128 lines
3.5 KiB
Python
Executable File
128 lines
3.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import os
|
|
import re
|
|
import sys
|
|
|
|
import matplotlib as mpl
|
|
import matplotlib.pyplot as plt
|
|
import matplotlib.ticker as ticker
|
|
import numpy as np
|
|
import pandas as pd
|
|
import seaborn as sns
|
|
|
|
|
|
def obj_timeline(file_contents: bytes):
|
|
objectives = []
|
|
times = []
|
|
for line in file_contents:
|
|
if line.strip() == "==========":
|
|
break
|
|
match = re.match(r"objective\s=\s(\d+)", line)
|
|
if match:
|
|
objectives.append(int(match.group(1)))
|
|
continue
|
|
match = re.match(r"%\stime elapsed:\s(\d+\.\d+)\ss", line)
|
|
if match:
|
|
times.append(float(match.group(1)))
|
|
continue
|
|
|
|
assert len(objectives) > 0
|
|
assert len(objectives) == len(times)
|
|
|
|
return [(times[i], objectives[i]) for i in range(len(objectives))]
|
|
|
|
|
|
TAGMAP = {
|
|
"original": "Base",
|
|
"restart": "Restart Based LNS",
|
|
"replay": "LNS Replay",
|
|
}
|
|
|
|
if __name__ == "__main__":
|
|
folder = sys.argv[1]
|
|
CONFIG = ["original", "restart"]
|
|
solver = sys.argv[2]
|
|
if solver == "Gecode":
|
|
CONFIG.append("replay")
|
|
statistics = dict()
|
|
instances = set()
|
|
# Read all the files
|
|
for config in CONFIG:
|
|
statistics[config] = dict()
|
|
for root, dirs, files in os.walk(folder + "/" + config):
|
|
for name in files:
|
|
if not name.endswith(".sol"):
|
|
continue
|
|
components = name[:-(4)].split(".")
|
|
data = components[0]
|
|
instances.add(data)
|
|
seed = 1
|
|
if len(components) > 1:
|
|
assert len(components) == 2
|
|
seed = components[1]
|
|
|
|
if data not in statistics[config]:
|
|
statistics[config][data] = []
|
|
|
|
with open(os.path.join(root, name)) as f:
|
|
contents = f.readlines()
|
|
|
|
timeline = obj_timeline(contents)
|
|
statistics[config][data].append(timeline)
|
|
|
|
baseline = 0
|
|
for data in instances:
|
|
baseline += statistics["original"][data][0][0][1]
|
|
|
|
times = []
|
|
cumulative = []
|
|
tag = []
|
|
|
|
def emit(time, obj, conf):
|
|
times.append(time)
|
|
cumulative.append(obj)
|
|
tag.append(TAGMAP[conf])
|
|
|
|
for config in CONFIG:
|
|
events = dict()
|
|
for data in instances:
|
|
length = len(statistics[config][data])
|
|
for i in range(length):
|
|
timeline = statistics[config][data][i]
|
|
for j in range(1, len(timeline)):
|
|
if timeline[j][0] not in events:
|
|
events[timeline[j][0]] = 0
|
|
events[timeline[j][0]] += (
|
|
timeline[j][1] - timeline[j - 1][1]
|
|
) / length
|
|
|
|
sorted_events = sorted(events)
|
|
incumbent = baseline
|
|
emit(0, incumbent, config)
|
|
for i in sorted_events:
|
|
incumbent += events[i]
|
|
emit(i, incumbent, config)
|
|
emit(120, incumbent, config)
|
|
|
|
df = pd.DataFrame(
|
|
data={
|
|
"Time (s)": times,
|
|
"Cumulative Objective": cumulative,
|
|
"Solver Version": tag,
|
|
}
|
|
)
|
|
|
|
sns.set(font_scale=1.23, style="whitegrid", font="IBM Plex Sans")
|
|
fig, ax = plt.subplots()
|
|
ax.yaxis.set_major_formatter(ticker.EngFormatter())
|
|
|
|
plot = sns.lineplot(
|
|
data=df,
|
|
x="Time (s)",
|
|
y="Cumulative Objective",
|
|
hue="Solver Version",
|
|
style="Solver Version",
|
|
linewidth=4,
|
|
)
|
|
plot.figure.savefig("output.pdf")
|