Browse Source

add circulation problem resolution

Arnaud Vergnet 3 years ago
parent
commit
236600e387
8 changed files with 215 additions and 129 deletions
  1. 4
    1
      .gitignore
  2. 20
    9
      Makefile
  3. 27
    0
      circulation_input_graphs/test1
  4. 15
    0
      graphs/test2
  5. 0
    119
      outfile.svg
  6. 100
    0
      src/circulationfile.ml
  7. 11
    0
      src/circulationfile.mli
  8. 38
    0
      src/circulationtest.ml

+ 4
- 1
.gitignore View File

@@ -1,4 +1,7 @@
1 1
 _build/
2 2
 ftest.native
3
+circulationtest.native
3 4
 outfile
4
-*~
5
+*~
6
+test/
7
+run/

+ 20
- 9
Makefile View File

@@ -20,33 +20,44 @@ edit:
20 20
 
21 21
 demo: build
22 22
 	@echo $(EXECUTING)
23
-	./ftest.native graphs/graph1 1 2 outfile
23
+	./ftest.native graphs/graph1 1 2 test/outfile
24 24
 	@echo $(RESULT)
25
-	@cat outfile
25
+	@cat test/outfile
26 26
 
27 27
 test: build
28 28
 	@echo $(EXECUTING)
29
-	./ftest.native graphs/graph1 1 2 outfile
29
+	./ftest.native graphs/graph1 1 2 test/outfile
30 30
 	@echo $(BUILDING_SVG)
31 31
 	@echo "outfile..."
32
-	@dot -Tsvg outfile > outfile.svg
32
+	@dot -Tsvg test/outfile > test/outfile.svg
33 33
 	@echo "graph_init..."
34
-	@dot -Tsvg graph_init > graph_init.svg
34
+	@dot -Tsvg test/graph_init > test/graph_init.svg
35 35
 	@echo "graph_apply..."
36
-	@dot -Tsvg graph_apply > graph_apply.svg
36
+	@dot -Tsvg test/graph_apply > test/graph_apply.svg
37 37
 	@echo "graph_res..."
38
-	@dot -Tsvg graph_res > graph_res.svg
38
+	@dot -Tsvg test/graph_res > test/graph_res.svg
39 39
 	@echo ""
40 40
 
41 41
 run: build
42 42
 	@echo $(EXECUTING)
43
-	./ftest.native graphs/test1 0 3 solution
43
+	./ftest.native graphs/test2 0 5 run/solution
44 44
 	@echo $(BUILDING_SVG)
45 45
 	@echo "solution..."
46
-	@dot -Tsvg solution > solution.svg
46
+	@dot -Tsvg run/solution > run/solution.svg
47 47
 	@echo ""
48 48
 
49 49
 
50 50
 clean:
51 51
 	-rm -rf _build/
52 52
 	-rm ftest.native
53
+
54
+build_circulation: 
55
+	@echo $(COMPILING)
56
+	ocamlbuild circulationtest.native
57
+
58
+run_circulation: build_circulation
59
+	@echo $(EXECUTING)
60
+	./circulationtest.native circulation_input_graphs/test1 run/circulation_solution
61
+	@echo $(BUILDING_SVG)
62
+	@echo "solution..."
63
+	@dot -Tsvg run/circulation_solution > run/circulation_solution.svg

+ 27
- 0
circulation_input_graphs/test1 View File

@@ -0,0 +1,27 @@
1
+% Factories
2
+% factory id production_rate 
3
+factory 0 6
4
+factory 1 6
5
+
6
+% Villages
7
+% village id demand
8
+village 5 10
9
+village 6 10
10
+village 7 10
11
+
12
+% n id
13
+node 2
14
+node 3
15
+node 4
16
+
17
+road 0 1 2
18
+road 0 2 4
19
+road 0 3 4
20
+road 1 2 3
21
+road 1 4 3
22
+road 2 3 5
23
+road 4 3 3
24
+road 4 5 1
25
+road 4 6 5
26
+road 2 6 4
27
+road 2 7 1

+ 15
- 0
graphs/test2 View File

@@ -0,0 +1,15 @@
1
+% Graph saved at Fri Nov 20 2020 14:11:39 GMT+0100 (Central European Standard Time)
2
+n 130 200
3
+n 225 300
4
+n 325 300
5
+n 175 100
6
+n 275 100
7
+n 370 200
8
+e 0 1 15
9
+e 1 2 12
10
+e 2 5 7
11
+e 0 3 4
12
+e 3 4 10
13
+e 4 5 10
14
+e 2 3 3
15
+e 4 1 5

+ 0
- 119
outfile.svg View File

