/*******************************************************************************
* Copyright (c) 2010-2012, Tamas Szabo, Istvan Rath and Daniel Varro
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Tamas Szabo - initial API and implementation
*******************************************************************************/
package org.eclipse.incquery.runtime.base.itc.alg.misc.topsort;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import org.eclipse.incquery.runtime.base.itc.igraph.IGraphDataSource;
public class TopSort<V> {
private IGraphDataSource<V> gds;
private HashMap<Integer, V> forwardNodeMap;
private HashMap<V, Integer> backwardNodeMap;
private int nodeCount;
private int[] visited;
private int[] finishNumber;
private int[] depthNumber;
private int[] sourceNumber;
private int depthCount = 0;
private int finishCount = 0;
private List<V> topologicalSorting = null;
public TopSort(IGraphDataSource<V> g) {
this.gds = g;
nodeCount = gds.getAllNodes().size();
this.topologicalSorting = new ArrayList<V>();
visited = new int[nodeCount];
finishNumber = new int[nodeCount];
depthNumber = new int[nodeCount];
sourceNumber = new int[nodeCount];
forwardNodeMap = new HashMap<Integer, V>();
backwardNodeMap = new HashMap<V, Integer>();
int j = 0;
for (V n : gds.getAllNodes()) {
forwardNodeMap.put(j, n);
backwardNodeMap.put(n, j);
j++;
}
for (int i = 0; i < nodeCount; i++) {
visited[i] = 0;
finishNumber[i] = -1;
depthNumber[i] = -1;
sourceNumber[i] = -1;
}
}
public void doDFS() {
for (int i = 0; i < nodeCount; i++) {
if (visited[i] == 0)
oneDFS(i);
}
Collections.reverse(topologicalSorting);
}
private void oneDFS(int v) {
visited[v] = 1;
depthNumber[v] = ++depthCount;
List<V> targets = gds.getTargetNodes(forwardNodeMap.get(v));
if (targets != null) {
for (V t : targets) {
int u = backwardNodeMap.get(t);
sourceNumber[u] = v;
if (visited[u] == 0)
oneDFS(u);
}
}
finishNumber[v] = ++finishCount;
topologicalSorting.add(forwardNodeMap.get(v));
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static List<?> getTopologicalSorting(IGraphDataSource<?> g) {
TopSort da = new TopSort(g);
da.doDFS();
return da.topologicalSorting;
}
}