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    import graphlab.library.BaseEdge;
008    import graphlab.library.BaseGraph;
009    import graphlab.library.BaseVertex;
010    import graphlab.library.algorithms.Algorithm;
011    import graphlab.library.genericcloners.BaseEdgeVertexCopier;
012    
013    import java.util.Collection;
014    import java.util.Iterator;
015    import java.util.Vector;
016    
017    /**
018     * This Algorithm computes the lenght of the shortest
019     * path between any two arbitrary vertices.
020     * This method is usually used for sparse graphs.
021     *
022     * @author Soroush Sabet
023     */
024    public class Johnson
025            <VertexType extends BaseVertex, EdgeType extends BaseEdge<VertexType>, GraphType extends BaseGraph<VertexType, EdgeType>>
026            extends Algorithm {
027    
028        int[] a;
029        int[][] d;
030    
031        //HashMap nw = new HashMap<EdgeType,Integer>();
032        Johnson() {
033    
034        }
035    
036        public int[][] ComputePaths(GraphType g) {
037    
038            BaseEdgeVertexCopier gc = new BaseEdgeVertexCopier();
039            VertexType u;
040            BaseEdge e;
041    
042            u = (VertexType) gc.convert(null);
043            g.insertVertex(u);
044            for (VertexType v : g) {
045    
046                if (v != u) {
047                    e = gc.convert(null, u, v);
048                    g.insertEdge((EdgeType) e);
049                    e.setWeight(0);
050                }
051    
052            }
053            BellmanFord sp = new BellmanFord();
054    
055            if (sp.computePaths(g, u) != null) {
056                Vector<VertexType> pd = sp.computePaths(g, u);
057                for (VertexType v : g) {
058    
059                    int dd = 0;
060                    VertexType w = v;
061                    EdgeType h;
062                    while (w != u) {
063                        h = getSingleEdge(g, pd.get(v.getId()), w);
064                        dd += h.getWeight();
065                    }
066                    a[v.getId()] = dd;
067    
068                }
069                Iterator<EdgeType> iet = g.edgeIterator();
070                EdgeType h;
071                while (iet.hasNext()) {
072                    h = iet.next();
073                    int w = h.getWeight() + a[h.source.getId()] - a[h.target.getId()];
074                    //nw.put(h,w);
075                    h.setWeight(w);
076                }
077    
078                for (VertexType v : g) {
079                    Dijkstra dj = new Dijkstra();
080                    Vector<VertexType> pdj = dj.getShortestPath(g, v);
081                    for (VertexType z : g) {
082                        int dd = 0;
083                        VertexType w = z;
084                        EdgeType f;
085                        while (w != v) {
086                            f = getSingleEdge(g, pdj.get(z.getId()), w);
087                            dd += f.getWeight();
088                        }
089                        d[v.getId()][z.getId()] = dd + a[z.getId()] - a[v.getId()];
090    
091                    }
092                }
093    
094            }
095    
096    
097            return new int[0][];
098        }
099    
100        private EdgeType getSingleEdge(GraphType g, VertexType v, VertexType w) {
101            Collection<EdgeType> f;
102            EdgeType h;
103            f = g.getEdges(v, w);
104            h = f.iterator().next();
105            return h;
106        }
107    
108    }