diff --git a/src/path.ml b/src/path.ml index fb5e0cdb..053d01d2 100644 --- a/src/path.ml +++ b/src/path.ml @@ -64,9 +64,13 @@ struct module PQ = Heap.Imperative(Elt) + (* Gets the shortest path between v1 and v2 in graph g *) let shortest_path g v1 v2 = + (* Create a hashtable (which is essentially a set...) of visited nodes *) let visited = H.create 97 in + (* Create a hashtable of distances from each of the nodes *) let dist = H.create 97 in + (* Create a priority queue *) let q = PQ.create 17 in let rec loop () = if PQ.is_empty q then raise Not_found; @@ -98,6 +102,44 @@ struct H.add dist v1 W.zero; loop () + + + let all_shortest_paths g v1 = + (* Create a hashtable (which is essentially a set...) of visited nodes *) + let visited = H.create 97 in + (* Create a hashtable of distances from each of the nodes *) + let dist = H.create 97 in + (* Create a priority queue *) + let q = PQ.create 17 in + let rec loop () = + if PQ.is_empty q then + dist + else + let (w,v,p) = PQ.pop_maximum q in + begin + if not (H.mem visited v) then begin + H.add visited v (); + G.iter_succ_e + (fun e -> + let ev = dst e in + if not (H.mem visited ev) then begin + let dev = W.add w (W.weight e) in + let improvement = + try W.compare dev (H.find dist ev) < 0 with Not_found -> true + in + if improvement then begin + H.replace dist ev dev; + PQ.add q (dev, ev, e :: p) + end + end) + g v + end; + loop () + end + in + PQ.add q (W.zero, v1, []); + H.add dist v1 W.zero; + loop () end (* The following module is a contribution of Yuto Takei (University of Tokyo) *) diff --git a/src/path.mli b/src/path.mli index 5b1e74ac..5123b5fd 100644 --- a/src/path.mli +++ b/src/path.mli @@ -45,6 +45,8 @@ module Dijkstra (W: Sig.WEIGHT with type edge = G.E.t) : sig + module H : Hashtbl.S with type key = G.V.t + val shortest_path : G.t -> G.V.t -> G.V.t -> G.E.t list * W.t (** [shortest_path g v1 v2] computes the shortest path from vertex [v1] to vertex [v2] in graph [g]. The path is returned as the list of @@ -53,6 +55,9 @@ sig Complexity: at most O((V+E)log(V)) *) + val all_shortest_paths : G.t -> G.V.t -> W.t H.t + + end (* The following module is a contribution of Yuto Takei (University of Tokyo) *)