All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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