diff --git a/analyse_gecode.py b/analyse_gecode.py index 0a7b730..90fb8ce 100755 --- a/analyse_gecode.py +++ b/analyse_gecode.py @@ -13,15 +13,15 @@ import os import re import sys +from statistics import stdev + def compute_area(file): - area = -1 - objectives = [] times = [0] - timeout = -1 objectives.append(0) - for line in contents: + for line in file: + # match = re.match(r'%\sinit_area\s=\s(\d+)', line) # match = re.match(r'%\sinit_area\s=\s(\d+)', line) # if match: # objectives.append(int(match[1])) @@ -30,7 +30,7 @@ def compute_area(file): if match: objectives.append(int(match.group(1))) continue - match = re.match(r"%\stime elapsed:\s(\d\.\d+)\ss", line) + match = re.match(r"%\stime elapsed:\s(\d+\.\d+)\ss", line) if match: times.append(float(match.group(1))) continue @@ -43,65 +43,111 @@ def compute_area(file): assert len(objectives) + 1 == len(times) area = 0 for i in range(len(objectives)): - area += ((times[i + 1] - times[i]) / 1000) * objectives[i] + area += (times[i + 1] - times[i]) * objectives[i] return int(area) folder = sys.argv[1] -statistics = {} -for root, dirs, files in os.walk(folder): - for name in files: - if name.endswith(".sol"): - seed = 1 - match = re.search(r"\.(\d+)\.sol", name) - if match: - seed = int(match.group(1)) - with open(os.path.join(root, name)) as f: - contents = f.readlines() - # Area - area = compute_area(contents) +statistics = dict() +instances = set() +for config in ["original", "restart", "replay"]: + for root, dirs, files in os.walk(folder + "/" + config): + for name in files: + if name.endswith(".sol"): + components = name[:-(4)].split(".") + data = components[0] + instances.add(data) + seed = 1 + if len(components) > 1: + assert len(components) == 2 + seed = components[1] - objective = "UNSAT" - for line in contents[::-1]: - # Best objective - match = re.match(r"objective\s=\s(\d+)", line) - if match: - objective = int(match.group(1)) - break + if data not in statistics: + statistics[data] = dict() + if config not in statistics[data]: + statistics[data][config] = [] - nodes = -1 - solvetime = -1 - restarts = -1 - for line in contents: - # Evaluation time - match = re.search(r"copies:\s+(\d+)", line) - if match: - nodes = int(match.group(1)) - continue - # Solve time - match = re.search(r"solveTime=(\d+(.\d+)?)", line) - if match: - solvetime = float(match.group(1)) - continue - # Restarts - match = re.search(r"restarts=(\d+)", line) - if match: - restarts = int(match.group(1)) - continue - statistics[name[:-(4)].replace(".", ",")] = ( - area, - objective, - solvetime, - restarts, - nodes, + with open(os.path.join(root, name)) as f: + contents = f.readlines() + # Area + area = compute_area(contents) + + objective = "UNSAT" + for line in contents[::-1]: + # Best objective + match = re.match(r"objective\s=\s(\d+)", line) + if match: + objective = int(match.group(1)) + break + + nodes = -1 + solvetime = -1 + restarts = -1 + for line in contents: + # Evaluation time + match = re.search(r"copies:\s+(\d+)", line) + if match: + nodes = int(match.group(1)) + continue + # Solve time + match = re.search(r"solveTime=(\d+(.\d+)?)", line) + if match: + solvetime = float(match.group(1)) + continue + # Restarts + match = re.search(r"restarts=(\d+)", line) + if match: + restarts = int(match.group(1)) + continue + statistics[data][config].append( + ( + area, + objective, + solvetime, + restarts, + nodes, + ) + ) + +for data in instances: + for config in ["original", "restart", "replay"]: + stats = statistics[data][config] + cumulative = stats[0] + for i in range(1, len(stats)): + cumulative = tuple(map(sum, zip(cumulative, stats[i]))) + avg = tuple([x / len(stats) for x in cumulative]) + dev = stdev([x[1] for x in stats]) if len(stats) > 1 else 0 + # (avg area, avg objective, stdev objective) + statistics[data][config] = (avg[0], avg[1], dev) + +# Print header +print( + """ +\\begin{tabular}{l|rr|rr|rr} +\\toprule +& \multicolumn{2}{c|}{Gecode} & \multicolumn{2}{c|}{Gecode Restart} & \multicolumn{2}{c}{Gecode Replay}\\\\ +Instance & $\intobj$ & $\minobj$ & $\intobj$ & $\minobj$ & $\intobj$ & $\minobj$ \\\\ +\midrule +""" +) + +sorted_instances = sorted(instances) +for data in sorted_instances: + print(f"{data}", end="") + for config in ["original", "restart", "replay"]: + print( + f" & {int(statistics[data][config][0] / 1000) }k & {int(statistics[data][config][1])}", + end="", + ) + if statistics[data][config][2] != 0: + print("^{", end="") + print( + int(statistics[data][config][2] / statistics[data][config][1] * 100), + # int(statistics[data][config][2]), + end="", ) + print("}", end="") + print(" \\\\") -sorted_stats = sorted(statistics.items()) -a = sorted_stats[0][0][: sorted_stats[0][0].find(",")] -for key, val in sorted_stats: - if key[: key.find(",")] != a: - print("\n\n") - a = key[: key.find(",")] - print("%s,%s" % (key, ",".join([v.__str__() for v in val]))) - -exit(1) +# Print footer +print("\n\\bottomrule\n\end{tabular}")