// GraphTea Project: http://github.com/graphtheorysoftware/GraphTea
// Copyright (C) 2012 Graph Theory Software Foundation: http://GraphTheorySoftware.com
// Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology
// Distributed under the terms of the GNU Lesser General Public License (LGPL): http://www.gnu.org/licenses/
package graphtea.library.algorithms.sorting;
import graphtea.library.BaseEdge;
import graphtea.library.BaseGraph;
import graphtea.library.BaseVertex;
import graphtea.library.algorithms.Algorithm;
import graphtea.library.algorithms.AutomatedAlgorithm;
import graphtea.library.algorithms.util.LibraryUtils;
import graphtea.library.event.MessageEvent;
import graphtea.library.event.typedef.BaseGraphRequest;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Iterator;
/**
* @author Omid Aladini
*/
public class TopologicalSort extends Algorithm implements AutomatedAlgorithm {
public static <VertexType extends BaseVertex, EdgeType extends BaseEdge<VertexType>>
AbstractList<VertexType>
doSort(BaseGraph<VertexType, EdgeType> graph) {
ArrayList<VertexType> alv = new ArrayList<>();
ArrayList<VertexType> out = new ArrayList<>();
LibraryUtils.falsifyEdgeMarks(graph);
for (VertexType v : graph)
if (graph.getInDegree(v) == 0)
alv.add(v);
while (alv.size() != 0) {
VertexType v = alv.remove(0);
out.add(v);
Iterator<EdgeType> iet = graph.edgeIterator(v, true);
while (iet.hasNext()) {
EdgeType e = iet.next();
/*
if(e.getMark())
continue;
e.setMark(true);
if(alv.contains(e.target))
continue;
*/
if (graph.getInDegree(e.target) == 1)
alv.add(e.target);
}
}
if (LibraryUtils.falsifyEdgeMarks(graph))
return null;
else
return out;
}
public void doAlgorithm() {
BaseGraphRequest gr = new BaseGraphRequest();
dispatchEvent(gr);
BaseGraph<BaseVertex, BaseEdge<BaseVertex>> graph = gr.getGraph();
AbstractList<BaseVertex> alv = doSort(graph);
if (alv == null)
dispatchEvent(new MessageEvent("Graph has a cycle"));
else {
String s = "Topological sort sequence:";
for (BaseVertex v : alv)
s += v.getId() + ',';
dispatchEvent(new MessageEvent(s));
}
}
}