Rebol3 Code Examplex
Dijkstra's algorithm
Find the shortest paths from one starting point to all reachable nodes in a weighted graph with nonnegative edge costs.
Rebol [
title: "Rosetta code: Dijkstra's algorithm"
file: %Dijkstra's_algorithm.r3
url: https://rosettacode.org/wiki/Dijkstra's_algorithm
]
make-graph: function [
"Build adjacency map from an edge list of [src dst cost] blocks."
edges [block!]
][
neighbours: make map! []
foreach [src dst cost] edges [
unless neighbours/:src [neighbours/:src: make block! 4]
repend neighbours/:src [dst cost]
]
neighbours
]
dijkstra: function [
"Find lowest-cost path between first and last in graph."
graph [map!]
first [any-type!]
last [any-type!]
][
;; collect all vertices from the adjacency map
vertices: make block! 16
foreach [src neighbours] graph [
append vertices src
foreach [dst cost] neighbours [append vertices dst]
]
vertices: unique vertices
;; initialise distances to infinity, zero for start vertex
dist: make map! []
previous: make map! []
not-seen: copy vertices
foreach v vertices [dist/:v: 1.#inf]
dist/:first: 0
while [not empty? not-seen] [
;; pick unvisited vertex with smallest tentative distance
vertex1: none
mindist: 1.#inf
foreach v not-seen [
if dist/:v < mindist [vertex1: v mindist: dist/:v]
]
if any [none? vertex1 vertex1 = last] [break]
remove find not-seen vertex1
;; relax edges to neighbours
foreach [vertex2 cost] any [graph/:vertex1 []] [
if find not-seen vertex2 [
altdist: dist/:vertex1 + cost
if altdist < dist/:vertex2 [
;; vertex1 is best predecessor of vertex2
dist/:vertex2: altdist
previous/:vertex2: vertex1
]
]
]
]
;; reconstruct path by walking predecessors back from last to first
path: make block! 8
vertex: last
while [vertex] [
append path vertex
vertex: previous/:vertex
]
reverse path
]
print-path: function [
"Print a path as: first → ... → last"
path [block!]
][
buf: to string! path/1
foreach vertex next path [append append buf " → " vertex]
print [
"Shortest path from" path/1 "to" last path ":"
buf
]
]
graph: make-graph [
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
]
?? graph
print-path dijkstra graph 'a 'e
print-path dijkstra graph 'a 'f
Output:
graph: #(map! [
a: [b 7 c 9 f 14]
b: [c 10 d 15]
c: [d 11 f 2]
d: [e 6]
e: [f 9]
])
Shortest path from a to e : a -> c -> d -> e
Shortest path from a to f : a -> c -> f