001 // GraphLab Project: http://graphlab.sharif.edu 002 // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology 003 // Distributed under the terms of the GNU Lesser General Public License (LGPL): http://www.gnu.org/licenses/ 004 005 package graphlab.library.algorithms.sorting; 006 007 import graphlab.library.BaseEdge; 008 import graphlab.library.BaseGraph; 009 import graphlab.library.BaseVertex; 010 import graphlab.library.algorithms.Algorithm; 011 import graphlab.library.algorithms.AutomatedAlgorithm; 012 import graphlab.library.algorithms.util.LibraryUtils; 013 import graphlab.library.event.MessageEvent; 014 import graphlab.library.event.typedef.BaseGraphRequest; 015 016 import java.util.AbstractList; 017 import java.util.ArrayList; 018 import java.util.Iterator; 019 020 /** 021 * @author Omid Aladini 022 */ 023 public class TopologicalSort extends Algorithm implements AutomatedAlgorithm { 024 public static <VertexType extends BaseVertex, EdgeType extends BaseEdge<VertexType>> 025 AbstractList<VertexType> 026 doSort(BaseGraph<VertexType, EdgeType> graph) { 027 ArrayList<VertexType> alv = new ArrayList<VertexType>(); 028 ArrayList<VertexType> out = new ArrayList<VertexType>(); 029 030 LibraryUtils.falsifyEdgeMarks(graph); 031 032 for (VertexType v : graph) 033 if (graph.getInDegree(v) == 0) 034 alv.add(v); 035 036 while (alv.size() != 0) { 037 VertexType v = alv.remove(0); 038 out.add(v); 039 040 for (VertexType target: graph.getNeighbors(v)){ 041 if (graph.getInDegree(target) == 1) 042 alv.add(target); 043 } 044 } 045 046 if (LibraryUtils.falsifyEdgeMarks(graph)) 047 return null; 048 else 049 return out; 050 } 051 052 public void doAlgorithm() { 053 BaseGraphRequest gr = new BaseGraphRequest(); 054 dispatchEvent(gr); 055 BaseGraph<BaseVertex, BaseEdge<BaseVertex>> graph = gr.getGraph(); 056 AbstractList<BaseVertex> alv = doSort(graph); 057 if (alv == null) 058 dispatchEvent(new MessageEvent("Graph has a cycle")); 059 else { 060 String s = "Topological sort sequence:"; 061 for (BaseVertex v : alv) 062 s += v.getId() + ','; 063 064 dispatchEvent(new MessageEvent(s)); 065 } 066 067 } 068 069 070 } 071