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

aQute.libg.tarjan.Tarjan Maven / Gradle / Ivy

The newest version!
package aQute.libg.tarjan;

import static java.lang.Math.min;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

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> tarjan(Map> graph) {
		Tarjan tarjan = new Tarjan<>();
		return tarjan.getResult(graph);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy