Dijkstra's algorithm: Difference between revisions

Content added Content deleted
No edit summary
No edit summary
Line 1,474: Line 1,474:
return 0;
return 0;
}</lang>
}</lang>

=={{header|CafeOBJ}}==
<lang CafeOBJ>
"
Save this file as DijkstraRosetta.cafe.
To run the file type
CafeOBJ> in DijkstraRosetta.cafe
at the CafeOBJ command prompt.

CafeOBJ is primarily a first order specification language which can also be used as a functional programming language.
Being first order, we make no use higher order functions such as map.


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

Input
A directed positively weighted graph. The graph is represented as a list of 4tuples containing directed edges of the form (beginning, end, edgeDist,pathDist)
The tuple (start, start,0,0) means there is zero distance from start to start.

Ouput
1) a list of 4-tuples with each tuple represents a node N, its source, length of the conecting edge to N, and the shortest distance from the some starting node to N .
2) a list of nodes on the shortest path from a chosen start to some cosen end node.

Note needs a bit more work to exacly match the specified Rosetta Dijkstra task.
"

-- some system settings
-- Most important is memoization (memo) which stores the value of a function instead of recomputing it each time the function is called.
full reset
set step off
set print fancy
set stats on
set verbose off
set quiet on
set memo on

-- A module defining a simple parameterized list.
mod! LIST(T :: TRIV) principal-sort List {
[Elt < List ]
op nil : -> List
op (_:_) : List List -> List {memo assoc id: nil}
op reverse_ : List -> List
op head_ : List -> Elt
var e : Elt
var l : List
eq reverse nil = nil .
eq reverse (e : l) = (reverse l) : e .
eq head e : l = e .
}


-- Main module
mod! DIJKSTRA {
-- A four tuple used to store graph and shortest distance
-- start, end, edgeDist,pathDist
pr(LIST(4TUPLE(INT,INT,INT,INT)))
-- A list of integers used to store final shortest path.
pr(LIST(INT) *{sort List -> PathList})
[List < PathList]
op dijkstra___ : Int List List -> List
op exploreNeighbours___ : Int List List -> 4Tuple {memo}
ops inf finished : -> Int
op currDist__ : Int List -> Int
op relax__ : List List -> List
op connectedTo__ : Int List -> Bool
op nextNode2Explore_ : List -> 4Tuple
op connectedList___ : List Int List -> List
op unvisitedList__ : List List -> List
op shortestPath__ : Int List -> PathList
op SP___ : 4Tuple 4Tuple List -> PathList
op shortestDist__ : Int List -> Int
op SD____ : Int Int List List -> Int

vars x y z n eD pD eD1 pD1 eD2 pD2 source currentVertex startVertex : Int
vars graph permanent xs : List
vars t t1 t2 : 4Tuple

eq inf = 500 .
eq finished = -1 .

-- Main dijkstra function
eq dijkstra startVertex graph permanent =
if (exploreNeighbours startVertex permanent graph) == << finished ; finished ; finished ; finished >> then permanent
else (dijkstra startVertex graph ( ((exploreNeighbours startVertex permanent graph) : permanent))) fi .
eq exploreNeighbours startVertex permanent graph = (nextNode2Explore
(relax (unvisitedList (connectedList graph startVertex permanent) permanent) permanent )) .

-- nextNode2Explore takes a list of records and returns a record with the minimum 4th element else finished
eq nextNode2Explore nil = << finished ; finished ; finished ; finished >> .
eq nextNode2Explore (t1 : nil) = t1 .
eq nextNode2Explore (t2 : (t1 : xs)) = if (4* t1) < (4* t2) then t1 else nextNode2Explore (t2 : xs) fi .

-- relaxes all edges leaving y
eq relax nil permanent = nil .
eq relax (<< x ; y ; eD ; pD >> : xs) permanent = if (currDist x permanent) < pD then << y ; x ; eD ; ((currDist x permanent) + eD) >> : (relax xs permanent) else << y ; x ; eD ; pD >> : (relax xs permanent) fi .

-- Get the current best distance for a particulare vertex n.
eq currDist n nil = inf .
eq currDist n (t : permanent) = if ((1* t) == n) then (4* t ) else (currDist n permanent) fi .


eq connectedTo z nil = false .
eq connectedTo z ((<< x ; y ; eD ; pD >>) : xs) = if (x == z) then true else (connectedTo z xs) fi .


eq connectedList nil source permanent = nil .
eq connectedList (t : graph) source permanent = if (connectedTo source permanent) then
(t : (connectedList graph source permanent))
else (connectedList graph source permanent) fi .


eq unvisitedList nil permanent = nil .
eq unvisitedList (t : graph) permanent = if not(connectedTo (2* t) permanent) then (t : (unvisitedList graph permanent)) else (unvisitedList graph permanent) fi .


-- To get the shortest path we used the above dijkstra function.
-- From a given start to a given end we need to trace the path from the finish to the start and then reverse the output.
var pList : PathList
var currentTuple : 4Tuple
vars start end : Int
eq SP start end nil = nil .
eq SP start end (currentTuple : pList) = if (end == (1* currentTuple)) then ( end : (SP start (2* currentTuple) pList)) else (SP start end pList) fi .


-- The graph to be traversed
op DirectedRosetta : -> List
eq DirectedRosetta = ( << 1 ; 2 ; 7 ; inf >> :
<< 1 ; 3 ; 9 ; inf >> :
<< 1 ; 6 ; 14 ; inf >> :
<< 2 ; 3 ; 10 ; inf >> :
<< 2 ; 4 ; 15 ; inf >> :
<< 3 ; 4 ; 11 ; inf >> :
<< 3 ; 6 ; 2 ; inf >> :
<< 4 ; 5 ; 6 ; inf >> :
<< 5 ; 6 ; 9 ; inf >>) .

-- A set of possible strating points
ops oneStart twoStart threeStart fourStart fiveStart sixStart : -> List
eq oneStart = << 1 ; 1 ; 0 ; 0 >> .
eq twoStart = << 2 ; 2 ; 0 ; 0 >> .
eq threeStart = << 3 ; 3 ; 0 ; 0 >> .
eq fourStart = << 4 ; 4 ; 0 ; 0 >> .
eq fiveStart = << 5 ; 5 ; 0 ; 0 >> .
eq sixStart = << 6 ; 6 ; 0 ; 0 >> .

} -- End module

-- We must open the module in the CafeOBJ interpreter
open DIJKSTRA .
--> All shortest distances starting from a(1)
red dijkstra 1 DirectedRosetta oneStart .
-- Gives
-- ((((<< 5 ; 4 ; 6 ; 26 >>) : (<< 4 ; 3 ; 11 ; 20 >>)) : ((<< 6 ; 3 ; 2 ; 11 >>) : (<< 3 ; 1 ; 9 ; 9 >>))) : ((<< 2 ; 1 ; 7 ; 7 >>) : (<< 1 ; 1 ; 0 ; 0 >>))):List

--> Shortest path from a(1) to e(5)
red reverse (SP 1 5 (dijkstra 1 DirectedRosetta oneStart)) .
-- Gives
-- ((1 : 3) : (4 : 5)):PathList

--> Shortest path from a(1) to f(6)
red reverse (SP 1 6 (dijkstra 1 DirectedRosetta oneStart)) .
-- Gives
-- ((1 : 3) : 6):PathList
eof
</lang>


=={{header|Clojure}}==
=={{header|Clojure}}==