Dijkstra's algorithm: Difference between revisions

Content added Content deleted
m (syntax highlighting fixup automation)
Line 45: Line 45:


;An example, starting with:
;An example, starting with:
<lang> a──►b, cost=7, lastNode=a
<syntaxhighlight lang="text"> a──►b, cost=7, lastNode=a
a──►c, cost=9, lastNode=a
a──►c, cost=9, lastNode=a
a──►d, cost=NA, lastNode=a
a──►d, cost=NA, lastNode=a
Line 84: Line 84:
c──►f
c──►f
a──►c
a──►c
a──►b ] </lang>
a──►b ] </syntaxhighlight>




Line 144: Line 144:
{{trans|Python}}
{{trans|Python}}


<lang 11l>T Edge
<syntaxhighlight lang="11l">T Edge
String start
String start
String end
String end
Line 194: Line 194:
(‘b’, ‘d’, 15), (‘c’, ‘d’, 11), (‘c’, ‘f’, 2), (‘d’, ‘e’, 6),
(‘b’, ‘d’, 15), (‘c’, ‘d’, 11), (‘c’, ‘f’, 2), (‘d’, ‘e’, 6),
(‘e’, ‘f’, 9)])
(‘e’, ‘f’, 9)])
print(graph.dijkstra(‘a’, ‘e’))</lang>
print(graph.dijkstra(‘a’, ‘e’))</syntaxhighlight>


{{out}}
{{out}}
Line 205: Line 205:
This solution uses a generic package and Ada 2012 (containers, extended return statements, expression functions).
This solution uses a generic package and Ada 2012 (containers, extended return statements, expression functions).
The very convenient 'Img attribute is a GNAT feature.
The very convenient 'Img attribute is a GNAT feature.
<lang Ada>private with Ada.Containers.Ordered_Maps;
<syntaxhighlight lang="ada">private with Ada.Containers.Ordered_Maps;
generic
generic
type t_Vertex is (<>);
type t_Vertex is (<>);
Line 236: Line 236:
end record;
end record;
type t_Graph is array (t_Vertex) of t_Vertex_Data;
type t_Graph is array (t_Vertex) of t_Vertex_Data;
end Dijkstra;</lang>
end Dijkstra;</syntaxhighlight>


<lang Ada>with Ada.Containers.Ordered_Sets;
<syntaxhighlight lang="ada">with Ada.Containers.Ordered_Sets;
package body Dijkstra is
package body Dijkstra is


Line 328: Line 328:
end Distance;
end Distance;


end Dijkstra;</lang>
end Dijkstra;</syntaxhighlight>
The testing main procedure :
The testing main procedure :
<lang Ada>with Ada.Text_IO; use Ada.Text_IO;
<syntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;
with Dijkstra;
with Dijkstra;
procedure Test_Dijkstra is
procedure Test_Dijkstra is
Line 368: Line 368:
end loop;
end loop;
end loop;
end loop;
end Test_Dijkstra;</lang>
end Test_Dijkstra;</syntaxhighlight>
{{out}}
{{out}}
<pre>Path from 'a' to 'e' = [a,c,d,e] distance = 26
<pre>Path from 'a' to 'e' = [a,c,d,e] distance = 26
Line 414: Line 414:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-2.6 algol68g-2.6].}}
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-2.6 algol68g-2.6].}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
'''File: prelude_dijkstras_algorithm.a68'''<lang algol68># -*- coding: utf-8 -*- #
'''File: prelude_dijkstras_algorithm.a68'''<syntaxhighlight lang="algol68"># -*- coding: utf-8 -*- #


COMMENT REQUIRED BY "prelude_dijkstras_algorithm.a68" CO
COMMENT REQUIRED BY "prelude_dijkstras_algorithm.a68" CO
Line 554: Line 554:
);
);


SKIP</lang>'''File: test_dijkstras_algorithm.a68'''<lang algol68>#!/usr/bin/a68g --script #
SKIP</syntaxhighlight>'''File: test_dijkstras_algorithm.a68'''<syntaxhighlight lang="algol68">#!/usr/bin/a68g --script #
# -*- coding: utf-8 -*- #
# -*- coding: utf-8 -*- #


Line 605: Line 605:
# TODO: generate random 100000 VERTEX graph test case and test performance - important #
# TODO: generate random 100000 VERTEX graph test case and test performance - important #


)</lang>'''Output:'''
)</syntaxhighlight>'''Output:'''
<pre>
<pre>
a --9-> c --2-> f --9-> e
a --9-> c --2-> f --9-> e
Line 611: Line 611:


=={{header|Applesoft BASIC}}==
=={{header|Applesoft BASIC}}==
<lang basic>100 O$ = "A" : T$ = "EF"
<syntaxhighlight lang="basic">100 O$ = "A" : T$ = "EF"
110 DEF FN N(P) = ASC(MID$(N$,P+(P=0),1))-64
110 DEF FN N(P) = ASC(MID$(N$,P+(P=0),1))-64
120 DIM D(26),UNVISITED(26)
120 DIM D(26),UNVISITED(26)
Line 661: Line 661:
670 DATA 6,D-E
670 DATA 6,D-E
680 DATA 9,E-F
680 DATA 9,E-F
690 DATA</lang>
690 DATA</syntaxhighlight>
'''Output:'''
'''Output:'''
<pre>SHORTEST PATH
<pre>SHORTEST PATH
Line 674: Line 674:
{{trans|Nim}}
{{trans|Nim}}


<lang rebol>define :graph [vertices, neighbours][]
<syntaxhighlight lang="rebol">define :graph [vertices, neighbours][]


