this repo has no description
1#!/usr/bin/env python3
2"""
3This script will produce the final value of a variable named 'objective' and its
4area for every file ending in '.sol' in the directory provided. The files are
5expected to be fzn-gecode output piped through solns2out with the
6'--output-time' flag. Furthermore the file is expected to contain the initial
7area which can be found by adding
8'constraint trace("% init_area = \(ub(objective));\n", true);'
9to the model in question.
10"""
11import os
12import re
13import sys
14
15from statistics import stdev
16
17
18def compute_area(file):
19 objectives = []
20 times = [0]
21 objectives.append(0)
22 for line in file:
23 # match = re.match(r'%\sinit_area\s=\s(\d+)', line)
24 # match = re.match(r'%\sinit_area\s=\s(\d+)', line)
25 # if match:
26 # objectives.append(int(match[1]))
27 # continue
28 match = re.match(r"objective\s=\s(\d+)", line)
29 if match:
30 objectives.append(int(match.group(1)))
31 continue
32 match = re.match(r"%\stime elapsed:\s(\d+\.\d+)\ss", line)
33 if match:
34 times.append(float(match.group(1)))
35 continue
36 match = re.search(r"solveTime=(\d+(.\d+)?)", line)
37 if match:
38 times.append(float(match.group(1)))
39 continue
40
41 assert len(objectives) > 0
42 assert len(objectives) + 1 == len(times)
43 area = 0
44 for i in range(len(objectives)):
45 area += (times[i + 1] - times[i]) * objectives[i]
46 return int(area)
47
48
49folder = sys.argv[1]
50statistics = dict()
51instances = set()
52for config in ["original", "restart", "replay"]:
53 for root, dirs, files in os.walk(folder + "/" + config):
54 for name in files:
55 if name.endswith(".sol"):
56 components = name[:-(4)].split(".")
57 data = components[0]
58 instances.add(data)
59 seed = 1
60 if len(components) > 1:
61 assert len(components) == 2
62 seed = components[1]
63
64 if data not in statistics:
65 statistics[data] = dict()
66 if config not in statistics[data]:
67 statistics[data][config] = []
68
69 with open(os.path.join(root, name)) as f:
70 contents = f.readlines()
71 # Area
72 area = compute_area(contents)
73
74 objective = "UNSAT"
75 for line in contents[::-1]:
76 # Best objective
77 match = re.match(r"objective\s=\s(\d+)", line)
78 if match:
79 objective = int(match.group(1))
80 break
81
82 nodes = -1
83 solvetime = -1
84 restarts = -1
85 for line in contents:
86 # Evaluation time
87 match = re.search(r"copies:\s+(\d+)", line)
88 if match:
89 nodes = int(match.group(1))
90 continue
91 # Solve time
92 match = re.search(r"solveTime=(\d+(.\d+)?)", line)
93 if match:
94 solvetime = float(match.group(1))
95 continue
96 # Restarts
97 match = re.search(r"restarts=(\d+)", line)
98 if match:
99 restarts = int(match.group(1))
100 continue
101 statistics[data][config].append(
102 (
103 area,
104 objective,
105 solvetime,
106 restarts,
107 nodes,
108 )
109 )
110
111for data in instances:
112 for config in ["original", "restart", "replay"]:
113 stats = statistics[data][config]
114 cumulative = stats[0]
115 for i in range(1, len(stats)):
116 cumulative = tuple(map(sum, zip(cumulative, stats[i])))
117 avg = tuple([x / len(stats) for x in cumulative])
118 dev = stdev([x[1] for x in stats]) if len(stats) > 1 else 0
119 # (avg area, avg objective, stdev objective)
120 statistics[data][config] = (avg[0], avg[1], dev)
121
122# Print header
123print(
124 """
125\\begin{tabular}{l|rr|rr|rr}
126\\toprule
127& \multicolumn{2}{c|}{Gecode} & \multicolumn{2}{c|}{Gecode Restart} & \multicolumn{2}{c}{Gecode Replay}\\\\
128Instance & $\intobj$ & $\minobj$ & $\intobj$ & $\minobj$ & $\intobj$ & $\minobj$ \\\\
129\midrule
130"""
131)
132
133sorted_instances = sorted(instances)
134for data in sorted_instances:
135 print(f"{data}", end="")
136 for config in ["original", "restart", "replay"]:
137 print(
138 f" & {int(statistics[data][config][0] / 1000) }k & {int(statistics[data][config][1])}",
139 end="",
140 )
141 if statistics[data][config][2] != 0:
142 print("^{", end="")
143 print(
144 int(statistics[data][config][2] / statistics[data][config][1] * 100),
145 # int(statistics[data][config][2]),
146 end="",
147 )
148 print("}", end="")
149 print(" \\\\")
150
151# Print footer
152print("\n\\bottomrule\n\end{tabular}")