aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime-base-itc/src/main/java/tools/refinery/viatra/runtime/base/itc/alg/representative/StronglyConnectedComponentAlgorithm.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/viatra-runtime-base-itc/src/main/java/tools/refinery/viatra/runtime/base/itc/alg/representative/StronglyConnectedComponentAlgorithm.java')
-rw-r--r--subprojects/viatra-runtime-base-itc/src/main/java/tools/refinery/viatra/runtime/base/itc/alg/representative/StronglyConnectedComponentAlgorithm.java66
1 files changed, 66 insertions, 0 deletions
diff --git a/subprojects/viatra-runtime-base-itc/src/main/java/tools/refinery/viatra/runtime/base/itc/alg/representative/StronglyConnectedComponentAlgorithm.java b/subprojects/viatra-runtime-base-itc/src/main/java/tools/refinery/viatra/runtime/base/itc/alg/representative/StronglyConnectedComponentAlgorithm.java
new file mode 100644
index 00000000..ba42bb13
--- /dev/null
+++ b/subprojects/viatra-runtime-base-itc/src/main/java/tools/refinery/viatra/runtime/base/itc/alg/representative/StronglyConnectedComponentAlgorithm.java
@@ -0,0 +1,66 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.viatra.runtime.base.itc.alg.representative;
7
8import tools.refinery.viatra.runtime.base.itc.alg.misc.GraphHelper;
9import tools.refinery.viatra.runtime.base.itc.alg.misc.bfs.BFS;
10import tools.refinery.viatra.runtime.base.itc.alg.misc.scc.SCC;
11import tools.refinery.viatra.runtime.base.itc.graphimpl.Graph;
12
13import java.util.Collection;
14import java.util.Set;
15
16public class StronglyConnectedComponentAlgorithm extends RepresentativeElectionAlgorithm {
17 public StronglyConnectedComponentAlgorithm(Graph<Object> graph) {
18 super(graph);
19 }
20
21 @Override
22 protected void initializeComponents() {
23 var computedSCCs = SCC.computeSCC(graph).getSccs();
24 for (var computedSCC : computedSCCs) {
25 initializeSet(computedSCC);
26 }
27 }
28
29 @Override
30 public void edgeInserted(Object source, Object target) {
31 var sourceRoot = getRepresentative(source);
32 var targetRoot = getRepresentative(target);
33 if (sourceRoot.equals(targetRoot)) {
34 // New edge does not change strongly connected components.
35 return;
36 }
37 if (BFS.isReachable(target, source, graph)) {
38 merge(sourceRoot, targetRoot);
39 }
40 }
41
42 @Override
43 public void edgeDeleted(Object source, Object target) {
44 var sourceRoot = getRepresentative(source);
45 var targetRoot = getRepresentative(target);
46 if (!sourceRoot.equals(targetRoot)) {
47 // New edge does not change strongly connected components.
48 return;
49 }
50 var component = GraphHelper.getSubGraph(getComponent(sourceRoot), graph);
51 if (!BFS.isReachable(source, target, component)) {
52 var newSCCs = SCC.computeSCC(component).getSccs();
53 split(sourceRoot, newSCCs);
54 }
55 }
56
57 private void split(Object preservedRepresentative, Collection<? extends Set<Object>> sets) {
58 for (var set : sets) {
59 if (set.contains(preservedRepresentative)) {
60 components.put(preservedRepresentative, set);
61 } else {
62 assignNewRepresentative(preservedRepresentative, set);
63 }
64 }
65 }
66}