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
210
211
212
213
214
215
module Generic(G : Sig.IM with type V.label = int and type E.label = int) =
struct
include G
exception Found of V.t
let find_vertex g i =
try
iter_vertex (fun v -> if V.label v = i then raise (Found v)) g;
raise Not_found
with Found v ->
v
module Builder = Builder.I(G)
module Dfs = Traverse.Dfs(G)
module Bfs = Traverse.Bfs(G)
module Marking = Traverse.Mark(G)
module Coloring = Coloring.Mark(G)
module Classic = Classic.I(G)
module Rand = Rand.I(G)
module Components = Components.Make(G)
module W = struct
type edge = G.E.t
type t = int
let weight e = G.E.label e
let zero = 0
let add = (+)
let sub = (-)
let compare : t -> t -> int = Stdlib.compare
end
include Path.Dijkstra(G)(W)
include Path.Johnson(G)(W)
module BF = Path.BellmanFord(G)(W)
let bellman_ford = BF.find_negative_cycle_from
module Bfs01 = Path.Bfs01(G)
let bfs_0_1 = Bfs01.iter
module F = struct
type label = int
type t = int
let max_capacity x = x
let min_capacity _ = 0
let flow _ = 0
let add = (+)
let sub = (-)
let compare : t -> t -> int = Stdlib.compare
let zero = 0
end
module FF = Flow.Ford_Fulkerson(G)(F)
let ford_fulkerson g =
if not G.is_directed then
invalid_arg "ford_fulkerson: not a directed graph";
FF.maxflow g
module Goldberg = Flow.Goldberg_Tarjan(G)(F)
let goldberg_tarjan g =
if not G.is_directed then invalid_arg "goldberg: not a directed graph";
Goldberg.maxflow g
include Oper.Make(Builder)
module PathCheck = Path.Check(G)
module Topological = struct
include Topological.Make(G)
module S = Topological.Make_stable(G)
let fold_stable = S.fold
let iter_stable = S.iter
end
module Eulerian = struct
include Eulerian.Make(G)
end
module Int = struct
type t = int
let compare : t -> t -> int = Stdlib.compare
end
include Kruskal.Make(G)(Int)
module Display = struct
include G
let vertex_name v = string_of_int (V.label v)
let graph_attributes _ = []
let default_vertex_attributes _ = []
let vertex_attributes _ = []
let default_edge_attributes _ = []
let edge_attributes e = [ `Label (string_of_int (E.label e) ) ]
let get_subgraph _ = None
end
module Dot_ = Graphviz.Dot(Display)
module Neato = Graphviz.Neato(Display)
let dot_output g f =
let oc = open_out f in
if is_directed then Dot_.output_graph oc g else Neato.output_graph oc g;
close_out oc
let display_with_gv g =
let tmp = Filename.temp_file "graph" ".dot" in
dot_output g tmp;
ignore (Sys.command ("dot -Tps " ^ tmp ^ " | gv -"));
Sys.remove tmp
module GmlParser =
Gml.Parse
(Builder)
(struct
let node l =
try match List.assoc "id" l with Gml.Int n -> n | _ -> -1
with Not_found -> -1
let edge _ =
0
end)
let parse_gml_file = GmlParser.parse
module DotParser =
Dot.Parse
(Builder)
(struct
let nodes = Hashtbl.create 97
let new_node = ref 0
let node (id,_) _ =
try
Hashtbl.find nodes id
with Not_found ->
incr new_node;
Hashtbl.add nodes id !new_node;
!new_node
let edge _ =
0
end)
let parse_dot_file = DotParser.parse
open Format
module GmlPrinter =
Gml.Print
(G)
(struct
let node n = ["label", Gml.Int n]
let edge n = ["label", Gml.Int n]
end)
let print_gml = GmlPrinter.print
let print_gml_file g f =
let c = open_out f in
let fmt = formatter_of_out_channel c in
fprintf fmt "%a@." GmlPrinter.print g;
close_out c
end
module I = struct
type t = int
let compare : t -> t -> int = Stdlib.compare
let default = 0
end
module Digraph = Generic(Imperative.Digraph.AbstractLabeled(I)(I))
module Graph = Generic(Imperative.Graph.AbstractLabeled(I)(I))