@@ -15,6 +15,7 @@ module.exports = function Graph(serialized){
1515 outdegree : outdegree ,
1616 depthFirstSearch : depthFirstSearch ,
1717 topologicalSort : topologicalSort ,
18+ shortestPath : shortestPath ,
1819 serialize : serialize ,
1920 deserialize : deserialize
2021 } ;
@@ -194,6 +195,91 @@ module.exports = function Graph(serialized){
194195 return depthFirstSearch ( sourceNodes , includeSourceNodes ) . reverse ( ) ;
195196 }
196197
198+ // Dijkstra's Shortest Path Algorithm.
199+ // Cormen et al. "Introduction to Algorithms" 3rd Ed. p. 658
200+ // Variable and function names correspond to names in the book.
201+ function shortestPath ( source , destination ) {
202+
203+ // Upper bounds for shortest path weights from source.
204+ var d = { } ;
205+
206+ // Predecessors.
207+ var p = { } ;
208+
209+ // Poor man's priority queue, keyed on d.
210+ var q = { } ;
211+
212+ function initializeSingleSource ( ) {
213+ nodes ( ) . forEach ( function ( node ) {
214+ d [ node ] = Infinity ;
215+ } ) ;
216+ d [ source ] = 0 ;
217+ }
218+
219+ // Adds entries in q for all nodes.
220+ function initializePriorityQueue ( ) {
221+ nodes ( ) . forEach ( function ( node ) {
222+ q [ node ] = true ;
223+ } ) ;
224+ }
225+
226+ // Returns true if q is empty.
227+ function priorityQueueEmpty ( ) {
228+ return Object . keys ( q ) . length === 0 ;
229+ }
230+
231+ // Linear search to extract (find and remove) min from q.
232+ function extractMin ( ) {
233+ var min = Infinity ;
234+ var minNode ;
235+ Object . keys ( q ) . forEach ( function ( node ) {
236+ if ( d [ node ] < min ) {
237+ min = d [ node ] ;
238+ minNode = node ;
239+ }
240+ } ) ;
241+ delete q [ minNode ] ;
242+ return minNode ;
243+ }
244+
245+ function relax ( u , v ) {
246+ var w = getEdgeWeight ( u , v ) ;
247+ if ( d [ v ] > d [ u ] + w ) {
248+ d [ v ] = d [ u ] + w ;
249+ p [ v ] = u ;
250+ }
251+ }
252+
253+ function dijkstra ( ) {
254+ initializeSingleSource ( ) ;
255+ initializePriorityQueue ( ) ;
256+ while ( ! priorityQueueEmpty ( ) ) {
257+ var u = extractMin ( ) ;
258+ adjacent ( u ) . forEach ( function ( v ) {
259+ relax ( u , v ) ;
260+ } ) ;
261+ }
262+ }
263+
264+ // Assembles the shortest path by traversing the
265+ // predecessor subgraph from destination to source.
266+ function path ( ) {
267+ var nodeList = [ ] ;
268+ var node = destination ;
269+ while ( p [ node ] ) {
270+ nodeList . push ( node ) ;
271+ node = p [ node ] ;
272+ }
273+ nodeList . push ( source ) ;
274+ nodeList . reverse ( ) ;
275+ return nodeList ;
276+ }
277+
278+ dijkstra ( ) ;
279+
280+ return path ( ) ;
281+ }
282+
197283 // Serializes the graph.
198284 function serialize ( ) {
199285 var serialized = {
0 commit comments