From eb21a8984c9cfd3da3e8b4e25ae2c9b8678b5b06 Mon Sep 17 00:00:00 2001 From: Joachim Klein Date: Fri, 12 Oct 2018 14:24:34 +0200 Subject: [PATCH] imported patch tarjan-lowlink-index-array.patch --- prism/src/explicit/SCCComputerTarjan.java | 53 +++++++++-------------- 1 file changed, 20 insertions(+), 33 deletions(-) diff --git a/prism/src/explicit/SCCComputerTarjan.java b/prism/src/explicit/SCCComputerTarjan.java index 18d43a9f..2d2aee02 100644 --- a/prism/src/explicit/SCCComputerTarjan.java +++ b/prism/src/explicit/SCCComputerTarjan.java @@ -28,7 +28,7 @@ package explicit; import java.util.ArrayDeque; -import java.util.ArrayList; +import java.util.Arrays; import java.util.BitSet; import java.util.Deque; import java.util.function.IntPredicate; @@ -50,10 +50,14 @@ public class SCCComputerTarjan extends SCCComputer private int index = 0; /* Stack of nodes */ private Deque stack = new ArrayDeque(); - /* List of nodes in the graph. Invariant: {@code nodeList.get(i).id == i} */ - private ArrayList nodeList; /* Nodes currently on the stack. */ private BitSet onStack; + + /** The lowlink information for the nodes (states) */ + private int[] nodeLowlink; + /** The index information for the nodes (states) */ + private int[] nodeIndex; + /** Should we filter trivial SCCs? */ private boolean filterTrivialSCCs; private IntPredicate restrict; @@ -66,10 +70,10 @@ public class SCCComputerTarjan extends SCCComputer super(parent, consumer); this.model = model; this.numNodes = model.getNumStates(); - this.nodeList = new ArrayList(numNodes); - for (int i = 0; i < numNodes; i++) { - nodeList.add(new Node(i)); - } + nodeLowlink = new int[numNodes]; + Arrays.fill(nodeLowlink, -1); + nodeIndex = new int[numNodes]; + Arrays.fill(nodeIndex, -1); onStack = new BitSet(); } @@ -96,17 +100,16 @@ public class SCCComputerTarjan extends SCCComputer for (int i = 0; i < numNodes; i++) { if (restrict != null && !restrict.test(i)) continue; // skip state if not one of the relevant states - if (nodeList.get(i).lowlink == -1) + if (nodeLowlink[i] == -1) tarjan(i); } } - private void tarjan(int i) throws PrismException + private void tarjan(final int i) throws PrismException { - final Node v = nodeList.get(i); - v.index = index; - v.lowlink = index; + nodeIndex[i] = index; + nodeLowlink[i] = index; index++; stack.push(i); onStack.set(i); @@ -114,7 +117,7 @@ public class SCCComputerTarjan extends SCCComputer boolean hadSelfloop = false; SuccessorsIterator it = model.getSuccessors(i); while (it.hasNext()) { - int e = it.nextInt(); + final int e = it.nextInt(); if (e == i) { hadSelfloop = true; @@ -125,15 +128,14 @@ public class SCCComputerTarjan extends SCCComputer continue; // ignore edge to state that is not relevant } - Node n = nodeList.get(e); - if (n.index == -1) { + if (nodeIndex[e] == -1) { tarjan(e); - v.lowlink = Math.min(v.lowlink, n.lowlink); + nodeLowlink[i] = Math.min(nodeLowlink[i], nodeLowlink[e]); } else if (onStack.get(e)) { - v.lowlink = Math.min(v.lowlink, n.index); + nodeLowlink[i] = Math.min(nodeLowlink[i], nodeIndex[e]); } } - if (v.lowlink == v.index) { + if (nodeLowlink[i] == nodeIndex[i]) { // this is a singleton SCC if the top of the stack equals i boolean singletonSCC = (stack.peek() == i); if (singletonSCC && filterTrivialSCCs) { @@ -155,19 +157,4 @@ public class SCCComputerTarjan extends SCCComputer } } - /** - * A small class wrapping a node. - * It carries extra information necessary for Tarjan's algorithm. - */ - protected static class Node - { - public int lowlink = -1; - public int index = -1; - public int id; - - public Node(int id) - { - this.id = id; - } - } }