From 35d79f34b71a2a4fa41d0671db555743502ab8c9 Mon Sep 17 00:00:00 2001 From: Simon Fowler Date: Fri, 21 Jul 2017 17:10:43 +0100 Subject: [PATCH 1/2] tinker --- src/path.ml | 14 ++++++++++++++ src/path.mli | 5 +++++ 2 files changed, 19 insertions(+) diff --git a/src/path.ml b/src/path.ml index fb5e0cdb..e519446c 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,16 @@ struct H.add dist v1 W.zero; loop () + let all_shortest_paths g i = + let paths = Hashtbl.create 8192 in + G.iter_vertex + (fun j -> + let _, length = shortest_path g i j in + Hashtbl.add paths j length) + g; + paths + + 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..66754858 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 -> (G.V.t, W.t) Hashtbl.t + + end (* The following module is a contribution of Yuto Takei (University of Tokyo) *) From 4423e097f87c45d6e44676727c4e32e96740542f Mon Sep 17 00:00:00 2001 From: Simon Fowler Date: Fri, 21 Jul 2017 18:36:21 +0100 Subject: [PATCH 2/2] all_shortest_paths via dijkstra --- src/path.ml | 44 ++++++++++++++++++++++++++++++++++++-------- src/path.mli | 2 +- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/path.ml b/src/path.ml index e519446c..053d01d2 100644 --- a/src/path.ml +++ b/src/path.ml @@ -102,16 +102,44 @@ struct H.add dist v1 W.zero; loop () - let all_shortest_paths g i = - let paths = Hashtbl.create 8192 in - G.iter_vertex - (fun j -> - let _, length = shortest_path g i j in - Hashtbl.add paths j length) - g; - paths + 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 66754858..5123b5fd 100644 --- a/src/path.mli +++ b/src/path.mli @@ -55,7 +55,7 @@ sig Complexity: at most O((V+E)log(V)) *) - val all_shortest_paths : G.t -> G.V.t -> (G.V.t, W.t) Hashtbl.t + val all_shortest_paths : G.t -> G.V.t -> W.t H.t end