Import Upstream version 20180207
[hcoop/debian/mlton.git] / lib / mlton / directed-graph / dijkstra.fun
CommitLineData
7f918cf1
CE
1(* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
2 * Jagannathan, and Stephen Weeks.
3 *
4 * MLton is released under a BSD-style license.
5 * See the file MLton-LICENSE for details.
6 *)
7
8functor Dijkstra (S : SHORTEST_PATH_STRUCTS): SHORTEST_PATH =
9struct
10
11open S
12
13structure Heap = FibonacciHeap (structure Key = Weight)
14structure Elt = Heap.Elt
15
16fun shortestPath {graph, weight, source} =
17 let
18 val {get: Node.t -> Node.t Heap.Elt.t option, set, destroy} =
19 Property.destGetSetOnce (Node.plist, Property.initConst NONE)
20 val elt = valOf o get
21 fun distanceOption n = Option.map (get n, Elt.key)
22 val distance = valOf o distanceOption
23 val fringe: Node.t Heap.t = Heap.empty ()
24 fun addToFringe (n: Node.t, d: Weight.t): unit =
25 set (n, SOME (Heap.insert (fringe, d, n)))
26 fun relax (n: Node.t, e: Edge.t): unit =
27 let val n' = Edge.to e
28 val d = Weight.+ (distance n, weight e)
29 in case distanceOption n' of
30 NONE => addToFringe (n', d)
31 | SOME d' => if Weight.< (d, d')
32 then Heap.decreaseKey (fringe, elt n', d)
33 else ()
34 end
35 in addToFringe (source, Weight.zero)
36 ; while not (Heap.isEmpty fringe)
37 do let val n = Heap.deleteMin fringe
38 in List.foreach (Node.successors n, fn e => relax (n, e))
39 end
40 ; distanceOption
41 end
42
43end