package org.bundlemaker.core.analysis.algorithms; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.bundlemaker.core.analysis.IBundleMakerArtifact; import org.eclipse.core.runtime.Assert; /** */ public class Tarjan<T extends IBundleMakerArtifact> { /** - */ private int _index = 0; /** - */ private ArrayList<Integer> _stack = new ArrayList<Integer>(); /** - */ private List<List<T>> _stronglyConnectedComponents = new ArrayList<List<T>>(); /** - */ int[] _vlowlink; /** - */ int[] _vindex; /** - */ private IBundleMakerArtifact[] _artifacts; /** * @param artifacts * @return */ public List<List<T>> executeTarjan(Collection<? extends T> artifacts) { Assert.isNotNull(artifacts); _artifacts = artifacts.toArray(new IBundleMakerArtifact[0]); int[][] adjacencyList = AdjacencyList.computeAdjacencyList(_artifacts, null); return executeTarjan(adjacencyList); } // private List<List<T>> executeTarjan(int[][] graph) { Assert.isNotNull(graph); // clear _stronglyConnectedComponents.clear(); _index = 0; _stack.clear(); _vlowlink = new int[graph.length]; _vindex = new int[graph.length]; for (int i = 0; i < _vlowlink.length; i++) { _vlowlink[i] = -1; _vindex[i] = -1; } // for (int i = 0; i < graph.length; i++) { if (_vindex[i] == -1) { tarjan(i, graph); } } // return _stronglyConnectedComponents; } @SuppressWarnings("unchecked") private void tarjan(int v, int[][] graph) { Assert.isNotNull(v); Assert.isNotNull(graph); _vindex[v] = _index; _vlowlink[v] = _index; _index++; _stack.add(0, v); for (int n : graph[v]) { if (_vindex[n] == -1) { tarjan(n, graph); _vlowlink[v] = Math.min(_vlowlink[v], _vlowlink[n]); } else if (_stack.contains(n)) { _vlowlink[v] = Math.min(_vlowlink[v], _vindex[n]); } } if (_vlowlink[v] == _vindex[v]) { int n; ArrayList<T> component = new ArrayList<T>(); do { n = _stack.remove(0); component.add((T) _artifacts[n]); } while (n != v); _stronglyConnectedComponents.add(component); } } }