From f1303fe37b0f143d87c5d03ea28c898a95a57830 Mon Sep 17 00:00:00 2001 From: Oshgnacknak Date: Sun, 5 Sep 2021 22:44:37 +0200 Subject: [PATCH] Introduce MinimumSpanningForestAlgorithm and implement Kruskal --- src/main/java/h07/algorithm/Kruskal.java | 62 +++++++++++++++++++ .../MinimumSpanningForestAlgorithm.java | 11 ++++ src/main/java/h07/algorithm/Pair.java | 11 ++++ 3 files changed, 84 insertions(+) create mode 100644 src/main/java/h07/algorithm/Kruskal.java create mode 100644 src/main/java/h07/algorithm/MinimumSpanningForestAlgorithm.java create mode 100644 src/main/java/h07/algorithm/Pair.java diff --git a/src/main/java/h07/algorithm/Kruskal.java b/src/main/java/h07/algorithm/Kruskal.java new file mode 100644 index 0000000..77aabae --- /dev/null +++ b/src/main/java/h07/algorithm/Kruskal.java @@ -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 implements MinimumSpanningForestAlgorithm { + + @Override + public DirectedGraph minimumSpanningForest(DirectedGraph graph, Comparator comparator, DirectedGraphFactory factory) { + var output = factory.createDirectedGraph(); + var sets = new ArrayList>(); + + for (V node : graph.getAllNodes()) { + output.addNode(node); + + var set = new HashSet(); + 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; + } +} diff --git a/src/main/java/h07/algorithm/MinimumSpanningForestAlgorithm.java b/src/main/java/h07/algorithm/MinimumSpanningForestAlgorithm.java new file mode 100644 index 0000000..72b78be --- /dev/null +++ b/src/main/java/h07/algorithm/MinimumSpanningForestAlgorithm.java @@ -0,0 +1,11 @@ +package h07.algorithm; + +import h07.graph.DirectedGraph; +import h07.graph.DirectedGraphFactory; + +import java.util.Comparator; + +public interface MinimumSpanningForestAlgorithm { + + DirectedGraph minimumSpanningForest(DirectedGraph graph, Comparator comparator, DirectedGraphFactory factory); +} diff --git a/src/main/java/h07/algorithm/Pair.java b/src/main/java/h07/algorithm/Pair.java new file mode 100644 index 0000000..71c4184 --- /dev/null +++ b/src/main/java/h07/algorithm/Pair.java @@ -0,0 +1,11 @@ +package h07.algorithm; + +public class Pair { + public T fst; + public S snd; + + public Pair(T fst, S snd) { + this.fst = fst; + this.snd = snd; + } +}