aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime-rete/src/main/java/tools
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-08-27 02:13:15 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-08-27 02:13:15 +0200
commitcca3b176cea8df8823094c105f612844b649647e (patch)
tree02e24ecd37228fe170a3b07e4e29570bf97732bf /subprojects/viatra-runtime-rete/src/main/java/tools
parentchore(deps): bump frontend dependencies (diff)
downloadrefinery-cca3b176cea8df8823094c105f612844b649647e.tar.gz
refinery-cca3b176cea8df8823094c105f612844b649647e.tar.zst
refinery-cca3b176cea8df8823094c105f612844b649647e.zip
fix: strong represenative election algorithm
Make sure to merge all clusters reachable from source and target.
Diffstat (limited to 'subprojects/viatra-runtime-rete/src/main/java/tools')
-rw-r--r--subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/alg/misc/bfs/BFS.java29
-rw-r--r--subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/alg/representative/RepresentativeElectionAlgorithm.java34
-rw-r--r--subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/alg/representative/StronglyConnectedComponentAlgorithm.java5
3 files changed, 51 insertions, 17 deletions
diff --git a/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/alg/misc/bfs/BFS.java b/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/alg/misc/bfs/BFS.java
index 00b0a96d..22ce8962 100644
--- a/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/alg/misc/bfs/BFS.java
+++ b/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/alg/misc/bfs/BFS.java
@@ -12,10 +12,7 @@ package tools.refinery.viatra.runtime.rete.itc.alg.misc.bfs;
12import tools.refinery.viatra.runtime.rete.itc.igraph.IBiDirectionalGraphDataSource; 12import tools.refinery.viatra.runtime.rete.itc.igraph.IBiDirectionalGraphDataSource;
13import tools.refinery.viatra.runtime.rete.itc.igraph.IGraphDataSource; 13import tools.refinery.viatra.runtime.rete.itc.igraph.IGraphDataSource;
14 14
15import java.util.ArrayList; 15import java.util.*;
16import java.util.HashSet;
17import java.util.List;
18import java.util.Set;
19 16
20public class BFS<V> { 17public class BFS<V> {
21 18
@@ -35,7 +32,7 @@ public class BFS<V> {
35 * @return true if source is reachable from target, false otherwise 32 * @return true if source is reachable from target, false otherwise
36 */ 33 */
37 public static <V> boolean isReachable(V source, V target, IGraphDataSource<V> graph) { 34 public static <V> boolean isReachable(V source, V target, IGraphDataSource<V> graph) {
38 List<V> nodeQueue = new ArrayList<V>(); 35 Deque<V> nodeQueue = new ArrayDeque<V>();
39 Set<V> visited = new HashSet<V>(); 36 Set<V> visited = new HashSet<V>();
40 37
41 nodeQueue.add(source); 38 nodeQueue.add(source);
@@ -45,17 +42,17 @@ public class BFS<V> {
45 return ret; 42 return ret;
46 } 43 }
47 44
48 private static <V> boolean _isReachable(V target, IGraphDataSource<V> graph, List<V> nodeQueue, Set<V> visited) { 45 private static <V> boolean _isReachable(V target, IGraphDataSource<V> graph, Deque<V> nodeQueue, Set<V> visited) {
49 46
50 while (!nodeQueue.isEmpty()) { 47 while (!nodeQueue.isEmpty()) {
51 V node = nodeQueue.remove(0); 48 V node = nodeQueue.removeFirst();
52 for (V t : graph.getTargetNodes(node).distinctValues()){ 49 for (V t : graph.getTargetNodes(node).distinctValues()){
53 if (t.equals(target)) { 50 if (t.equals(target)) {
54 return true; 51 return true;
55 } 52 }
56 if (!visited.contains(t)) { 53 if (!visited.contains(t)) {
57 visited.add(t); 54 visited.add(t);
58 nodeQueue.add(t); 55 nodeQueue.addLast(t);
59 } 56 }
60 } 57 }
61 } 58 }
@@ -65,7 +62,7 @@ public class BFS<V> {
65 public static <V> Set<V> reachableSources(IBiDirectionalGraphDataSource<V> graph, V target) { 62 public static <V> Set<V> reachableSources(IBiDirectionalGraphDataSource<V> graph, V target) {
66 Set<V> retSet = new HashSet<V>(); 63 Set<V> retSet = new HashSet<V>();
67 retSet.add(target); 64 retSet.add(target);
68 List<V> nodeQueue = new ArrayList<V>(); 65 Deque<V> nodeQueue = new ArrayDeque<V>();
69 nodeQueue.add(target); 66 nodeQueue.add(target);
70 67
71 _reachableSources(graph, nodeQueue, retSet); 68 _reachableSources(graph, nodeQueue, retSet);
@@ -73,14 +70,14 @@ public class BFS<V> {
73 return retSet; 70 return retSet;
74 } 71 }
75 72
76 private static <V> void _reachableSources(IBiDirectionalGraphDataSource<V> graph, List<V> nodeQueue, 73 private static <V> void _reachableSources(IBiDirectionalGraphDataSource<V> graph, Deque<V> nodeQueue,
77 Set<V> retSet) { 74 Set<V> retSet) {
78 while (!nodeQueue.isEmpty()) { 75 while (!nodeQueue.isEmpty()) {
79 V node = nodeQueue.remove(0); 76 V node = nodeQueue.removeFirst();
80 for (V _node : graph.getSourceNodes(node).distinctValues()) { 77 for (V _node : graph.getSourceNodes(node).distinctValues()) {
81 if (!retSet.contains(_node)) { 78 if (!retSet.contains(_node)) {
82 retSet.add(_node); 79 retSet.add(_node);
83 nodeQueue.add(_node); 80 nodeQueue.addLast(_node);
84 } 81 }
85 } 82 }
86 } 83 }
@@ -89,7 +86,7 @@ public class BFS<V> {
89 public static <V> Set<V> reachableTargets(IGraphDataSource<V> graph, V source) { 86 public static <V> Set<V> reachableTargets(IGraphDataSource<V> graph, V source) {
90 Set<V> retSet = new HashSet<V>(); 87 Set<V> retSet = new HashSet<V>();
91 retSet.add(source); 88 retSet.add(source);
92 List<V> nodeQueue = new ArrayList<V>(); 89 Deque<V> nodeQueue = new ArrayDeque<V>();
93 nodeQueue.add(source); 90 nodeQueue.add(source);
94 91
95 _reachableTargets(graph, nodeQueue, retSet); 92 _reachableTargets(graph, nodeQueue, retSet);
@@ -97,15 +94,15 @@ public class BFS<V> {
97 return retSet; 94 return retSet;
98 } 95 }
99 96
100 private static <V> void _reachableTargets(IGraphDataSource<V> graph, List<V> nodeQueue, Set<V> retSet) { 97 private static <V> void _reachableTargets(IGraphDataSource<V> graph, Deque<V> nodeQueue, Set<V> retSet) {
101 while (!nodeQueue.isEmpty()) { 98 while (!nodeQueue.isEmpty()) {
102 V node = nodeQueue.remove(0); 99 V node = nodeQueue.removeFirst();
103 100
104 for (V _node : graph.getTargetNodes(node).distinctValues()) { 101 for (V _node : graph.getTargetNodes(node).distinctValues()) {
105 102
106 if (!retSet.contains(_node)) { 103 if (!retSet.contains(_node)) {
107 retSet.add(_node); 104 retSet.add(_node);
108 nodeQueue.add(_node); 105 nodeQueue.addLast(_node);
109 } 106 }
110 } 107 }
111 } 108 }
diff --git a/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/alg/representative/RepresentativeElectionAlgorithm.java b/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/alg/representative/RepresentativeElectionAlgorithm.java
index 5343f956..794dabc0 100644
--- a/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/alg/representative/RepresentativeElectionAlgorithm.java
+++ b/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/alg/representative/RepresentativeElectionAlgorithm.java
@@ -45,6 +45,40 @@ public abstract class RepresentativeElectionAlgorithm implements IGraphObserver<
45 components.put(representative, set); 45 components.put(representative, set);
46 } 46 }
47 47
48 protected void merge(Set<Object> toMerge) {
49 if (toMerge.isEmpty()) {
50 return;
51 }
52 var representativesToMerge = new HashSet<>();
53 Object bestRepresentative = null;
54 Set<Object> bestSet = null;
55 for (var object : toMerge) {
56 var representative = getRepresentative(object);
57 if (representativesToMerge.add(representative)) {
58 var component = getComponent(representative);
59 if (bestSet == null || bestSet.size() < component.size()) {
60 bestRepresentative = representative;
61 bestSet = component;
62 }
63 }
64 }
65 if (bestRepresentative == null) {
66 throw new AssertionError("Could not determine best representative");
67 }
68 for (var representative : representativesToMerge) {
69 if (!bestRepresentative.equals(representative)) {
70 components.remove(representative);
71 }
72 }
73 components.put(bestRepresentative, toMerge);
74 for (var object : toMerge) {
75 var previousRepresentative = representatives.put(object, bestRepresentative);
76 if (!bestSet.contains(object)) {
77 notifyToObservers(object, previousRepresentative, bestRepresentative);
78 }
79 }
80 }
81
48 protected void merge(Object leftRepresentative, Object rightRepresentative) { 82 protected void merge(Object leftRepresentative, Object rightRepresentative) {
49 if (leftRepresentative.equals(rightRepresentative)) { 83 if (leftRepresentative.equals(rightRepresentative)) {
50 return; 84 return;
diff --git a/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/alg/representative/StronglyConnectedComponentAlgorithm.java b/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/alg/representative/StronglyConnectedComponentAlgorithm.java
index 4acb2b77..0463301b 100644
--- a/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/alg/representative/StronglyConnectedComponentAlgorithm.java
+++ b/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/itc/alg/representative/StronglyConnectedComponentAlgorithm.java
@@ -35,7 +35,10 @@ public class StronglyConnectedComponentAlgorithm extends RepresentativeElectionA
35 return; 35 return;
36 } 36 }
37 if (BFS.isReachable(target, source, graph)) { 37 if (BFS.isReachable(target, source, graph)) {
38 merge(sourceRoot, targetRoot); 38 var sources = BFS.reachableSources(graph, target);
39 var targets = BFS.reachableTargets(graph, source);
40 sources.retainAll(targets);
41 merge(sources);
39 } 42 }
40 } 43 }
41 44