@@ -1,119 +0,0 @@
1
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
3
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4
-<!-- Generated by graphviz version 2.43.0 (0)
5
- -->
6
-<!-- Title: finite_state_machine Pages: 1 -->
7
-<svg width="388pt" height="155pt"
8
- viewBox="0.00 0.00 388.00 155.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
9
-<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 151)">
10
-<title>finite_state_machine</title>
11
-<polygon fill="white" stroke="transparent" points="-4,4 -4,-151 384,-151 384,4 -4,4"/>
12
-<!-- 0 -->
13
-<g id="node1" class="node">
14
-<title>0</title>
15
-<ellipse fill="none" stroke="black" cx="18" cy="-72" rx="18" ry="18"/>
16
-<text text-anchor="middle" x="18" y="-68.3" font-family="Times,serif" font-size="14.00">0</text>
17
-</g>
18
-<!-- 1 -->
19
-<g id="node2" class="node">
20
-<title>1</title>
21
-<ellipse fill="none" stroke="black" cx="190" cy="-129" rx="18" ry="18"/>
22
-<text text-anchor="middle" x="190" y="-125.3" font-family="Times,serif" font-size="14.00">1</text>
23
-</g>
24
-<!-- 0&#45;&gt;1 -->
25
-<g id="edge3" class="edge">
26
-<title>0&#45;&gt;1</title>
27
-<path fill="none" stroke="black" d="M34.06,-80.87C40.15,-84.27 47.3,-88.04 54,-91 91.02,-107.38 100.76,-111.03 140,-121 147.07,-122.8 154.83,-124.28 162.04,-125.46"/>
28
-<polygon fill="black" stroke="black" points="161.66,-128.94 172.07,-126.97 162.7,-122.02 161.66,-128.94"/>
29
-<text text-anchor="middle" x="104" y="-119.8" font-family="Times,serif" font-size="14.00">7</text>
30
-</g>
31
-<!-- 2 -->
32
-<g id="node3" class="node">
33
-<title>2</title>
34
-<ellipse fill="none" stroke="black" cx="190" cy="-18" rx="18" ry="18"/>
35
-<text text-anchor="middle" x="190" y="-14.3" font-family="Times,serif" font-size="14.00">2</text>
36
-</g>
37
-<!-- 0&#45;&gt;2 -->
38
-<g id="edge1" class="edge">
39
-<title>0&#45;&gt;2</title>
40
-<path fill="none" stroke="black" d="M32.43,-61.03C45.34,-51.14 65.8,-37.1 86,-30 110.59,-21.36 140.3,-18.65 161.49,-17.93"/>
41
-<polygon fill="black" stroke="black" points="161.79,-21.43 171.71,-17.72 161.64,-14.43 161.79,-21.43"/>
42
-<text text-anchor="middle" x="104" y="-33.8" font-family="Times,serif" font-size="14.00">8</text>
43
-</g>
44
-<!-- 3 -->
45
-<g id="node4" class="node">
46
-<title>3</title>
47
-<ellipse fill="none" stroke="black" cx="104" cy="-72" rx="18" ry="18"/>
48
-<text text-anchor="middle" x="104" y="-68.3" font-family="Times,serif" font-size="14.00">3</text>
49
-</g>
50
-<!-- 0&#45;&gt;3 -->
51
-<g id="edge2" class="edge">
52
-<title>0&#45;&gt;3</title>
53
-<path fill="none" stroke="black" d="M36.4,-72C47.74,-72 62.77,-72 75.68,-72"/>
54
-<polygon fill="black" stroke="black" points="75.9,-75.5 85.9,-72 75.9,-68.5 75.9,-75.5"/>
55
-<text text-anchor="middle" x="61" y="-75.8" font-family="Times,serif" font-size="14.00">10</text>
56
-</g>
57
-<!-- 4 -->
58
-<g id="node5" class="node">
59
-<title>4</title>
60
-<ellipse fill="none" stroke="black" cx="276" cy="-77" rx="18" ry="18"/>
61
-<text text-anchor="middle" x="276" y="-73.3" font-family="Times,serif" font-size="14.00">4</text>
62
-</g>
63
-<!-- 1&#45;&gt;4 -->
64
-<g id="edge8" class="edge">
65
-<title>1&#45;&gt;4</title>
66
-<path fill="none" stroke="black" d="M205.55,-119.22C211.8,-115.08 219.21,-110.23 226,-106 234.08,-100.96 243.01,-95.61 251.02,-90.89"/>
67
-<polygon fill="black" stroke="black" points="253.02,-93.78 259.88,-85.7 249.48,-87.73 253.02,-93.78"/>
68
-<text text-anchor="middle" x="233" y="-109.8" font-family="Times,serif" font-size="14.00">1</text>
69
-</g>
70
-<!-- 5 -->
71
-<g id="node6" class="node">
72
-<title>5</title>
73
-<ellipse fill="none" stroke="black" cx="362" cy="-108" rx="18" ry="18"/>
74
-<text text-anchor="middle" x="362" y="-104.3" font-family="Times,serif" font-size="14.00">5</text>
75
-</g>
76
-<!-- 1&#45;&gt;5 -->
77
-<g id="edge9" class="edge">
78
-<title>1&#45;&gt;5</title>
79
-<path fill="none" stroke="black" d="M208.07,-127.11C233.69,-124.24 283.64,-118.53 326,-113 328.56,-112.67 331.22,-112.31 333.88,-111.94"/>
80
-<polygon fill="black" stroke="black" points="334.51,-115.39 343.92,-110.52 333.53,-108.45 334.51,-115.39"/>
81
-<text text-anchor="middle" x="276" y="-124.8" font-family="Times,serif" font-size="14.00">21</text>
82
-</g>
83
-<!-- 2&#45;&gt;4 -->
84
-<g id="edge4" class="edge">
85
-<title>2&#45;&gt;4</title>
86
-<path fill="none" stroke="black" d="M207.14,-24.75C217.04,-29.24 229.75,-35.66 240,-43 245.51,-46.95 251,-51.75 255.94,-56.49"/>
87
-<polygon fill="black" stroke="black" points="253.64,-59.14 263.18,-63.75 258.6,-54.2 253.64,-59.14"/>
88
-<text text-anchor="middle" x="233" y="-46.8" font-family="Times,serif" font-size="14.00">12</text>
89
-</g>
90
-<!-- 3&#45;&gt;1 -->
91
-<g id="edge7" class="edge">
92
-<title>3&#45;&gt;1</title>
93
-<path fill="none" stroke="black" d="M119.25,-81.67C132.04,-90.35 151.05,-103.25 165.99,-113.39"/>
94
-<polygon fill="black" stroke="black" points="164.44,-116.56 174.68,-119.28 168.37,-110.77 164.44,-116.56"/>
95
-<text text-anchor="middle" x="147" y="-106.8" font-family="Times,serif" font-size="14.00">11</text>
96
-</g>
97
-<!-- 3&#45;&gt;2 -->
98
-<g id="edge6" class="edge">
99
-<title>3&#45;&gt;2</title>
100
-<path fill="none" stroke="black" d="M117.76,-60.27C124.18,-54.68 132.22,-48.12 140,-43 147.49,-38.07 156.07,-33.4 163.94,-29.46"/>
101
-<polygon fill="black" stroke="black" points="165.59,-32.55 173.06,-25.04 162.54,-26.25 165.59,-32.55"/>
102
-<text text-anchor="middle" x="147" y="-46.8" font-family="Times,serif" font-size="14.00">2</text>
103
-</g>
104
-<!-- 3&#45;&gt;4 -->
105
-<g id="edge5" class="edge">
106
-<title>3&#45;&gt;4</title>
107
-<path fill="none" stroke="black" d="M122.24,-72.51C151.84,-73.38 212.57,-75.16 247.89,-76.2"/>
108
-<polygon fill="black" stroke="black" points="247.87,-79.7 257.97,-76.5 248.08,-72.71 247.87,-79.7"/>
109
-<text text-anchor="middle" x="190" y="-77.8" font-family="Times,serif" font-size="14.00">5</text>
110
-</g>
111
-<!-- 4&#45;&gt;5 -->
112
-<g id="edge10" class="edge">
113
-<title>4&#45;&gt;5</title>
114
-<path fill="none" stroke="black" d="M293.2,-82.98C305.17,-87.39 321.7,-93.5 335.44,-98.57"/>
115
-<polygon fill="black" stroke="black" points="334.26,-101.86 344.85,-102.04 336.68,-95.3 334.26,-101.86"/>
116
-<text text-anchor="middle" x="319" y="-97.8" font-family="Times,serif" font-size="14.00">14</text>
117
-</g>
118
-</g>
119
-</svg>