initGraph: function [edges][
initGraph: function [edges][
Line 745: Line 745:


print ["Shortest path from 'a' to 'e': " join.with:" -> " dijkstraPath graph "a" "e"]
print ["Shortest path from 'a' to 'e': " join.with:" -> " dijkstraPath graph "a" "e"]
print ["Shortest path from 'a' to 'f': " join.with:" -> " dijkstraPath graph "a" "f"]</lang>
print ["Shortest path from 'a' to 'f': " join.with:" -> " dijkstraPath graph "a" "f"]</syntaxhighlight>


{{out}}
{{out}}
Line 753: Line 753:


=={{header|AutoHotkey}}==
=={{header|AutoHotkey}}==
<lang AutoHotkey>Dijkstra(data, start){
<syntaxhighlight lang="autohotkey">Dijkstra(data, start){
nodes := [], dist := [], Distance := [], dist := [], prev := [], Q := [], min := "x"
nodes := [], dist := [], Distance := [], dist := [], prev := [], Q := [], min := "x"
for each, line in StrSplit(data, "`n" , "`r")
for each, line in StrSplit(data, "`n" , "`r")
Line 797: Line 797:
count := A_Index
count := A_Index
return count
return count
}</lang>
}</syntaxhighlight>
Examples:<lang AutoHotkey>data =
Examples:<syntaxhighlight lang="autohotkey">data =
(
(
A B 7
A B 7
Line 856: Line 856:
GuiClose:
GuiClose:
ExitApp
ExitApp
return</lang>
return</syntaxhighlight>
Outputs:<pre>A > C 9
Outputs:<pre>A > C 9
C > F 2
C > F 2
Line 865: Line 865:
=={{header|C}}==
=={{header|C}}==
The priority queue is implemented as a binary heap. The heap stores an index into its data array, so it can quickly update the weight of an item already in it.
The priority queue is implemented as a binary heap. The heap stores an index into its data array, so it can quickly update the weight of an item already in it.
<syntaxhighlight lang="cafe">
<lang Cafe>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
Line 1,046: Line 1,046:
return 0;
return 0;
}
}
</syntaxhighlight>
</lang>
output
output
26 acde
26 acde
Line 1,052: Line 1,052:
=={{header|C sharp|C#}}==
=={{header|C sharp|C#}}==
{{works with|C sharp|7}}
{{works with|C sharp|7}}
<lang csharp>using static System.Linq.Enumerable;
<syntaxhighlight lang="csharp">using static System.Linq.Enumerable;
using static System.String;
using static System.String;
using static System.Console;
using static System.Console;
Line 1,189: Line 1,189:
}
}


}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 1,212: Line 1,212:
The outer loop executes once for each element popped from the priority queue, so it will execute at most once for each vertex, so at most V times. Each iteration of the outer loop executes one pop from the priority queue, which has time complexity O(log V). The inner loop executes at most once for each directed edge, since each directed edge has one originating vertex, and there is only at most one iteration of the outer loop for each vertex. Each iteration of the inner loop potentially performs one push or re-order on the priority queue (where re-order is a pop and a push), which has complexity O(log V). There is also the O(V) complexity for initializing the data structures. Combining these, we have a complexity of O(V log V + E log V), and assuming this is a connected graph, V <= E+1 = O(E), so we can write it as O(E log V).
The outer loop executes once for each element popped from the priority queue, so it will execute at most once for each vertex, so at most V times. Each iteration of the outer loop executes one pop from the priority queue, which has time complexity O(log V). The inner loop executes at most once for each directed edge, since each directed edge has one originating vertex, and there is only at most one iteration of the outer loop for each vertex. Each iteration of the inner loop potentially performs one push or re-order on the priority queue (where re-order is a pop and a push), which has complexity O(log V). There is also the O(V) complexity for initializing the data structures. Combining these, we have a complexity of O(V log V + E log V), and assuming this is a connected graph, V <= E+1 = O(E), so we can write it as O(E log V).


<lang cpp>#include <iostream>
<syntaxhighlight lang="cpp">#include <iostream>
#include <vector>
#include <vector>
#include <string>
#include <string>
Line 1,332: Line 1,332:


return 0;
return 0;
}</lang>
}</syntaxhighlight>


----
----
Line 1,346: Line 1,346:
The number of times the outer loop executes (the number of times an element is popped from the priority queue) is bounded by E, and in each iteration, the popping operation takes time complexity O(log E). The number of times the inner loop executes is also bounded by E, and the pushing operation inside it also takes time complexity O(log E). So in total, the time complexity is O(E log E). But not that, for a simple graph, E < V^2, so log E < 2 log V = O(log V). So O(E log E) can also be written as O(E log V), which is the same as for the preceding algorithm.
The number of times the outer loop executes (the number of times an element is popped from the priority queue) is bounded by E, and in each iteration, the popping operation takes time complexity O(log E). The number of times the inner loop executes is also bounded by E, and the pushing operation inside it also takes time complexity O(log E). So in total, the time complexity is O(E log E). But not that, for a simple graph, E < V^2, so log E < 2 log V = O(log V). So O(E log E) can also be written as O(E log V), which is the same as for the preceding algorithm.


<lang cpp>#include <iostream>
<syntaxhighlight lang="cpp">#include <iostream>
#include <vector>
#include <vector>
#include <string>
#include <string>
Line 1,473: Line 1,473:


return 0;
return 0;
}</lang>
}</syntaxhighlight>


=={{header|CafeOBJ}}==
=={{header|CafeOBJ}}==
Dijkstra's algorithm repeatedly chooses the nearest vertex and relaxes the edges leaving it, terminating when no more vertices are accessible from the origin.
Dijkstra's algorithm repeatedly chooses the nearest vertex and relaxes the edges leaving it, terminating when no more vertices are accessible from the origin.


<syntaxhighlight lang="cafeobj">
<lang CafeOBJ>
"
"
This code works with CafeOBJ 1.5.1 and CafeOBJ 1.5.5.
This code works with CafeOBJ 1.5.1 and CafeOBJ 1.5.5.
Line 1,671: Line 1,671:
-- 'a' :p 'c' :p 'f':PathList
-- 'a' :p 'c' :p 'f':PathList
eof
eof
</syntaxhighlight>
</lang>


=={{header|Clojure}}==
=={{header|Clojure}}==
<lang clojure>
<syntaxhighlight lang="clojure">
(declare neighbours
(declare neighbours
process-neighbour
process-neighbour
Line 1,872: Line 1,872:
;; | e | 26 | (a c d e) |
;; | e | 26 | (a c d e) |
;; | f | 11 | (a c f) |
;; | f | 11 | (a c f) |
</syntaxhighlight>
</lang>


=={{header|Commodore BASIC}}==
=={{header|Commodore BASIC}}==
Line 1,879: Line 1,879:
(The program outputs the shortest path to each node in the graph, including E and F, so I assume that meets the requirements of Task item 3.)
(The program outputs the shortest path to each node in the graph, including E and F, so I assume that meets the requirements of Task item 3.)


<lang basic>100 NV=0: REM NUMBER OF VERTICES
<syntaxhighlight lang="basic">100 NV=0: REM NUMBER OF VERTICES
110 READ N$:IF N$<>"" THEN NV=NV+1:GOTO 110
110 READ N$:IF N$<>"" THEN NV=NV+1:GOTO 110
120 NE=0: REM NUMBER OF EDGES
120 NE=0: REM NUMBER OF EDGES
Line 1,941: Line 1,941:
700 DATA 4,5,9
700 DATA 4,5,9
710 DATA -1
710 DATA -1
720 DATA 0</lang>
720 DATA 0</syntaxhighlight>


{{Out}}
{{Out}}
Line 1,955: Line 1,955:


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
<lang lisp>
<syntaxhighlight lang="lisp">
(defparameter *w* '((a (a b . 7) (a c . 9) (a f . 14))
(defparameter *w* '((a (a b . 7) (a c . 9) (a f . 14))
(b (b c . 10) (b d . 15))
(b (b c . 10) (b d . 15))
Line 1,976: Line 1,976:
(defun nodes (c)
(defun nodes (c)
(sort (cdr (assoc c *w*)) #'< :key #'cddr))
(sort (cdr (assoc c *w*)) #'< :key #'cddr))
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 1,982: Line 1,982:
((A C D E) 26)
((A C D E) 26)
</pre>
</pre>
<lang lisp>
<syntaxhighlight lang="lisp">
(defvar *r* nil)
(defvar *r* nil)
Line 1,999: Line 1,999:
(paths w b g (+ (cddr a) z)
(paths w b g (+ (cddr a) z)
(cons b v))))))
(cons b v))))))
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 2,030: Line 2,030:
{{trans|C++}}
{{trans|C++}}
The algorithm and the important data structures are essentially the same as in the C++ version, so the same comments apply (built-in D associative arrays are unsorted).
The algorithm and the important data structures are essentially the same as in the C++ version, so the same comments apply (built-in D associative arrays are unsorted).
<lang d>import std.stdio, std.typecons, std.algorithm, std.container;
<syntaxhighlight lang="d">import std.stdio, std.typecons, std.algorithm, std.container;


