package ocamlgraph
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
A generic graph library for OCaml
Install
dune-project
Dependency
Authors
Maintainers
Sources
ocamlgraph-2.2.0.tbz
sha256=b0956210863cc24f480203ba3c2ef06dfae5579536a05744364e7de58822b230
sha512=257cdd5fb90337b3e3682cade1269c1d181f3124e569a731909f49bbfbe581ab529ac401472fb9ef57166ac34d8ebadfa6a32c93665f38f5a335982d5e5dc0e1
doc/src/ocamlgraph/components.ml.html
Source file components.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209(**************************************************************************) (* *) (* Ocamlgraph: a generic graph library for OCaml *) (* Copyright (C) 2004-2010 *) (* Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles *) (* *) (* This software is free software; you can redistribute it and/or *) (* modify it under the terms of the GNU Library General Public *) (* License version 2.1, with the special exception on linking *) (* described in file LICENSE. *) (* *) (* This software is distributed in the hope that it will be useful, *) (* but WITHOUT ANY WARRANTY; without even the implied warranty of *) (* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *) (* *) (**************************************************************************) module type G = sig type t module V : Sig.COMPARABLE val iter_vertex : (V.t -> unit) -> t -> unit val iter_succ : (V.t -> unit) -> t -> V.t -> unit end module Make(G: G) = struct module H = Hashtbl.Make(G.V) (* iterative code using a stack (variable [cont] below) *) type action = | Finish of G.V.t * int | Visit of G.V.t * G.V.t | Test of G.V.t * G.V.t let scc g = let root = H.create 997 in let hashcomp = H.create 997 in let stack = ref [] in let numdfs = ref 0 in let numcomp = ref 0 in let rec pop x = function | ((y: int), w) :: l when y > x -> H.add hashcomp w !numcomp; pop x l | l -> l in let cont = ref [] in let visit v = if not (H.mem root v) then begin let n = incr numdfs; !numdfs in H.add root v n; cont := Finish (v, n) :: !cont; G.iter_succ (fun w -> cont := Visit (v, w) :: Test (v, w) :: !cont) g v; end in let rec finish () = match !cont with | [] -> () | action :: tail -> cont := tail; begin match action with | Finish (v, n) -> if H.find root v = n then begin H.add hashcomp v !numcomp; let s = pop n !stack in stack:= s; incr numcomp end else stack := (n, v) :: !stack; | Visit (_, w) -> visit w | Test (v, w) -> if not (H.mem hashcomp w) then H.replace root v (min (H.find root v) (H.find root w)) end; finish () in let visit_and_finish v = visit v; finish () in G.iter_vertex visit_and_finish g; !numcomp, (fun v -> H.find hashcomp v) let scc_array g = let n,f = scc g in let t = Array.make n [] in G.iter_vertex (fun v -> let i = f v in t.(i) <- v :: t.(i)) g; t let scc_list g = let a = scc_array g in Array.fold_right (fun l acc -> l :: acc) a [] end (** Connectivity in strongly connected directed graphs *) module Connectivity (GB: Builder.S) = struct module MOper = Oper.Make(GB) module Choose = Oper.Choose(GB.G) module Dom = Dominator.Make(GB.G) module S = Dom.S let sstrong_articulation_points g = let s = Choose.choose_vertex g in let module SCC = Make (struct include GB.G let iter_vertex f = GB.G.iter_vertex (fun v -> if not (V.equal s v) then f v) let iter_succ f = GB.G.iter_succ (fun v -> if not (V.equal s v) then f v) end) in let s_is_sap = fst (SCC.scc g) > 1 in let dt_s = Dom.(idom_to_dom_tree g (compute_idom g s)) in let d_s = Dom.dom_tree_to_snontrivial_dom s dt_s in let g_r = MOper.mirror g in let dtr_s = Dom.(idom_to_dom_tree g_r (compute_idom g_r s)) in let dr_s = Dom.dom_tree_to_snontrivial_dom s dtr_s in let d = Dom.S.union d_s dr_s in if s_is_sap then Dom.S.add s d else d let strong_articulation_points g = S.elements (sstrong_articulation_points g) end module BiConnectivity (G: Sig.G) = struct module Choose = Oper.Choose(G) module Dom = Dominator.Make(G) module RDom = Dominator.Make( struct type t = G.t module V = G.V let pred = G.succ let succ = G.pred let fold_vertex = G.fold_vertex let iter_vertex = G.iter_vertex let iter_succ = G.iter_pred let nb_vertex = G.nb_vertex end) module S = Dom.S let sstrong_articulation_points g = let s = Choose.choose_vertex g in let module SCC = Make (struct include G let iter_vertex f = G.iter_vertex (fun v -> if not (V.equal s v) then f v) let iter_succ f = G.iter_succ (fun v -> if not (V.equal s v) then f v) end) in let s_is_sap = fst (SCC.scc g) > 1 in let dt_s = Dom.(idom_to_dom_tree g (compute_idom g s)) in let d_s = Dom.dom_tree_to_snontrivial_dom s dt_s in let dtr_s = RDom.(idom_to_dom_tree g (compute_idom g s)) in let dr_s = Dom.dom_tree_to_snontrivial_dom s dtr_s in let d = Dom.S.union d_s dr_s in if s_is_sap then Dom.S.add s d else d let strong_articulation_points g = S.elements (sstrong_articulation_points g) end (** Connected components (for undirected graphs) *) module type U = sig type t module V : Sig.COMPARABLE val iter_vertex : (V.t -> unit) -> t -> unit val iter_edges : (V.t -> V.t -> unit) -> t -> unit end module Undirected(G: U) = struct module UF = Unionfind.Make(G.V) module H = Hashtbl.Make(G.V) let components g = let vertices = ref [] in G.iter_vertex (fun v -> vertices := v :: !vertices) g; let uf = UF.init !vertices in let visit u v = UF.union u v uf in G.iter_edges visit g; let count = ref 0 in let comp = H.create 5003 in let visit v = let v = UF.find v uf in if not (H.mem comp v) then begin H.add comp v !count; incr count end in G.iter_vertex visit g; !count, (fun v -> H.find comp (UF.find v uf)) let components_array g = let n,f = components g in let t = Array.make n [] in G.iter_vertex (fun v -> let i = f v in t.(i) <- v :: t.(i)) g; t let components_list g = let a = components_array g in Array.fold_right (fun l acc -> l :: acc) a [] end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>