+ 100
- 0
src/circulationfile.ml View File

@@ -0,0 +1,100 @@
1
+open Graph
2
+open Printf
3
+open Ffalgo
4
+
5
+type path = string
6
+
7
+(* Format of text files:
8
+   % This is a comment
9
+
10
+   % A node with its coordinates (which are not used).
11
+   n 88.8 209.7
12
+   n 408.9 183.0
13
+
14
+   % The first node has id 0, the next is 1, and so on.
15
+
16
+   % Edges: e source dest label
17
+   e 3 1 11
18
+   e 0 2 8
19
+
20
+*)
21
+
22
+let source = (-1)
23
+let destination = (-2)
24
+
25
+let read_factory graph line =
26
+  try Scanf.sscanf line "factory %d %d" (fun id capacity -> new_arc (new_node graph id) source id capacity)
27
+  with e ->
28
+    Printf.printf "Cannot read factory in line - %s:\n%s\n%!" (Printexc.to_string e) line ;
29
+    failwith "from_file"
30
+
31
+let read_village graph line =
32
+  try Scanf.sscanf line "village %d %d" (fun id capacity -> new_arc (new_node graph id) id destination capacity)
33
+  with e ->
34
+    Printf.printf "Cannot read village in line - %s:\n%s\n%!" (Printexc.to_string e) line ;
35
+    failwith "from_file"
36
+
37
+(* Reads a line with a node. *)
38
+let read_node graph line =
39
+  try Scanf.sscanf line "node %d" (fun id -> new_node graph id)
40
+  with e ->
41
+    Printf.printf "Cannot read node in line - %s:\n%s\n%!" (Printexc.to_string e) line ;
42
+    failwith "from_file"
43
+
44
+(* Ensure that the given node exists in the graph. If not, create it. 
45
+ * (Necessary because the website we use to create online graphs does not generate correct files when some nodes have been deleted.) *)
46
+let ensure graph id = if node_exists graph id then graph else new_node graph id
47
+
48
+(* Reads a line with an arc. *)
49
+let read_road graph line =
50
+  try Scanf.sscanf line "road %d %d %d"
51
+        (fun id1 id2 capacity -> new_arc (ensure (ensure graph id1) id2) id1 id2 capacity)
52
+  with e ->
53
+    Printf.printf "Cannot read arc in line - %s:\n%s\n%!" (Printexc.to_string e) line ;
54
+    failwith "from_file"
55
+
56
+(* Reads a comment or fail. *)
57
+let read_comment graph line =
58
+  try Scanf.sscanf line " %%" graph
59
+  with _ ->
60
+    Printf.printf "Unknown line:\n%s\n%!" line ;
61
+    failwith "from_file"
62
+
63
+let circulation_from_file path =
64
+
65
+  let infile = open_in path in
66
+  (* create source and destination *)
67
+  let initial_graph = new_node (new_node empty_graph source) destination in
68
+  (* Read all lines until end of file. 
69
+   * n is the current node counter. *)
70
+  let rec loop graph =
71
+    try
72
+      let line = input_line infile in
73
+
74
+      (* Remove leading and trailing spaces. *)
75
+      let line = String.trim line in
76
+
77
+      let graph2 =
78
+        (* Ignore empty lines *)
79
+        if line = "" then graph
80
+
81
+        (* The first character of a line determines its content : n or e. *)
82
+        else match line.[0] with
83
+          | 'f' -> read_factory graph line
84
+          | 'v' -> read_village graph line
85
+          | 'n' -> read_node graph line
86
+          | 'r' -> read_road graph line
87
+
88
+          (* It should be a comment, otherwise we complain. *)
89
+          | _ -> read_comment graph line
90
+      in      
91
+      loop graph2
92
+
93
+    with End_of_file -> graph (* Done *)
94
+  in
95
+
96
+  let final_graph = loop initial_graph in
97
+
98
+  close_in infile ;
99
+  {graph = final_graph; origin = source; destination = destination}
100
+

