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;
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<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. */
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<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();
}
@ -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;
}
}
}
Loading…
Cancel
Save