mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 11:15:31 -05:00
add CCGraph.spanning_tree with a lazy tree
This commit is contained in:
parent
d8a0bbc748
commit
eed339463d
2 changed files with 56 additions and 0 deletions
|
|
@ -341,6 +341,44 @@ let topo_sort ?eq ?rev ?(tbl=mk_table 128) ~graph seq =
|
||||||
[ 42, 21; 14, 2; 3, 1; 21, 7; 42, 3]
|
[ 42, 21; 14, 2; 3, 1; 21, 7; 42, 3]
|
||||||
*)
|
*)
|
||||||
|
|
||||||
|
(** {2 Lazy Spanning Tree} *)
|
||||||
|
|
||||||
|
module LazyTree = struct
|
||||||
|
type ('v, 'e) t =
|
||||||
|
| Vertex of 'v * ('e * ('v, 'e) t) list Lazy.t
|
||||||
|
|
||||||
|
let rec map_v f (Vertex (v, l)) =
|
||||||
|
let l' = lazy (List.map (fun (e, child) -> e, map_v f child) (Lazy.force l)) in
|
||||||
|
Vertex (f v, l')
|
||||||
|
|
||||||
|
let rec fold_v f acc t = match t with
|
||||||
|
| Vertex (v, l) ->
|
||||||
|
let acc = f acc v in
|
||||||
|
List.fold_left
|
||||||
|
(fun acc (_, t') -> fold_v f acc t')
|
||||||
|
acc
|
||||||
|
(Lazy.force l)
|
||||||
|
end
|
||||||
|
|
||||||
|
let spanning_tree ?(tbl=mk_table 128) ~graph v =
|
||||||
|
let rec mk_node v =
|
||||||
|
let children = lazy (
|
||||||
|
Seq.fold
|
||||||
|
(fun acc e ->
|
||||||
|
let v' = graph.dest e in
|
||||||
|
if tbl.mem v'
|
||||||
|
then acc
|
||||||
|
else (
|
||||||
|
tbl.add v' ();
|
||||||
|
(e, mk_node v') :: acc
|
||||||
|
)
|
||||||
|
) [] (graph.children v)
|
||||||
|
)
|
||||||
|
in
|
||||||
|
LazyTree.Vertex (v, children)
|
||||||
|
in
|
||||||
|
mk_node v
|
||||||
|
|
||||||
(** {2 Strongly Connected Components} *)
|
(** {2 Strongly Connected Components} *)
|
||||||
|
|
||||||
module SCC = struct
|
module SCC = struct
|
||||||
|
|
|
||||||
|
|
@ -217,6 +217,24 @@ val topo_sort_tag : ?eq:('v -> 'v -> bool) ->
|
||||||
'v list
|
'v list
|
||||||
(** Same as {!topo_sort} *)
|
(** Same as {!topo_sort} *)
|
||||||
|
|
||||||
|
(** {2 Lazy Spanning Tree} *)
|
||||||
|
|
||||||
|
module LazyTree : sig
|
||||||
|
type ('v, 'e) t =
|
||||||
|
| Vertex of 'v * ('e * ('v, 'e) t) list Lazy.t
|
||||||
|
|
||||||
|
val map_v : ('a -> 'b) -> ('a, 'e) t -> ('b, 'e) t
|
||||||
|
|
||||||
|
val fold_v : ('acc -> 'v -> 'acc) -> 'acc -> ('v, _) t -> 'acc
|
||||||
|
end
|
||||||
|
|
||||||
|
val spanning_tree : ?tbl:'v set ->
|
||||||
|
graph:('v, 'e) t ->
|
||||||
|
'v ->
|
||||||
|
('v, 'e) LazyTree.t
|
||||||
|
(** [spanning_tree ~graph v] computes a lazy spanning tree that has [v]
|
||||||
|
as a root. The table [tbl] is used for the memoization part *)
|
||||||
|
|
||||||
(** {2 Strongly Connected Components} *)
|
(** {2 Strongly Connected Components} *)
|
||||||
|
|
||||||
type 'v scc_state
|
type 'v scc_state
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue