Browse Source

imported patch tarjan-lowlink-index-array.patch

tud-infrastructure-2018-10-12
Joachim Klein 7 years ago
parent
commit
eb21a8984c
  1. 53
      prism/src/explicit/SCCComputerTarjan.java

53
prism/src/explicit/SCCComputerTarjan.java

@ -28,7 +28,7 @@
package explicit; package explicit;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet; import java.util.BitSet;
import java.util.Deque; import java.util.Deque;
import java.util.function.IntPredicate; import java.util.function.IntPredicate;
@ -50,10 +50,14 @@ public class SCCComputerTarjan extends SCCComputer
private int index = 0; private int index = 0;
/* Stack of nodes */ /* Stack of nodes */
private Deque<Integer> stack = new ArrayDeque<Integer>(); private Deque<Integer> stack = new ArrayDeque<Integer>();
/* List of nodes in the graph. Invariant: {@code nodeList.get(i).id == i} */
private ArrayList<Node> nodeList;
/* Nodes currently on the stack. */ /* Nodes currently on the stack. */
private BitSet onStack; 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? */ /** Should we filter trivial SCCs? */
private boolean filterTrivialSCCs; private boolean filterTrivialSCCs;
private IntPredicate restrict; private IntPredicate restrict;
@ -66,10 +70,10 @@ public class SCCComputerTarjan extends SCCComputer
super(parent, consumer); super(parent, consumer);
this.model = model; this.model = model;
this.numNodes = model.getNumStates(); this.numNodes = model.getNumStates();
this.nodeList = new ArrayList<Node>(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(); onStack = new BitSet();
} }
@ -96,17 +100,16 @@ public class SCCComputerTarjan extends SCCComputer
for (int i = 0; i < numNodes; i++) { for (int i = 0; i < numNodes; i++) {
if (restrict != null && !restrict.test(i)) if (restrict != null && !restrict.test(i))
continue; // skip state if not one of the relevant states continue; // skip state if not one of the relevant states
if (nodeList.get(i).lowlink == -1)
if (nodeLowlink[i] == -1)
tarjan(i); 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++; index++;
stack.push(i); stack.push(i);
onStack.set(i); onStack.set(i);
@ -114,7 +117,7 @@ public class SCCComputerTarjan extends SCCComputer
boolean hadSelfloop = false; boolean hadSelfloop = false;
SuccessorsIterator it = model.getSuccessors(i); SuccessorsIterator it = model.getSuccessors(i);
while (it.hasNext()) { while (it.hasNext()) {
int e = it.nextInt();
final int e = it.nextInt();
if (e == i) { if (e == i) {
hadSelfloop = true; hadSelfloop = true;
@ -125,15 +128,14 @@ public class SCCComputerTarjan extends SCCComputer
continue; // ignore edge to state that is not relevant continue; // ignore edge to state that is not relevant
} }
Node n = nodeList.get(e);
if (n.index == -1) {
if (nodeIndex[e] == -1) {
tarjan(e); tarjan(e);
v.lowlink = Math.min(v.lowlink, n.lowlink);
nodeLowlink[i] = Math.min(nodeLowlink[i], nodeLowlink[e]);
} else if (onStack.get(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 // this is a singleton SCC if the top of the stack equals i
boolean singletonSCC = (stack.peek() == i); boolean singletonSCC = (stack.peek() == i);
if (singletonSCC && filterTrivialSCCs) { 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;
}
}
} }
Loading…
Cancel
Save