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.algorithms.AutomatedAlgorithm; 012 import graphlab.library.algorithms.util.EventUtils; 013 import graphlab.library.event.GraphRequest; 014 import graphlab.library.event.VertexEvent; 015 import graphlab.library.event.VertexRequest; 016 import graphlab.library.exceptions.InvalidVertexException; 017 018 import java.util.*; 019 020 021 /** 022 * This method finds the shortest path from a vertex to all vertices 023 * of a graph. 024 * [Should be tested] 025 * 026 * @author Omid Aladini 027 */ 028 public class Dijkstra<VertexType extends BaseVertex, 029 EdgeType extends BaseEdge<VertexType>> extends Algorithm 030 implements AutomatedAlgorithm { 031 /** 032 * This method finds a reference array using Dijkstra algorithm 033 * from which, one can find 034 * the shortest paths of all vertices of a graph from an arbitrary 035 * given vertex. 036 * 037 * @param graph Graph object to be searched. 038 * @param vertex The source of the paths. 039 * @return Vector of vertices that for each i, it has a reference to 040 * the vertex, before the vertex with ID number i in the shortest path 041 * from "vertex" to i, or null if there is no such vertex. 042 * @throws InvalidVertexException if the supplied vertices are invalid. 043 */ 044 public Vector<VertexType> 045 getShortestPath(final BaseGraph<VertexType, EdgeType> graph, 046 VertexType vertex) 047 throws InvalidVertexException { 048 graph.checkVertex(vertex); 049 050 final Integer dist[] = new Integer[graph.getVerticesCount()]; 051 //the edge connected to i'th vertex 052 final HashMap<VertexType, EdgeType> edges = new HashMap<VertexType, EdgeType>(); 053 Vector<VertexType> prev = new Vector<VertexType>(); 054 055 for (int i = 0; i < dist.length; i++) 056 dist[i] = Integer.MAX_VALUE; 057 058 dist[vertex.getId()] = 0; 059 060 class VertexComparator implements Comparator<VertexType> { 061 public int compare(VertexType o1, VertexType o2) { 062 if (dist[o1.getId()] < dist[o2.getId()]) 063 return -1; 064 if (dist[o1.getId()] == dist[o2.getId()]) 065 return 0; 066 else 067 return 1; 068 } 069 } 070 071 VertexComparator vComp = new VertexComparator(); 072 073 //selected vertices 074 HashSet<VertexType> selectedVertices = new HashSet<VertexType>(); 075 076 PriorityQueue<VertexType> Q = new PriorityQueue<VertexType>(1, vComp); 077 078 Q.add(vertex); 079 dispatchEvent(new VertexEvent<VertexType, EdgeType>(graph, vertex, VertexEvent.EventType.MARK)); 080 vertex.setMark(true); 081 while (!Q.isEmpty()) { 082 VertexType vMin = Q.poll(); 083 vMin.setMark(true); 084 EdgeType edg = edges.get(vMin); 085 if (edg != null) 086 edg.setMark(true); 087 // vMin.setColor(2); 088 EventUtils.algorithmStep(this, ""); 089 selectedVertices.add(vMin); 090 Iterator<EdgeType> iet = graph.edgeIterator(vMin); 091 while ((iet.hasNext())) { 092 EdgeType edge = iet.next(); 093 // edge.setColor((int) (Math.random() * 10)); 094 // EventUtils.algorithmStep(this,600); 095 VertexType target = vMin == edge.source ? edge.target : edge.source; 096 VertexType source = vMin; 097 if (!selectedVertices.contains(target)) { 098 if (dist[target.getId()] > dist[source.getId()] + edge.getWeight()) { 099 dist[target.getId()] = dist[source.getId()] + edge.getWeight(); 100 // dispatchEvent(new EdgeEvent<VertexType, EdgeType>(graph, edge, EdgeEvent.EventType.MARK)); 101 // dispatchEvent(new VertexEvent<VertexType, EdgeType>(graph, target, VertexEvent.EventType.MARK)); 102 // edge.setMark(true); 103 edges.put(target, edge); 104 // target.setMark(true); 105 // target.setColor(5); 106 Q.add(target); 107 // prev.add(edge.source.getId(), edge.target); 108 } 109 } 110 } 111 } 112 113 return prev; 114 } 115 116 public void doAlgorithm() { 117 GraphRequest<VertexType, EdgeType> gr = new GraphRequest<VertexType, EdgeType>(); 118 dispatchEvent(gr); 119 BaseGraph<VertexType, EdgeType> g = gr.getGraph(); 120 VertexRequest<VertexType, EdgeType> vr = new VertexRequest<VertexType, EdgeType>(g, "Please choose a vertex for the Dijkstra algorithm."); 121 dispatchEvent(vr); 122 VertexType v = vr.getVertex(); 123 getShortestPath(g, v); 124 } 125 }