Dijkstra's algorithm: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) 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 ] </ |
a──►b ] </syntaxhighlight> |
||
Line 144: | Line 144: | ||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<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’))</ |
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. |
||
< |
<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;</ |
end Dijkstra;</syntaxhighlight> |
||
< |
<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;</ |
end Dijkstra;</syntaxhighlight> |
||
The testing main procedure : |
The testing main procedure : |
||
< |
<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;</ |
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'''< |
'''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</ |
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 # |
||
)</ |
)</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}}== |
||
< |
<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</ |
690 DATA</syntaxhighlight> |
||
'''Output:''' |
'''Output:''' |
||
<pre>SHORTEST PATH |
<pre>SHORTEST PATH |
||
Line 674: | Line 674: | ||
{{trans|Nim}} |
{{trans|Nim}} |
||
< |
<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"]</ |
print ["Shortest path from 'a' to 'f': " join.with:" -> " dijkstraPath graph "a" "f"]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 753: | Line 753: | ||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
< |
<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 |
||
}</ |
}</syntaxhighlight> |
||
Examples:< |
Examples:<syntaxhighlight lang="autohotkey">data = |
||
( |
( |
||
A B 7 |
A B 7 |
||
Line 856: | Line 856: | ||
GuiClose: |
GuiClose: |
||
ExitApp |
ExitApp |
||
return</ |
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}} |
||
< |
<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: | ||
} |
} |
||
}</ |
}</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). |
||
< |
<syntaxhighlight lang="cpp">#include <iostream> |
||
#include <vector> |
#include <vector> |
||
#include <string> |
#include <string> |
||
Line 1,332: | Line 1,332: | ||
return 0; |
return 0; |
||
}</ |
}</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. |
||
< |
<syntaxhighlight lang="cpp">#include <iostream> |
||
#include <vector> |
#include <vector> |
||
#include <string> |
#include <string> |
||
Line 1,473: | Line 1,473: | ||
return 0; |
return 0; |
||
}</ |
}</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}}== |
||
< |
<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.) |
||
< |
<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</ |
720 DATA 0</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
Line 1,955: | Line 1,955: | ||
=={{header|Common Lisp}}== |
=={{header|Common 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> |
||
< |
<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). |
||
< |
<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)); |
||
}</ |
}</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. |
||
< |
<syntaxhighlight lang="delphi">program Rosetta_Dijkstra_Console; |
||
{$APPTYPE CONSOLE} |
{$APPTYPE CONSOLE} |
||
Line 2,230: | Line 2,230: | ||
WriteLn( lineOut); |
WriteLn( lineOut); |
||
end; |
end; |
||
end.</ |
end.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,243: | Line 2,243: | ||
=={{header|Emacs Lisp}}== |
=={{header|Emacs 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}}== |
||
< |
<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=== |
||
< |
<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=== |
||
< |
<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}}== |
||
< |
<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)) |
||
}</ |
}</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. |
||
< |
<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</ |
putStrLn $ "Path: " ++ show path</syntaxhighlight> |
||
=={{header|Huginn}}== |
=={{header|Huginn}}== |
||
< |
<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" ) ) ); |
||
}</ |
}</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. |
||
< |
<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</ |
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 === |
||
< |
<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 |
||
)</ |
)</syntaxhighlight> |
||
Example use: |
Example use: |
||
< |
<syntaxhighlight lang="j"> (;:'a e') vertices shortest_path edges |
||
┌─────────┐ |
┌─────────┐ |
||
│┌─┬─┬─┬─┐│ |
│┌─┬─┬─┬─┐│ |
||
││a│c│d│e││ |
││a│c│d│e││ |
||
│└─┴─┴─┴─┘│ |
│└─┴─┴─┴─┘│ |
||
└─────────┘</ |
└─────────┘</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. |
||
< |
<syntaxhighlight lang="java"> |
||
import java.io.*; |
import java.io.*; |
||
import java.util.*; |
import java.util.*; |
||
Line 3,292: | Line 3,292: | ||
} |
} |
||
} |
} |
||
}</ |
}</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]] |
||
< |
<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''' |
||
< |
<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''' |
||
< |
<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])</ |
(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}} |
||
< |
<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</ |
end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,615: | Line 3,615: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
{{trans|Java}} |
{{trans|Java}} |
||
< |
<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) |
||
} |
} |
||
}</ |
}</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... |
||
< |
<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))</ |
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}}== |
||
< |
<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]]</ |
# [[[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}}== |
||
< |
<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"}</ |
-> {"a", "c", "d", "e"}</syntaxhighlight> |
||
[[File:Mma_dijkstra2.PNG]] |
[[File:Mma_dijkstra2.PNG]] |
||
=={{header|Maxima}}== |
=={{header|Maxima}}== |
||
< |
<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]] */</ |
/* [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: |
||
< |
<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)</ |
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. |
||
< |
<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 ()</ |
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. |
||
< |
<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 |
||
};</ |
};</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... |
||
< |
<syntaxhighlight lang="pascal">program dijkstra(output); |
||
type |
type |
||
Line 4,454: | Line 4,454: | ||
vtx := vtx^.next; |
vtx := vtx^.next; |
||
end |
end |
||
end.</ |
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. |
||
< |
<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}}== |
||
< |
<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";</ |
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. |
||
<!--< |
<!--<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> |
||
<!--</ |
<!--</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: |
||
< |
<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 ) )</ |
Cost ) )</syntaxhighlight> |
||
Test: |
Test: |
||
< |
<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)</ |
(dijkstra 'a 'e)</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>-> 20</pre> |
<pre>-> 20</pre> |
||
Line 4,915: | Line 4,915: | ||
< |
<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]. |
||
< |
<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"))</ |
pp(graph.dijkstra("a", "e"))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 5,039: | Line 5,039: | ||
=={{header|Racket}}== |
=={{header|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: |
||
< |
<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 |
<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;</ |
]).dijkstra('a', 'e').say;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 5,162: | Line 5,162: | ||
:::* a test for a ''no path found'' condition |
:::* a test for a ''no path found'' condition |
||
:::* use of memoization |
:::* use of memoization |
||
< |
<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</ |
return</syntaxhighlight> |
||
{{out|output|text= when using the internal default inputs:}} |
{{out|output|text= when using the internal default inputs:}} |
||
<pre> |
<pre> |
||
Line 5,237: | Line 5,237: | ||
=={{header|Ring}}== |
=={{header|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. |
||
< |
<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(" -> ")</ |
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. |
||
< |
<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); |
||
}</ |
}</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: |
||
< |
<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;</ |
run;</syntaxhighlight> |
||
Output: |
Output: |
||
Line 5,583: | Line 5,583: | ||
A functional implementation of Dijkstras Algorithm: |
A functional implementation of Dijkstras Algorithm: |
||
< |
<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) |
||
} |
} |
||
}</ |
}</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: |
||
< |
<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}} |
||
< |
<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}"</ |
say "#{g.get('e').dist} #{path}"</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 5,785: | Line 5,785: | ||
{{trans|Rust}} |
{{trans|Rust}} |
||
< |
<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: " -> "))</ |
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. |
||
< |
<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 |
||
< |
<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. |
||
< |
<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] |
||
}</ |
}</syntaxhighlight> |
||
Showing the code in use: |
Showing the code in use: |
||
< |
<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] { -> }]"</ |
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}}== |
||
< |
<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</ |
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}} |
||
< |
<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)</ |
g.printPath(END)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 6,379: | Line 6,379: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
< |
<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: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
< |
<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();</ |
dijkstra(graph,"e","a").println();</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |