this repo has no description
at develop 5.1 kB view raw
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 csv 12import os 13import re 14import sys 15 16from statistics import stdev 17 18 19def compute_area(file, time): 20 area = -1 21 22 objectives = [] 23 times = [0] 24 timeout = -1 25 objectives.append(0) 26 for line in contents: 27 # match = re.match(r'%\sinit_area\s=\s(\d+)', line) 28 # if match: 29 # objectives.append(int(match.group(1))) 30 # continue 31 match = re.match(r"objective\s=\s(\d+)", line) 32 if match: 33 objectives.append(int(match.group(1))) 34 continue 35 match = re.match(r"%\stime elapsed:\s(\d+\.\d+)\ss", line) 36 if match: 37 times.append(float(match.group(1))) 38 continue 39 # Not proven optimal 40 if len(times) == len(objectives): 41 times.append(time) 42 43 assert len(objectives) > 0 44 assert len(objectives) + 1 == len(times) 45 area = 0 46 for i in range(len(objectives)): 47 area += (times[i + 1] - times[i]) * objectives[i] 48 return int(area) 49 50 51folder = sys.argv[1] 52statistics = dict() 53instances = set() 54for config in ["original", "restart"]: 55 for root, dirs, files in os.walk(folder + "/" + config): 56 for name in files: 57 if name.endswith(".sol"): 58 components = name[:-(4)].split(".") 59 data = components[0] 60 instances.add(data) 61 seed = 1 62 if len(components) > 1: 63 assert len(components) == 2 64 seed = components[1] 65 66 if data not in statistics: 67 statistics[data] = dict() 68 if config not in statistics[data]: 69 statistics[data][config] = [] 70 71 with open(os.path.join(root, name)) as f: 72 contents = f.readlines() 73 74 nodes = None 75 solvetime = None 76 restarts = None 77 objective = None 78 for line in contents: 79 # Nodes 80 match = re.search(r"%%%mzn-stat: nodes=(\d+)", line) 81 if match: 82 nodes = int(match.group(1)) 83 continue 84 # Solve time 85 match = re.search(r"%%%mzn-stat: solveTime=(\d+\.\d+)", line) 86 if match: 87 solvetime = float(match.group(1)) 88 continue 89 # Restarts 90 match = re.search(r"%%%mzn-stat: restarts=(\d+)", line) 91 if match: 92 restarts = int(match.group(1)) 93 continue 94 95 for line in contents[::-1]: 96 # Best objective 97 match = re.match(r"%%%mzn-stat: objective=(-?\d+)", line) 98 if match: 99 objective = int(match.group(1)) 100 break 101 # Area 102 area = compute_area(contents, solvetime) 103 104 statistics[data][config].append( 105 ( 106 area, 107 objective, 108 solvetime, 109 restarts, 110 nodes, 111 ) 112 ) 113 114for data in instances: 115 for config in ["original", "restart"]: 116 stats = statistics[data][config] 117 cumulative = stats[0] 118 for i in range(1, len(stats)): 119 cumulative = tuple(map(sum, zip(cumulative, stats[i]))) 120 avg = tuple([x / len(stats) for x in cumulative]) 121 dev = stdev([x[1] for x in stats]) if len(stats) > 1 else 0 122 # (avg area, avg objective, stdev objective) 123 statistics[data][config] = (avg[0], avg[1], dev) 124 125# Print header 126print( 127 """ 128\\begin{tabular}{l|rr|rr|rr} 129\\toprule 130& \multicolumn{2}{c|}{Chuffed} & \multicolumn{2}{c|}{Chuffed Restart} \\\\ 131Instance & $\intobj$ & $\minobj$ & $\intobj$ & $\minobj$ \\\\ 132\midrule 133""" 134) 135 136sorted_instances = sorted(instances) 137for data in sorted_instances: 138 print(f"{data}", end="") 139 for config in ["original", "restart"]: 140 print( 141 f" & {int(statistics[data][config][0] / 1000) }k & {int(statistics[data][config][1])}", 142 end="", 143 ) 144 if statistics[data][config][2] != 0: 145 print("^{", end="") 146 print( 147 int(statistics[data][config][2] / statistics[data][config][1] * 100), 148 # int(statistics[data][config][2]), 149 end="", 150 ) 151 print("}", end="") 152 print(" \\\\") 153 154# Print footer 155print("\n\\bottomrule\n\end{tabular}")