+ 11
- 0
src/circulationfile.mli View File

@@ -0,0 +1,11 @@
1
+(* Read a graph from a file,
2
+ * Write a graph to a file. *)
3
+
4
+open Graph
5
+open Ffalgo
6
+
7
+type path = string
8
+
9
+val circulation_from_file: path -> int network
10
+
11
+

+ 38
- 0
src/circulationtest.ml View File

@@ -0,0 +1,38 @@
1
+open Circulationfile
2
+open Gfile
3
+open Tools
4
+open Ffalgo
5
+
6
+
7
+let flow_to_string gr = gmap gr (fun fl -> String.concat "/" [(string_of_int fl.current); (string_of_int fl.capacity)])
8
+
9
+let () =
10
+
11
+  (* Check the number of command-line arguments *)
12
+  if Array.length Sys.argv <> 3 then
13
+    begin
14
+      Printf.printf "\nUsage: %s infile outfile\n\n%!" Sys.argv.(0) ;
15
+      exit 0
16
+    end ;
17
+
18
+
19
+  (* Arguments are : infile(1) source-id(2) sink-id(3) outfile(4) *)
20
+
21
+  let infile = Sys.argv.(1)
22
+  and outfile = Sys.argv.(2)
23
+  in
24
+
25
+  (* Open file *)
26
+  let initial_network = circulation_from_file infile in
27
+  (* Execute FF *)
28
+  let solution_network = run_ff initial_network in
29
+  (* Print max flow *)
30
+  let () = Printf.printf "Max flow: %d\n%!" (get_max_flow solution_network) in
31
+  (* Convert to string for export *)
32
+  let final_graph = flow_to_string solution_network.graph in
33
+
34
+  (* Rewrite the graph that has been read. *)
35
+  let () = export outfile final_graph in
36
+
37
+  ()
38
+

Loading…
Cancel
Save