aQute.libg.tarjan.Tarjan Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bndlib Show documentation
Show all versions of bndlib Show documentation
The bndlib project is a general library to be used with OSGi bundles. It contains
lots of cool functionality that calculates dependencies, etc.
package aQute.libg.tarjan;
import static java.lang.Math.*;
import java.util.*;
public class Tarjan {
public class Node {
final T name;
final List adjacent = new ArrayList();
int low = -1;
int index = -1;
public Node(T name) {
this.name = name;
}
@Override
public String toString() {
return name + "{" + index + "," + low + "}";
}
}
private int index = 0;
private List stack = new ArrayList();
private Set> scc = new HashSet>();
private Node root = new Node(null);
// public ArrayList> tarjan(Node v, AdjacencyList list){
// v.index = index;
// v.lowlink = index;
// index++;
// stack.add(0, v);
// for(Edge e : list.getAdjacent(v)){
// Node n = e.to;
// if(n.index == -1){
// tarjan(n, list);
// v.lowlink = Math.min(v.lowlink, n.lowlink);
// }else if(stack.contains(n)){
// v.lowlink = Math.min(v.lowlink, n.index);
// }
// }
// if(v.lowlink == v.index){
// Node n;
// ArrayList component = new ArrayList();
// do{
// n = stack.remove(0);
// component.add(n);
// }while(n != v);
// SCC.add(component);
// }
// return SCC;
// }
void tarjan(Node v) {
v.index = index;
v.low = index;
index++;
stack.add(0, v);
for (Node n : v.adjacent) {
if (n.index == -1) {
// first time visit
tarjan(n);
v.low = min(v.low, n.low);
} else if (stack.contains(n)) {
v.low = min(v.low, n.index);
}
}
if (v != root && v.low == v.index) {
Set component = new HashSet();
Node n;
do {
n = stack.remove(0);
component.add(n.name);
} while (n != v);
scc.add(component);
}
}
Set> getResult(Map> graph) {
Map index = new HashMap();
for (Map.Entry> entry : graph.entrySet()) {
Node node = getNode(index, entry.getKey());
root.adjacent.add(node);
for (T adj : entry.getValue())
node.adjacent.add(getNode(index, adj));
}
tarjan(root);
return scc;
}
private Node getNode(Map index, T key) {
Node node = index.get(key);
if (node == null) {
node = new Node(key);
index.put(key, node);
}
return node;
}
public static Collection< ? extends Collection> tarjan(Map> graph) {
Tarjan tarjan = new Tarjan();
return tarjan.getResult(graph);
}
}