alias Vertex = string;
alias Vertex = string;
Line 2,112: Line 2,112:
writeln(`Distance from "a" to "e": `, minDistance["e"]);
writeln(`Distance from "a" to "e": `, minDistance["e"]);
writeln("Path: ", dijkstraGetShortestPathTo("e", previous));
writeln("Path: ", dijkstraGetShortestPathTo("e", previous));
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>Distance from "a" to "e": 26
<pre>Distance from "a" to "e": 26
Line 2,121: Line 2,121:


An infinite distance is here represented by -1, which complicates the code when comparing distances, but ensures that infinity can't be equalled or exceeded by any finite distance.
An infinite distance is here represented by -1, which complicates the code when comparing distances, but ensures that infinity can't be equalled or exceeded by any finite distance.
<lang delphi>program Rosetta_Dijkstra_Console;
<syntaxhighlight lang="delphi">program Rosetta_Dijkstra_Console;


{$APPTYPE CONSOLE}
{$APPTYPE CONSOLE}
Line 2,230: Line 2,230:
WriteLn( lineOut);
WriteLn( lineOut);
end;
end;
end.</lang>
end.</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 2,243: Line 2,243:
=={{header|Emacs Lisp}}==
=={{header|Emacs Lisp}}==


<lang lisp>
<syntaxhighlight lang="lisp">
;; Path format: (start-point end-point previous-point distance)
;; Path format: (start-point end-point previous-point distance)
(setq path-list `(
(setq path-list `(
Line 2,337: Line 2,337:
(calculate-shortest-path)
(calculate-shortest-path)
</syntaxhighlight>
</lang>


outputs:
outputs:
Line 2,353: Line 2,353:


=={{header|Erlang}}==
=={{header|Erlang}}==
<lang erlang>
<syntaxhighlight lang="erlang">
-module(dijkstra).
-module(dijkstra).
-include_lib("eunit/include/eunit.hrl").
-include_lib("eunit/include/eunit.hrl").
Line 2,400: Line 2,400:
io:format(user, "The total cost was ~p and the path was: ", [Cost]),
io:format(user, "The total cost was ~p and the path was: ", [Cost]),
io:format(user, "~w~n", [Path]).
io:format(user, "~w~n", [Path]).
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 2,415: Line 2,415:
=={{header|F_Sharp|F#}}==
=={{header|F_Sharp|F#}}==
===Dijkstra's algorithm===
===Dijkstra's algorithm===
<lang fsharp>
<syntaxhighlight lang="fsharp">
//Dijkstra's algorithm: Nigel Galloway, August 5th., 2018
//Dijkstra's algorithm: Nigel Galloway, August 5th., 2018
[<CustomEquality;CustomComparison>]
[<CustomEquality;CustomComparison>]
Line 2,443: Line 2,443:
|_ ->None
|_ ->None
fN n [])
fN n [])
</syntaxhighlight>
</lang>


===The Task===
===The Task===
<lang fsharp>
<syntaxhighlight lang="fsharp">
type Node= |A|B|C|D|E|F
type Node= |A|B|C|D|E|F
let G=Map[((A,B),7);((A,C),9);((A,F),14);((B,C),10);((B,D),15);((C,D),11);((C,F),2);((D,E),6);((E,F),9)]
let G=Map[((A,B),7);((A,C),9);((A,F),14);((B,C),10);((B,D),15);((C,D),11);((C,F),2);((D,E),6);((E,F),9)]
Line 2,452: Line 2,452:
printfn "%A" (paths E)
printfn "%A" (paths E)
printfn "%A" (paths F)
printfn "%A" (paths F)
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 2,460: Line 2,460:


=={{header|Go}}==
=={{header|Go}}==
<lang go>package main
<syntaxhighlight lang="go">package main


import (
import (
Line 2,622: Line 2,622:
fmt.Printf("Distance to %s: %d, Path: %s\n", "e", dist[g.ids["e"]], g.path(g.ids["e"], prev))
fmt.Printf("Distance to %s: %d, Path: %s\n", "e", dist[g.ids["e"]], g.path(g.ids["e"], prev))
fmt.Printf("Distance to %s: %d, Path: %s\n", "f", dist[g.ids["f"]], g.path(g.ids["f"], prev))
fmt.Printf("Distance to %s: %d, Path: %s\n", "f", dist[g.ids["f"]], g.path(g.ids["f"], prev))
}</lang>
}</syntaxhighlight>
Runable on the [https://play.golang.org/p/w6nJ1ovjwn7 Go playground].
Runable on the [https://play.golang.org/p/w6nJ1ovjwn7 Go playground].
{{out}}
{{out}}
Line 2,634: Line 2,634:
{{trans|C++}}
{{trans|C++}}
Translation of the C++ solution, and all the complexities are the same as in the C++ solution. In particular, we again use a self-balancing binary search tree (<code>Data.Set</code>) to implement the priority queue, which results in an optimal complexity.
Translation of the C++ solution, and all the complexities are the same as in the C++ solution. In particular, we again use a self-balancing binary search tree (<code>Data.Set</code>) to implement the priority queue, which results in an optimal complexity.
<lang haskell>
<syntaxhighlight lang="haskell">
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleContexts #-}
import Data.Array
import Data.Array
Line 2,692: Line 2,692:
putStrLn $ "Distance from a to e: " ++ show (min_distance ! 'e')
putStrLn $ "Distance from a to e: " ++ show (min_distance ! 'e')
let path = shortest_path_to 'e' ' ' previous
let path = shortest_path_to 'e' ' ' previous
putStrLn $ "Path: " ++ show path</lang>
putStrLn $ "Path: " ++ show path</syntaxhighlight>


=={{header|Huginn}}==
=={{header|Huginn}}==
<lang huginn>import Algorithms as algo;
<syntaxhighlight lang="huginn">import Algorithms as algo;
import Mathematics as math;
import Mathematics as math;
import Text as text;
import Text as text;
Line 2,824: Line 2,824:
print( "{}\n".format( g.path( paths, "e" ) ) );
print( "{}\n".format( g.path( paths, "e" ) ) );
print( "{}\n".format( g.path( paths, "f" ) ) );
print( "{}\n".format( g.path( paths, "f" ) ) );
}</lang>
}</syntaxhighlight>


Sample run via: <pre>cat ~/graph.g | ./dijkstra.hgn</pre>, output:
Sample run via: <pre>cat ~/graph.g | ./dijkstra.hgn</pre>, output:
Line 2,848: Line 2,848:
discovered and then outputs the shortest path.
discovered and then outputs the shortest path.


<lang unicon>procedure main(A)
<syntaxhighlight lang="unicon">procedure main(A)
graph := getGraph()
graph := getGraph()
repeat {
repeat {
Line 2,956: Line 2,956:
procedure waitForCompletion()
procedure waitForCompletion()
critical qMiceEmpty: while *qMice > 0 do wait(qMiceEmpty)
critical qMiceEmpty: while *qMice > 0 do wait(qMiceEmpty)
end</lang>
end</syntaxhighlight>


Sample run:
Sample run:
Line 2,990: Line 2,990:


=={{header|J}}==
=={{header|J}}==
<syntaxhighlight lang="j">
<lang J>
NB. verbs and adverb
NB. verbs and adverb
parse_table=: ;:@:(LF&= [;._2 -.&CR)
parse_table=: ;:@:(LF&= [;._2 -.&CR)
Line 3,065: Line 3,065:
5 3 9
5 3 9
)
)
</syntaxhighlight>
</lang>


=== J: Alternative Implementation ===
=== J: Alternative Implementation ===


<lang j>vertices=: ;:'a b c d e f'
<syntaxhighlight lang="j">vertices=: ;:'a b c d e f'
edges=:|: ;:;._2]0 :0
edges=:|: ;:;._2]0 :0
a b 7
a b 7
Line 3,111: Line 3,111:
end.
end.
best {L:0 _ m
best {L:0 _ m
)</lang>
)</syntaxhighlight>


Example use:
Example use:


<lang J> (;:'a e') vertices shortest_path edges
<syntaxhighlight lang="j"> (;:'a e') vertices shortest_path edges
┌─────────┐
┌─────────┐
│┌─┬─┬─┬─┐│
│┌─┬─┬─┬─┐│
││a│c│d│e││
││a│c│d│e││
│└─┴─┴─┴─┘│
│└─┴─┴─┴─┘│
└─────────┘</lang>
└─────────┘</syntaxhighlight>


This version finds all shortest paths, and for this example completes in two thirds the time of the other J implementation.
This version finds all shortest paths, and for this example completes in two thirds the time of the other J implementation.
Line 3,132: Line 3,132:
Vertices are stored in a TreeSet (self-balancing binary search tree) instead of a PriorityQueue (a binary heap) in order to get O(log n) performance for removal of any element, not just the head.
Vertices are stored in a TreeSet (self-balancing binary search tree) instead of a PriorityQueue (a binary heap) in order to get O(log n) performance for removal of any element, not just the head.
Decreasing the distance of a vertex is accomplished by removing it from the tree and later re-inserting it.
Decreasing the distance of a vertex is accomplished by removing it from the tree and later re-inserting it.
<lang java>
<syntaxhighlight lang="java">
import java.io.*;
import java.io.*;
import java.util.*;
import java.util.*;
Line 3,292: Line 3,292:
}
}
}
}
}</lang>{{out}}<pre>
}</syntaxhighlight>{{out}}<pre>
a -> c(9) -> d(20) -> e(26)
a -> c(9) -> d(20) -> e(26)
</pre>
</pre>
Line 3,298: Line 3,298:
=={{header|Javascript}}==
=={{header|Javascript}}==
Using the [[wp:Dijkstra's_algorithm#Pseudocode]]
Using the [[wp:Dijkstra's_algorithm#Pseudocode]]
<lang javascript>
<syntaxhighlight lang="javascript">
const dijkstra = (edges,source,target) => {
const dijkstra = (edges,source,target) => {
const Q = new Set(),
const Q = new Set(),
Line 3,384: Line 3,384:
console.log(path) //[ 'a', 'c', 'f', 'e' ]
console.log(path) //[ 'a', 'c', 'f', 'e' ]
console.log(length) //20
console.log(length) //20
</syntaxhighlight>
</lang>


=={{header|jq}}==
=={{header|jq}}==
Line 3,402: Line 3,402:


'''Preliminaries'''
'''Preliminaries'''
<lang jq># (*) If using gojq, uncomment the following line:
<syntaxhighlight lang="jq"># (*) If using gojq, uncomment the following line:
# def keys_unsorted: keys;
# def keys_unsorted: keys;


Line 3,471: Line 3,471:
| readout($endname) ;
| readout($endname) ;


</syntaxhighlight>
</lang>
'''The Task'''
'''The Task'''
<lang jq>def GRAPH: {
<syntaxhighlight lang="jq">def GRAPH: {
"a": {"b": 7, "c": 9, "f": 14},
"a": {"b": 7, "c": 9, "f": 14},
"b": {"c": 10, "d": 15},
"b": {"c": 10, "d": 15},
Line 3,485: Line 3,485:


"\nThe shortest paths from a to e and to f:",
"\nThe shortest paths from a to e and to f:",
(GRAPH | Dijkstra("a"; "e", "f") | .[0])</lang>
(GRAPH | Dijkstra("a"; "e", "f") | .[0])</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 3,497: Line 3,497:
{{works with|Julia|0.6}}
{{works with|Julia|0.6}}


<lang julia>struct Digraph{T <: Real,U}
<syntaxhighlight lang="julia">struct Digraph{T <: Real,U}
edges::Dict{Tuple{U,U},T}
edges::Dict{Tuple{U,U},T}
verts::Set{U}
verts::Set{U}
Line 3,569: Line 3,569:
path, cost = dijkstrapath(g, src, dst)
path, cost = dijkstrapath(g, src, dst)
@printf("%4s | %3s | %s\n", src, dst, isempty(path) ? "no possible path" : join(path, " → ") * " ($cost)")
@printf("%4s | %3s | %s\n", src, dst, isempty(path) ? "no possible path" : join(path, " → ") * " ($cost)")
end</lang>
end</syntaxhighlight>


{{out}}
{{out}}
Line 3,615: Line 3,615:
=={{header|Kotlin}}==
=={{header|Kotlin}}==
{{trans|Java}}
{{trans|Java}}
<lang scala>// version 1.1.51
<syntaxhighlight lang="scala">// version 1.1.51


import java.util.TreeSet
import java.util.TreeSet
Line 3,761: Line 3,761:
printPath(END)
printPath(END)
}
}
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 3,772: Line 3,772:
=={{header|Lua}}==
=={{header|Lua}}==
Hopefully the variable names here make the process as clear as possible...
Hopefully the variable names here make the process as clear as possible...
<lang Lua>-- Graph definition
<syntaxhighlight lang="lua">-- Graph definition
local edges = {
local edges = {
a = {b = 7, c = 9, f = 14},
a = {b = 7, c = 9, f = 14},
Line 3,838: Line 3,838:
-- Main procedure
-- Main procedure
print("Directed:", dijkstra(edges, "a", "e", true))
print("Directed:", dijkstra(edges, "a", "e", true))
print("Undirected:", dijkstra(edges, "a", "e", false))</lang>
print("Undirected:", dijkstra(edges, "a", "e", false))</syntaxhighlight>
{{out}}
{{out}}
<pre>Directed: 26 a c d e
<pre>Directed: 26 a c d e
Line 3,844: Line 3,844:


=={{header|M2000 Interpreter}}==
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Dijkstra`s_algorithm {
Module Dijkstra`s_algorithm {
const max_number=1.E+306
const max_number=1.E+306
Line 3,932: Line 3,932:
}
}
Dijkstra`s_algorithm
Dijkstra`s_algorithm
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 3,988: Line 3,988:


=={{header|Maple}}==
=={{header|Maple}}==
<lang maple>restart:
<syntaxhighlight lang="maple">restart:
with(GraphTheory):
with(GraphTheory):
G:=Digraph([a,b,c,d,e,f],{[[a,b],7],[[a,c],9],[[a,f],14],[[b,c],10],[[b,d],15],[[c,d],11],[[c,f],2],[[d,e],6],[[e,f],9]}):
G:=Digraph([a,b,c,d,e,f],{[[a,b],7],[[a,c],9],[[a,f],14],[[b,c],10],[[b,d],15],[[c,d],11],[[c,f],2],[[d,e],6],[[e,f],9]}):
DijkstrasAlgorithm(G,a);
DijkstrasAlgorithm(G,a);
# [[[a], 0], [[a, b], 7], [[a, c], 9], [[a, c, d], 20], [[a, c, d, e], 26], [[a, c, f], 11]]</lang>
# [[[a], 0], [[a, b], 7], [[a, c], 9], [[a, c, d], 20], [[a, c, d, e], 26], [[a, c, f], 11]]</syntaxhighlight>


=={{header|Mathematica}}/{{header|Wolfram Language}}==
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<lang Mathematica>bd = Graph[{"a" \[DirectedEdge] "b", "a" \[DirectedEdge] "c",
<syntaxhighlight lang="mathematica">bd = Graph[{"a" \[DirectedEdge] "b", "a" \[DirectedEdge] "c",
"b" \[DirectedEdge] "c", "b" \[DirectedEdge] "d",
"b" \[DirectedEdge] "c", "b" \[DirectedEdge] "d",
"c" \[DirectedEdge] "d", "d" \[DirectedEdge] "e",
"c" \[DirectedEdge] "d", "d" \[DirectedEdge] "e",
Line 4,005: Line 4,005:


FindShortestPath[bd, "a", "e", Method -> "Dijkstra"]
FindShortestPath[bd, "a", "e", Method -> "Dijkstra"]
-> {"a", "c", "d", "e"}</lang>
-> {"a", "c", "d", "e"}</syntaxhighlight>
[[File:Mma_dijkstra2.PNG]]
[[File:Mma_dijkstra2.PNG]]


=={{header|Maxima}}==
=={{header|Maxima}}==
<lang maxima>load(graphs)$
<syntaxhighlight lang="maxima">load(graphs)$
g: create_graph([[1, "a"], [2, "b"], [3, "c"], [4, "d"], [5, "e"], [6, "f"]],
g: create_graph([[1, "a"], [2, "b"], [3, "c"], [4, "d"], [5, "e"], [6, "f"]],
[[[1, 2], 7],
[[[1, 2], 7],
Line 4,022: Line 4,022:
shortest_weighted_path(1, 5, g);
shortest_weighted_path(1, 5, g);
/* [26, [1, 3, 4, 5]] */</lang>
/* [26, [1, 3, 4, 5]] */</syntaxhighlight>


=={{header|Nim}}==
=={{header|Nim}}==
Translation of Wikipedia pseudo-code.
Translation of Wikipedia pseudo-code.
<syntaxhighlight lang="nim">
<lang Nim>
# Dijkstra algorithm.
# Dijkstra algorithm.


Line 4,106: Line 4,106:
printPath(graph.dijkstraPath("a", "e"))
printPath(graph.dijkstraPath("a", "e"))
printPath(graph.dijkstraPath("a", "f"))
printPath(graph.dijkstraPath("a", "f"))
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 4,117: Line 4,117:
Just a straightforward implementation of the pseudo-code from the Wikipedia article:
Just a straightforward implementation of the pseudo-code from the Wikipedia article:


<lang ocaml>let list_vertices graph =
<syntaxhighlight lang="ocaml">let list_vertices graph =
List.fold_left (fun acc ((a, b), _) ->
List.fold_left (fun acc ((a, b), _) ->
let acc = if List.mem b acc then acc else b::acc in
let acc = if List.mem b acc then acc else b::acc in
Line 4,203: Line 4,203:
in
in
let p = dijkstra max_int 0 (+) graph "a" "e" in
let p = dijkstra max_int 0 (+) graph "a" "e" in
print_endline (String.concat " -> " p)</lang>
print_endline (String.concat " -> " p)</syntaxhighlight>


Output:
Output:
Line 4,211: Line 4,211:
{{trans|C++}}
{{trans|C++}}
Translation of the C++ solution, and all the complexities are the same as in the C++ solution. In particular, we again use a self-balancing binary search tree (<code>Set</code>) to implement the priority queue, which results in an optimal complexity.
Translation of the C++ solution, and all the complexities are the same as in the C++ solution. In particular, we again use a self-balancing binary search tree (<code>Set</code>) to implement the priority queue, which results in an optimal complexity.
<lang ocaml>type vertex = int
<syntaxhighlight lang="ocaml">type vertex = int
type weight = float
type weight = float
type neighbor = vertex * weight
type neighbor = vertex * weight
Line 4,266: Line 4,266:
print_string "Path: ";
print_string "Path: ";
List.iter (Printf.printf "%d, ") path;
List.iter (Printf.printf "%d, ") path;
print_newline ()</lang>
print_newline ()</syntaxhighlight>


=={{header|PARI/GP}}==
=={{header|PARI/GP}}==
Basic, inefficient implementation. Takes an n×n matrix representing distance between nodes (a 0-1 matrix if you just want to count number of steps) and a number in 1..n representing the starting node, which defaults to 1 if not given.
Basic, inefficient implementation. Takes an n×n matrix representing distance between nodes (a 0-1 matrix if you just want to count number of steps) and a number in 1..n representing the starting node, which defaults to 1 if not given.
<lang parigp>shortestPath(G, startAt=1)={
<syntaxhighlight lang="parigp">shortestPath(G, startAt=1)={
my(n=#G[,1],dist=vector(n,i,9e99),prev=dist,Q=2^n-1);
my(n=#G[,1],dist=vector(n,i,9e99),prev=dist,Q=2^n-1);
dist[startAt]=0;
dist[startAt]=0;
Line 4,288: Line 4,288:
);
);
dist
dist
};</lang>
};</syntaxhighlight>


=={{header|Pascal}}==
=={{header|Pascal}}==
Classic algorithm like this has to have a Pascal implementation...
Classic algorithm like this has to have a Pascal implementation...


<lang pascal>program dijkstra(output);
<syntaxhighlight lang="pascal">program dijkstra(output);


type
type
Line 4,454: Line 4,454:
vtx := vtx^.next;
vtx := vtx^.next;
end
end
end.</lang>
end.</syntaxhighlight>


{{Out}}
{{Out}}
Line 4,475: Line 4,475:


Almost every online description of the algorithm introduces the concept of infinite path length. There is no mention of this in Dijkstra's paper, and it doesn't seem to be necessary.
Almost every online description of the algorithm introduces the concept of infinite path length. There is no mention of this in Dijkstra's paper, and it doesn't seem to be necessary.
<lang pascal>
<syntaxhighlight lang="pascal">
program Dijkstra_console;
program Dijkstra_console;
// Demo of Dijkstra's algorithm.
// Demo of Dijkstra's algorithm.
Line 4,583: Line 4,583:
end;
end;
end.
end.
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 4,595: Line 4,595:


=={{header|Perl}}==
=={{header|Perl}}==
<lang perl>use strict;
<syntaxhighlight lang="perl">use strict;
use warnings;
use warnings;
use constant True => 1;
use constant True => 1;
Line 4,657: Line 4,657:
}
}
my $path = join '', reverse @a;
my $path = join '', reverse @a;
print "$g->{e}{dist} $path\n";</lang>
print "$g->{e}{dist} $path\n";</syntaxhighlight>
{{out}}
{{out}}
<pre>26 acde</pre>
<pre>26 acde</pre>
Line 4,665: Line 4,665:
Selects the shortest path from A to B only. As for time complexity, it looks plenty efficient enough to me, though it clearly is O(V^2).<br>
Selects the shortest path from A to B only. As for time complexity, it looks plenty efficient enough to me, though it clearly is O(V^2).<br>
Written after the task was changed to be a directed graph, and shows the correct solution for that.
Written after the task was changed to be a directed graph, and shows the correct solution for that.
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #000080;font-style:italic;">--requires("1.0.2") -- (builtin E renamed as EULER)
<span style="color: #000080;font-style:italic;">--requires("1.0.2") -- (builtin E renamed as EULER)
Line 4,751: Line 4,751:
<span style="color: #000000;">test</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">A</span><span style="color: #0000FF;">,</span><span style="color: #000000;">E</span><span style="color: #0000FF;">,</span><span style="color: #000000;">26</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"ACDE"</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">A</span><span style="color: #0000FF;">,</span><span style="color: #000000;">F</span><span style="color: #0000FF;">,</span><span style="color: #000000;">11</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"ACF"</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">F</span><span style="color: #0000FF;">,</span><span style="color: #000000;">A</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"none"</span><span style="color: #0000FF;">}})</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">A</span><span style="color: #0000FF;">,</span><span style="color: #000000;">E</span><span style="color: #0000FF;">,</span><span style="color: #000000;">26</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"ACDE"</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">A</span><span style="color: #0000FF;">,</span><span style="color: #000000;">F</span><span style="color: #0000FF;">,</span><span style="color: #000000;">11</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"ACF"</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">F</span><span style="color: #0000FF;">,</span><span style="color: #000000;">A</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"none"</span><span style="color: #0000FF;">}})</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
{{out}}
{{out}}
<pre>
<pre>
Line 4,761: Line 4,761:
=={{header|PHP}}==
=={{header|PHP}}==
There are parts of this algorithm that could be optimized which have been marked TODO.
There are parts of this algorithm that could be optimized which have been marked TODO.
<syntaxhighlight lang="php">
<lang PHP>
<?php
<?php
function dijkstra($graph_array, $source, $target) {
function dijkstra($graph_array, $source, $target) {
Line 4,831: Line 4,831:


echo "path is: ".implode(", ", $path)."\n";
echo "path is: ".implode(", ", $path)."\n";
</syntaxhighlight>
</lang>
Output is:
Output is:
<pre>path is: a, c, f, e</pre>
<pre>path is: a, c, f, e</pre>
Line 4,837: Line 4,837:
=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
Following the Wikipedia algorithm:
Following the Wikipedia algorithm:
<lang PicoLisp>(de neighbor (X Y Cost)
<syntaxhighlight lang="picolisp">(de neighbor (X Y Cost)
(push (prop X 'neighbors) (cons Y Cost))
(push (prop X 'neighbors) (cons Y Cost))
(push (prop Y 'neighbors) (cons X Cost)) )
(push (prop Y 'neighbors) (cons X Cost)) )
Line 4,854: Line 4,854:
(del (asoq Curr (: neighbors)) (:: neighbors)) ) )
(del (asoq Curr (: neighbors)) (:: neighbors)) ) )
(setq Curr Next Cost Min) ) )
(setq Curr Next Cost Min) ) )
Cost ) )</lang>
Cost ) )</syntaxhighlight>
Test:
Test:
<lang PicoLisp>(neighbor 'a 'b 7)
<syntaxhighlight lang="picolisp">(neighbor 'a 'b 7)
(neighbor 'a 'c 9)
(neighbor 'a 'c 9)
(neighbor 'a 'f 14)
(neighbor 'a 'f 14)
Line 4,866: Line 4,866:
(neighbor 'e 'f 9)
(neighbor 'e 'f 9)


(dijkstra 'a 'e)</lang>
(dijkstra 'a 'e)</syntaxhighlight>
Output:
Output:
<pre>-> 20</pre>
<pre>-> 20</pre>
Line 4,915: Line 4,915:




<lang prolog>%___________________________________________________________________________
<syntaxhighlight lang="prolog">%___________________________________________________________________________


:-dynamic
:-dynamic
Line 4,961: Line 4,961:
[Path, Dist, Distance]);
[Path, Dist, Distance]);
writef('There is no route from %w to %w\n', [From, To]).
writef('There is no route from %w to %w\n', [From, To]).
</syntaxhighlight>
</lang>
for example:
for example:
<pre>?- go(a,e).
<pre>?- go(a,e).
Line 4,984: Line 4,984:


Note: q could be changed to be a priority queue instead of a set as mentioned [http://docs.python.org/3.3/library/heapq.html#priority-queue-implementation-notes here].
Note: q could be changed to be a priority queue instead of a set as mentioned [http://docs.python.org/3.3/library/heapq.html#priority-queue-implementation-notes here].
<lang python>from collections import namedtuple, deque
<syntaxhighlight lang="python">from collections import namedtuple, deque
from pprint import pprint as pp
from pprint import pprint as pp
Line 5,033: Line 5,033:
("b", "d", 15), ("c", "d", 11), ("c", "f", 2), ("d", "e", 6),
("b", "d", 15), ("c", "d", 11), ("c", "f", 2), ("d", "e", 6),
("e", "f", 9)])
("e", "f", 9)])
pp(graph.dijkstra("a", "e"))</lang>
pp(graph.dijkstra("a", "e"))</syntaxhighlight>


{{out}}
{{out}}
Line 5,039: Line 5,039:


=={{header|Racket}}==
=={{header|Racket}}==
<lang racket>
<syntaxhighlight lang="racket">
#lang racket
#lang racket
(require (planet jaymccarthy/dijkstra:1:2))
(require (planet jaymccarthy/dijkstra:1:2))
Line 5,062: Line 5,062:
(cond [(eq? (first path) 'a) path]
(cond [(eq? (first path) 'a) path]
[(loop (cons (hash-ref prevs (first path)) path))]))))])
[(loop (cons (hash-ref prevs (first path)) path))]))))])
</syntaxhighlight>
</lang>
Output:
Output:
<lang racket>
<syntaxhighlight lang="racket">
Distances from a: ((b 7) (d 20) (a 0) (c 9) (f 11) (e 26))
Distances from a: ((b 7) (d 20) (a 0) (c 9) (f 11) (e 26))
Shortest path: (a c d e)
Shortest path: (a c d e)
</syntaxhighlight>
</lang>


=={{header|Raku}}==
=={{header|Raku}}==
(formerly Perl 6)
(formerly Perl 6)
{{Works with|Rakudo|2018.03}}
{{Works with|Rakudo|2018.03}}
<lang perl6>class Graph {
<syntaxhighlight lang="raku" line>class Graph {
has (%.edges, %.nodes);
has (%.edges, %.nodes);


Line 5,151: Line 5,151:
["d", "e", 6],
["d", "e", 6],
["e", "f", 9]
["e", "f", 9]
]).dijkstra('a', 'e').say;</lang>
]).dijkstra('a', 'e').say;</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 5,162: Line 5,162:
:::* &nbsp; a test for a &nbsp; ''no path found'' &nbsp; condition
:::* &nbsp; a test for a &nbsp; ''no path found'' &nbsp; condition
:::* &nbsp; use of memoization
:::* &nbsp; use of memoization
<lang rexx>/*REXX program determines the least costly path between two vertices given a list. */
<syntaxhighlight lang="rexx">/*REXX program determines the least costly path between two vertices given a list. */
$.= copies(9, digits() ) /*edge cost: indicates doesn't exist. */
$.= copies(9, digits() ) /*edge cost: indicates doesn't exist. */
xList= '!. @. $. beg fin bestP best$ xx yy' /*common EXPOSEd variables for subs. */
xList= '!. @. $. beg fin bestP best$ xx yy' /*common EXPOSEd variables for subs. */
Line 5,217: Line 5,217:
@.?= !.qq; call .path ?+1 /*recursive call for next path. */
@.?= !.qq; call .path ?+1 /*recursive call for next path. */
end /*qq*/
end /*qq*/
return</lang>
return</syntaxhighlight>
{{out|output|text=&nbsp; when using the internal default inputs:}}
{{out|output|text=&nbsp; when using the internal default inputs:}}
<pre>
<pre>
Line 5,237: Line 5,237:


=={{header|Ring}}==
=={{header|Ring}}==
<lang ring>
<syntaxhighlight lang="ring">
# Project : Dijkstra's algorithm
# Project : Dijkstra's algorithm


Line 5,315: Line 5,315:
dgraph[p] = s
dgraph[p] = s
next
next
</syntaxhighlight>
</lang>
Output:
Output:
<pre>
<pre>
Line 5,327: Line 5,327:
Notes for this solution:
Notes for this solution:
* At every iteration, the next minimum distance node found by linear traversal of all nodes, which is inefficient.
* At every iteration, the next minimum distance node found by linear traversal of all nodes, which is inefficient.
<lang ruby>class Graph
<syntaxhighlight lang="ruby">class Graph
Vertex = Struct.new(:name, :neighbours, :dist, :prev)
Vertex = Struct.new(:name, :neighbours, :dist, :prev)
Line 5,397: Line 5,397:
path, dist = g.shortest_path(start, stop)
path, dist = g.shortest_path(start, stop)
puts "shortest path from #{start} to #{stop} has cost #{dist}:"
puts "shortest path from #{start} to #{stop} has cost #{dist}:"
puts path.join(" -> ")</lang>
puts path.join(" -> ")</syntaxhighlight>


{{out}}
{{out}}
Line 5,406: Line 5,406:
This solution uses a very bare-bones, naive implementation of an adjacency list to represent the graph.
This solution uses a very bare-bones, naive implementation of an adjacency list to represent the graph.


<lang rust>use std::cmp::Ordering;
<syntaxhighlight lang="rust">use std::cmp::Ordering;
use std::collections::BinaryHeap;
use std::collections::BinaryHeap;
use std::usize;
use std::usize;
Line 5,524: Line 5,524:
println!("\nCost: {}", cost);
println!("\nCost: {}", cost);


}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 5,533: Line 5,533:
=={{header|SAS}}==
=={{header|SAS}}==
Use network solver in SAS/OR:
Use network solver in SAS/OR:
<lang sas>/* create SAS data set */
<syntaxhighlight lang="sas">/* create SAS data set */
data Edges;
data Edges;
input Start $ End $ Cost;
input Start $ End $ Cost;
Line 5,570: Line 5,570:
/* print shortest path */
/* print shortest path */
proc print data=path;
proc print data=path;
run;</lang>
run;</syntaxhighlight>


Output:
Output:
Line 5,583: Line 5,583:
A functional implementation of Dijkstras Algorithm:
A functional implementation of Dijkstras Algorithm:


<lang scala>object Dijkstra {
<syntaxhighlight lang="scala">object Dijkstra {
type Path[Key] = (Double, List[Key])
type Path[Key] = (Double, List[Key])
Line 5,611: Line 5,611:
println(res)
println(res)
}
}
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 5,619: Line 5,619:


An implementation based on the functional version above that uses <code>PriorityQueue</code>. It is made functional-look:
An implementation based on the functional version above that uses <code>PriorityQueue</code>. It is made functional-look:
<lang scala>
<syntaxhighlight lang="scala">
import scala.collection.mutable
import scala.collection.mutable


Line 5,677: Line 5,677:
}
}
}
}
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>(26.0,List(a, c, d, e))</pre>
<pre>(26.0,List(a, c, d, e))</pre>
Line 5,683: Line 5,683:
=={{header|Sidef}}==
=={{header|Sidef}}==
{{trans|Perl}}
{{trans|Perl}}
<lang ruby>class Graph(*args) {
<syntaxhighlight lang="ruby">class Graph(*args) {


struct Node {
struct Node {
Line 5,773: Line 5,773:


var path = a.reverse.join
var path = a.reverse.join
say "#{g.get('e').dist} #{path}"</lang>
say "#{g.get('e').dist} #{path}"</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 5,785: Line 5,785:
{{trans|Rust}}
{{trans|Rust}}


<lang swift>typealias WeightedEdge = (Int, Int, Int)
<syntaxhighlight lang="swift">typealias WeightedEdge = (Int, Int, Int)


struct Grid<T> {
struct Grid<T> {
Line 5,873: Line 5,873:


print("Cost: \(cost)")
print("Cost: \(cost)")
print(path.map({ grid.nodes[$0].data }).joined(separator: " -> "))</lang>
print(path.map({ grid.nodes[$0].data }).joined(separator: " -> "))</syntaxhighlight>


{{out}}
{{out}}
Line 5,882: Line 5,882:
=={{header|Tailspin}}==
=={{header|Tailspin}}==
A simple algorithm that traverses through all edges at every step.
A simple algorithm that traverses through all edges at every step.
<lang tailspin>
<syntaxhighlight lang="tailspin">
data vertex <'a'..'f'>, to <vertex>
data vertex <'a'..'f'>, to <vertex>


Line 5,916: Line 5,916:
$fromA... -> \(<{to:<=vertex´'f'>}> $!\) -> 'Shortest path from $.path(1); to $.to; is distance $.distance; via $.path(2..last);
$fromA... -> \(<{to:<=vertex´'f'>}> $!\) -> 'Shortest path from $.path(1); to $.to; is distance $.distance; via $.path(2..last);
' -> !OUT::write
' -> !OUT::write
</syntaxhighlight>
</lang>


Alternatively you can use relational algebra operators for the exact same algorithm
Alternatively you can use relational algebra operators for the exact same algorithm
<lang tailspin>
<syntaxhighlight lang="tailspin">
data cost <"1">, distance <"1">
data cost <"1">, distance <"1">
data vertex <'[a-f]'>, to <vertex>, from <vertex>, path <[<vertex>* VOID]>
data vertex <'[a-f]'>, to <vertex>, from <vertex>, path <[<vertex>* VOID]>
Line 5,956: Line 5,956:
($fromA matching {|{to:'f'}|})... -> 'Shortest path from $.path(1); to $.to; is distance $.distance; via $.path(2..last);
($fromA matching {|{to:'f'}|})... -> 'Shortest path from $.path(1); to $.to; is distance $.distance; via $.path(2..last);
' -> !OUT::write
' -> !OUT::write
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 5,972: Line 5,972:


Note that this code traverses the entire set of unrouted nodes at each step, as this is simpler than computing the subset that are reachable at each stage.
Note that this code traverses the entire set of unrouted nodes at each step, as this is simpler than computing the subset that are reachable at each stage.
<lang tcl>proc dijkstra {graph origin} {
<syntaxhighlight lang="tcl">proc dijkstra {graph origin} {
# Initialize
# Initialize
dict for {vertex distmap} $graph {
dict for {vertex distmap} $graph {
Line 6,009: Line 6,009:
}
}
return [list $dist $path]
return [list $dist $path]
}</lang>
}</syntaxhighlight>
Showing the code in use:
Showing the code in use:
<lang tcl>proc makeUndirectedGraph arcs {
<syntaxhighlight lang="tcl">proc makeUndirectedGraph arcs {
# Assume that all nodes are connected to something
# Assume that all nodes are connected to something
foreach arc $arcs {
foreach arc $arcs {
Line 6,026: Line 6,026:
lassign [dijkstra [makeUndirectedGraph $arcs] "a"] costs path
lassign [dijkstra [makeUndirectedGraph $arcs] "a"] costs path
puts "path from a to e costs [dict get $costs e]"
puts "path from a to e costs [dict get $costs e]"
puts "route from a to e is: [join [dict get $path e] { -> }]"</lang>
puts "route from a to e is: [join [dict get $path e] { -> }]"</syntaxhighlight>
Output:
Output:
<pre>
<pre>
Line 6,034: Line 6,034:


=={{header|VBA}}==
=={{header|VBA}}==
<lang VB>Class Branch
<syntaxhighlight lang="vb">Class Branch
Public from As Node '[according to Dijkstra the first Node should be closest to P]
Public from As Node '[according to Dijkstra the first Node should be closest to P]
Public towards As Node
Public towards As Node
Line 6,208: Line 6,208:
Dijkstra testNodes, testBranches, a
Dijkstra testNodes, testBranches, a
GetPath f
GetPath f
End Sub</lang>{{out}}<pre>From To Distance Path
End Sub</syntaxhighlight>{{out}}<pre>From To Distance Path
a e 26 a c d e
a e 26 a c d e
a f 11 a c f</pre>
a f 11 a c f</pre>
Line 6,218: Line 6,218:
{{libheader|Wren-sort}}
{{libheader|Wren-sort}}
{{libheader|Wren-set}}
{{libheader|Wren-set}}
<lang ecmascript>import "/dynamic" for Tuple
<syntaxhighlight lang="ecmascript">import "/dynamic" for Tuple
import "/trait" for Comparable
import "/trait" for Comparable
import "/sort" for Cmp, Sort
import "/sort" for Cmp, Sort
Line 6,369: Line 6,369:
g = Graph.new(GRAPH, false, false) // undirected
g = Graph.new(GRAPH, false, false) // undirected
g.dijkstra(START)
g.dijkstra(START)
g.printPath(END)</lang>
g.printPath(END)</syntaxhighlight>


{{out}}
{{out}}
Line 6,379: Line 6,379:


=={{header|zkl}}==
=={{header|zkl}}==
<lang zkl>const INF=(0).MAX;
<syntaxhighlight lang="zkl">const INF=(0).MAX;
fcn dijkstra(graph,start,dst){
fcn dijkstra(graph,start,dst){
Q :=graph.copy();
Q :=graph.copy();
Line 6,400: Line 6,400:
}
}
}
}
}</lang>
}</syntaxhighlight>
<lang zkl>graph:=Dictionary( // directed graph
<syntaxhighlight lang="zkl">graph:=Dictionary( // directed graph
"a", T(T("b", 7.0), T("c", 9.0), T("f",14.0)),
"a", T(T("b", 7.0), T("c", 9.0), T("f",14.0)),
"b", T(T("c",10.0), T("d",15.0)),
"b", T(T("c",10.0), T("d",15.0)),
Line 6,410: Line 6,410:
);
);
dijkstra(graph,"a","e").println();
dijkstra(graph,"a","e").println();
dijkstra(graph,"e","a").println();</lang>
dijkstra(graph,"e","a").println();</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>