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.shortestpath;
006    
007    
008    import graphlab.library.BaseEdge;
009    import graphlab.library.BaseGraph;
010    import graphlab.library.BaseVertex;
011    import graphlab.library.algorithms.Algorithm;
012    import graphlab.library.algorithms.AutomatedAlgorithm;
013    import graphlab.library.event.GraphRequest;
014    import graphlab.library.event.PreWorkEvent;
015    import graphlab.library.event.VertexRequest;
016    import graphlab.library.exceptions.InvalidVertexException;
017    import graphlab.library.genericcloners.EdgeVertexCopier;
018    
019    import java.util.*;
020    
021    /**
022     * @author Soroush Sabet
023     */
024    public class AcyclicSP<VertexType extends BaseVertex,
025            EdgeType extends BaseEdge<VertexType>,
026            GraphType extends BaseGraph<VertexType, EdgeType>>
027            extends Algorithm implements AutomatedAlgorithm {
028    
029    
030        private EdgeVertexCopier<VertexType, EdgeType> gc;
031    
032        public AcyclicSP(EdgeVertexCopier<VertexType, EdgeType> gc) {
033            this.gc = gc;
034        }
035    
036        public Vector<VertexType> acyclicSP(BaseGraph<VertexType, EdgeType> g, VertexType v) throws InvalidVertexException {
037            BaseGraph<VertexType, EdgeType> gcopy = g.copy(gc);
038            final Integer dist[] = new Integer[g.getVerticesCount()];
039            Vector<VertexType> prev = new Vector<VertexType>();
040            Queue<VertexType> Q = new LinkedList<VertexType>();
041            HashMap<VertexType, VertexType> gcopy2g = new HashMap<VertexType, VertexType>();
042            HashMap<Integer, VertexType> t = new HashMap<Integer, VertexType>();
043            for (VertexType _ : gcopy)
044                t.put(_.getId(), _);
045            for (VertexType _ : g)
046                gcopy2g.put(t.get(_.getId()), _);
047            for (int i = 0; i < dist.length; i++)
048                dist[i] = Integer.MAX_VALUE;
049    
050            dist[v.getId()] = 0;
051    
052            for (VertexType u : gcopy) {
053    //                System.out.println(u.getId()+":"+g.getInDegree(u));
054                if (gcopy.getInDegree(u) == 0) {
055    //                System.out.println(u.getId());
056                    Q.add(u);
057                }
058            }
059    
060            while (!Q.isEmpty()) {
061                VertexType u = Q.poll();
062                Iterator<EdgeType> iet = gcopy.edgeIterator(u);
063                while (iet.hasNext()) {
064                    EdgeType e = iet.next();
065                    if ((dist[u.getId()] + e.getWeight()) < dist[e.target.getId()]) {
066                        dist[e.target.getId()] = dist[u.getId()] + e.getWeight();
067                        prev.add(e.target.getId(), u);
068                        dispatchEvent(new PreWorkEvent<VertexType, EdgeType>(gcopy2g.get(e.target), gcopy2g.get(u), gcopy));
069    //                    System.out.println(e.target.getId());
070                    }
071                    if (gcopy.getInDegree((VertexType) e.target) == 1)
072                        Q.add((VertexType) e.target);
073                }
074                gcopy.removeVertex(u);
075            }
076            return prev;
077        }
078    
079        public void doAlgorithm() {
080            GraphRequest<VertexType, EdgeType> gr = new GraphRequest<VertexType, EdgeType>();
081            dispatchEvent(gr);
082            BaseGraph<VertexType, EdgeType> g = gr.getGraph();
083            VertexRequest<VertexType, EdgeType> vr = new VertexRequest<VertexType, EdgeType>(g);
084            dispatchEvent(vr);
085            VertexType v = vr.getVertex();
086            acyclicSP(g, v);
087        }
088    }