Introduce MinimumSpanningForestAlgorithm and implement Kruskal
This commit is contained in:
		
							parent
							
								
									d8b5a76fb0
								
							
						
					
					
						commit
						f1303fe37b
					
				
					 3 changed files with 84 additions and 0 deletions
				
			
		
							
								
								
									
										62
									
								
								src/main/java/h07/algorithm/Kruskal.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/main/java/h07/algorithm/Kruskal.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,62 @@
 | 
				
			||||||
 | 
					package h07.algorithm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import aud.exam.prep.Pair;
 | 
				
			||||||
 | 
					import h07.graph.DirectedGraph;
 | 
				
			||||||
 | 
					import h07.graph.DirectedGraphFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class Kruskal<V, A> implements MinimumSpanningForestAlgorithm<V, A> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public DirectedGraph<V, A> minimumSpanningForest(DirectedGraph<V, A> graph, Comparator<? super A> comparator, DirectedGraphFactory<V, A> factory) {
 | 
				
			||||||
 | 
					        var output = factory.createDirectedGraph();
 | 
				
			||||||
 | 
					        var sets = new ArrayList<Set<V>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (V node : graph.getAllNodes()) {
 | 
				
			||||||
 | 
					            output.addNode(node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var set = new HashSet<V>();
 | 
				
			||||||
 | 
					            set.add(node);
 | 
				
			||||||
 | 
					            sets.add(set);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var egdes = graph.getAllNodes()
 | 
				
			||||||
 | 
					            .stream()
 | 
				
			||||||
 | 
					            .flatMap(n ->
 | 
				
			||||||
 | 
					                graph.getChildrenForNode(n)
 | 
				
			||||||
 | 
					                    .stream()
 | 
				
			||||||
 | 
					                    .map(c ->
 | 
				
			||||||
 | 
					                        new Pair<>(n, c)))
 | 
				
			||||||
 | 
					            .sorted(Comparator.comparing(
 | 
				
			||||||
 | 
					                p -> graph.getArcWeightBetween(p.fst, p.snd),
 | 
				
			||||||
 | 
					                comparator));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        egdes.forEach(p -> {
 | 
				
			||||||
 | 
					            var s1 = sets
 | 
				
			||||||
 | 
					                .stream()
 | 
				
			||||||
 | 
					                .filter(s -> s.contains(p.fst))
 | 
				
			||||||
 | 
					                .findFirst()
 | 
				
			||||||
 | 
					                .orElseThrow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (s1.contains(p.snd)) {
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var s2 = sets
 | 
				
			||||||
 | 
					                .stream()
 | 
				
			||||||
 | 
					                .filter(s -> s.contains(p.snd))
 | 
				
			||||||
 | 
					                .findFirst()
 | 
				
			||||||
 | 
					                .orElseThrow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            s1.addAll(s2);
 | 
				
			||||||
 | 
					            sets.remove(s2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var arc = graph.getArcWeightBetween(p.fst, p.snd);
 | 
				
			||||||
 | 
					            output.connectNodes(p.fst, arc, p.snd);
 | 
				
			||||||
 | 
					            output.connectNodes(p.snd, arc, p.fst);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return output;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					package h07.algorithm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import h07.graph.DirectedGraph;
 | 
				
			||||||
 | 
					import h07.graph.DirectedGraphFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.Comparator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public interface MinimumSpanningForestAlgorithm<V, A> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DirectedGraph<V, A> minimumSpanningForest(DirectedGraph<V, A> graph, Comparator<? super A> comparator, DirectedGraphFactory<V, A> factory);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								src/main/java/h07/algorithm/Pair.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/main/java/h07/algorithm/Pair.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					package h07.algorithm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class Pair<T, S> {
 | 
				
			||||||
 | 
					    public T fst;
 | 
				
			||||||
 | 
					    public S snd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Pair(T fst, S snd) {
 | 
				
			||||||
 | 
					        this.fst = fst;
 | 
				
			||||||
 | 
					        this.snd = snd;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in a new issue