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.spanningtree;
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.event.typedef.BaseGraphRequest;
013    
014    import java.util.AbstractList;
015    import java.util.ArrayList;
016    import java.util.Comparator;
017    import java.util.Iterator;
018    
019    /**
020     * @author Omid Aladini
021     */
022    public class Kruskal extends Algorithm implements AutomatedAlgorithm {
023        public static <VertexType extends BaseVertex, EdgeType extends BaseEdge<VertexType>>
024        AbstractList<EdgeType>
025        findMinimumSpanningTree(BaseGraph<VertexType, EdgeType> graph) {
026            ArrayList<EdgeType> outputEdges = new ArrayList<EdgeType>();
027            ArrayList<ArrayList<VertexType>> sets = new ArrayList<ArrayList<VertexType>>();
028    
029            for (VertexType v : graph) {
030                ArrayList<VertexType> set = new ArrayList<VertexType>();
031                set.add(v);
032                sets.add(set);
033            }
034    
035            ArrayList<EdgeType> edges = new ArrayList<EdgeType>(graph.getEdgesCount());
036    
037            Iterator<EdgeType> eit = graph.edgeIterator();
038            while (eit.hasNext())
039                edges.add(eit.next());
040    
041            java.util.Collections.sort(edges, new Comparator<EdgeType>() {
042                public int compare(EdgeType o1, EdgeType o2) {
043                    if (o1.getWeight() < o2.getWeight())
044                        return -1;
045                    else if (o1.getWeight() == o2.getWeight())
046                        return 0;
047                    return 1;
048                }
049            });
050    
051            for (EdgeType e : edges)
052                System.out.print(e.getWeight() + " ");
053            System.out.println();
054    
055            for (EdgeType e : edges) {
056                int set1 = findSet(sets, e.source);
057                int set2 = findSet(sets, e.target);
058    
059                if (set1 != set2) {
060                    outputEdges.add(e);
061                    e.source.setMark(true);
062                    e.setMark(true);
063                    e.target.setMark(true);
064                    sets.get(set1).addAll(sets.get(set2));
065                    sets.remove(set2);
066                    //EventUtils.algorithmStep(this,600);
067                }
068            }
069    
070            return outputEdges;
071        }
072    
073        private static <VertexType extends BaseVertex, EdgeType extends BaseEdge<VertexType>>
074        int findSet(ArrayList<ArrayList<VertexType>> aav, VertexType v) {
075            int i = -1;
076            for (ArrayList<VertexType> set : aav) {
077                ++i;
078                if (set.contains(v))
079                    return i;
080            }
081    
082            throw new RuntimeException("Element is not present in any subset.");
083        }
084    
085        public void doAlgorithm() {
086            BaseGraphRequest gr = new BaseGraphRequest();
087            dispatchEvent(gr);
088            BaseGraph<BaseVertex, BaseEdge<BaseVertex>> graph = gr.getGraph();
089    
090            Kruskal.findMinimumSpanningTree(graph);
091        }
092    
093    
094    }
095