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 }