org.jbpt.algo.tree.tctree.BiconnectivityCheck Maven / Gradle / Ivy
package org.jbpt.algo.tree.tctree;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Stack;
import org.jbpt.graph.abs.IEdge;
import org.jbpt.graph.abs.IGraph;
import org.jbpt.hypergraph.abs.IVertex;
public class BiconnectivityCheck, V extends IVertex> {
protected class NodeAttrs {
boolean visited;
boolean cut;
V parent;
int low;
int dis;
public NodeAttrs() {
visited = false;
cut = false;
parent = null;
low = 0;
dis = 0;
}
}
private IGraph graph;
private Iterator nodes = null;
private Hashtable attrs = null;
private Collection> components = new ArrayList>();
private Stack s = new Stack();
private int time;
private V startNode;
private boolean isBiconnected;
public BiconnectivityCheck(IGraph graph) {
this.nodes = graph.getVertices().iterator();
this.attrs = new Hashtable(graph.getVertices().size());
this.graph = graph;
while (nodes.hasNext()) {
prepareNode(nodes.next());
}
startNode = graph.getVertices().iterator().next();
this.time = 0;
if (startNode != null) {
process(startNode);
this.isBiconnected = this.components.size() == 1;
} else
this.isBiconnected = false;
}
public boolean isBiconnected() {
return this.isBiconnected;
}
private void process(V v) {
NodeAttrs att = (NodeAttrs)attrs.get(v);
att.visited = true;
time++;
att.dis = time;
att.low = att.dis;
V w;
Collection edges = new ArrayList();
edges.addAll(this.graph.getEdges(v));
for (E e : edges) {
if (v.equals(e.getV1())) w = e.getV2();
else w = e.getV1();
NodeAttrs watt = (NodeAttrs)attrs.get(w);
if (!watt.visited) {
s.push(e);
watt.parent = v;
process(w);
if (watt.low >= att.dis) {
if (att.dis != 1) {
att.cut = true;
} else if (watt.dis > 2) {
att.cut = true;
}
addComponent(e);
}
if (watt.low < att.low) {
att.low = watt.low;
}
} else if (!compareInts(att.parent, w) && (watt.dis < att.dis)) { // (att.parent != w)
s.push(e);
if (watt.dis < att.low) {
att.low = watt.dis;
}
}
}
time++;
}
private void addComponent(E e) {
EdgeList comp = new EdgeList();
E f;
do {
f = s.pop();
comp.add(f);
} while (e != f);
components.add(comp);
}
private boolean compareInts(V i1, V i2) {
if (i1==null && i2==null) return true;
if (i1!=null) return i1.equals(i2);
if (i2!=null) return false;
return true;
}
private void prepareNode(V node) {
attrs.put(node, new NodeAttrs());
}
@SuppressWarnings("unused")
private boolean visited(V node) {
return ((NodeAttrs)attrs.get(node)).visited;
}
}