spreadsheet.mapper.w2o.validation.engine.DependencyCycleCheckEngine Maven / Gradle / Ivy
package spreadsheet.mapper.w2o.validation.engine;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
/**
*
* use Tarjan's strongly connected components algorithm to check cycling,
* in directed graph, if a strongly connected component not a isolated node, means has cycle.
*
* Created by hanwen on 2017/1/5.
*/
public class DependencyCycleCheckEngine {
private LinkedHashMap> vGraph = new LinkedHashMap<>();
private Stack vStack = new Stack<>();
private Map vIndex = new HashMap<>();
private Map vLowLink = new HashMap<>();
private int index;
// found exists cycle
private List cycle = new ArrayList<>();
public DependencyCycleCheckEngine(LinkedHashMap> vGraph) {
this.vGraph = vGraph;
for (String s : vGraph.keySet()) {
vIndex.put(s, 0);
vLowLink.put(s, 0);
}
}
public boolean cycling() {
for (String v : vGraph.keySet()) {
if (vGraph.get(v).contains(v)) {
cycle = Collections.singletonList(v);
}
if (isCycling()) {
return true;
}
if (vIndex.get(v) == 0) {
strongConnect(v);
}
}
return false;
}
public List getCycle() {
return cycle;
}
private void strongConnect(String v) {
index++;
vIndex.put(v, index);
vLowLink.put(v, index);
vStack.push(v);
for (String w : vGraph.get(v)) {
if (vIndex.get(w) == 0) {
strongConnect(w);
vLowLink.put(v, Math.min(vLowLink.get(v), vLowLink.get(w)));
} else if (vStack.contains(w)) {
vLowLink.put(v, Math.min(vLowLink.get(v), vIndex.get(w)));
}
}
if (isCycling()) {
return;
}
if (Objects.equals(vLowLink.get(v), vIndex.get(v))) {
populateConnectedComponents(v);
}
}
private void populateConnectedComponents(String v) {
List connectedComponents = new ArrayList<>();
String connectedComponent = null;
while (!StringUtils.equals(connectedComponent, v)) {
connectedComponent = vStack.pop();
connectedComponents.add(connectedComponent);
}
if (connectedComponents.size() > 1) {
cycle = connectedComponents;
}
}
private boolean isCycling() {
return !cycle.isEmpty();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy