Dijkstra's algorithm: Difference between revisions

m
(→‎{{header|Forth}}: Add implementation)
(4 intermediate revisions by 2 users not shown)
Line 3,302:
5: distance = 11, 0 --> 2 --> 5
</pre>
 
=={{header|EasyLang}}==
<syntaxhighlight>
global con[][] n .
proc read . .
repeat
s$ = input
until s$ = ""
a = (strcode substr s$ 1 1) - 96
b = (strcode substr s$ 3 1) - 96
d = number substr s$ 5 9
if a > len con[][]
len con[][] a
.
con[a][] &= b
con[a][] &= d
.
con[][] &= [ ]
n = len con[][]
.
read
#
len cost[] n
len prev[] n
#
proc dijkstra . .
for i = 2 to len cost[]
cost[i] = 1 / 0
.
len todo[] n
todo[1] = 1
repeat
min = 1 / 0
a = 0
for i to len todo[]
if todo[i] = 1 and cost[i] < min
min = cost[i]
a = i
.
.
until a = 0
todo[a] = 0
for i = 1 step 2 to len con[a][] - 1
b = con[a][i]
c = con[a][i + 1]
if cost[a] + c < cost[b]
cost[b] = cost[a] + c
prev[b] = a
todo[b] = 1
.
.
.
.
dijkstra
#
func$ gpath nd$ .
nd = strcode nd$ - 96
while nd <> 1
s$ = " -> " & strchar (nd + 96) & s$
nd = prev[nd]
.
return "a" & s$
.
print gpath "e"
print gpath "f"
#
input_data
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
 
</syntaxhighlight>
 
=={{header|Emacs Lisp}}==
Line 3,485 ⟶ 3,563:
=={{header|Forth}}==
{{trans|Commodore BASIC}}
<syntaxhighlight lang="FORTH">\ utility routine to increment a variable
 
\ utility word: increment a variable
: 1+! 1 swap +! ;
 
\ enter the edge data
variable edge-count
0 edge-count !
Line 3,497 ⟶ 3,573:
'a , 'c , 9 , edge-count 1+!
'a , 'f , 14 , edge-count 1+!
'b , 'c , 10 , edge-count 1+!
'b , 'd , 15 , edge-count 1+!
'c , 'd , 11 , edge-count 1+!
Line 3,503 ⟶ 3,580:
'e , 'f , 9 , edge-count 1+!
 
\ definewith accessors for it
: edge 3 * cells edges + ;
: edge-from edge ;
Line 3,509 ⟶ 3,586:
: edge-weight edge 2 cells + ;
 
\ vertex data and acccessor
\ create a a place to store the vertex names
create vertex-names edge-count @ 2 * cells allot
 
\ and an accessor
: vertex-name cells vertex-names + ;
 
\ and a count
variable vertex-count
0 vertex-count !
Line 3,528 ⟶ 3,602:
;
 
\ routine to add a new vertex name if itnot doesn't exist yetfound
: add-vertex
dup find-vertex dup -1 = if
Line 3,540 ⟶ 3,614:
;
 
\ routine to populateadd vertexvertices to name listtable and changereplace edgenames endpointswith fromindices names toin numbersedges
: get-vertices
edge-count @ 0 ?do
Line 3,548 ⟶ 3,622:
;
 
\ call it to finish initializing our data set
get-vertices
 
\ arraysvariables to storehold state during algorithm run
 
\ true if vertex has been visited
create been-visited
vertex-count @ cells allot
: visited cells been-visited + ;
 
\ index of the previous vertex along shortest path found so far
create prior-vertices
vertex-count @ cells allot
: prior-vertex cells prior-vertices + ;
 
\ shortest distance found so far
create distances
vertex-count @ cells allot
: distance cells distances + ;
 
\ miscellaneous variables
variable origin
variable current-vertex
Line 3,578 ⟶ 3,647:
variable vertex
 
\ begincall algorithm.with expectsorigin vertex name of starting vertex on stack
: dijkstra ( origin -- )
 
Line 3,631 ⟶ 3,700:
." Shortest path to each vertex from " origin @ vertex-name @ emit ': emit cr
vertex-count @ 0 ?do
i origin @ <> if
i vertex-name @ emit ." : " i distance @ . '( emitdup
i-1 vertex= !if
begin drop
vertex." @ vertex-name @ emit(unreachable)"
vertex @ origin @ <> whileelse
." ←"
'( vertex @ prior-vertex @ vertex !emit
repeat i vertex !
') emit cr begin
vertex @ vertex-name @ emit
vertex @ origin @ <> while
." ←"
vertex @ prior-vertex @ vertex !
repeat
') emit
then
cr
then
loop
Line 3,652 ⟶ 3,729:
d: 20 (d←c←a)
e: 26 (e←d←c←a)
ok
'b dijkstra
Shortest path to each vertex from b:
a: ∞ (unreachable)
c: 10 (c←b)
f: 12 (f←c←b)
d: 15 (d←b)
e: 21 (e←d←b)
ok</pre>
 
2,023

edits