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