[workshop] Add notebook
This commit is contained in:
21
template/utils/load_data.py
Normal file
21
template/utils/load_data.py
Normal file
@@ -0,0 +1,21 @@
|
||||
def log(msg):
|
||||
print('[*] {msg}'.format(msg=msg))
|
||||
|
||||
def load_data(file):
|
||||
coords = []
|
||||
with open(file, "r") as infile:
|
||||
line = infile.readline()
|
||||
# Skip instance header
|
||||
while "NODE_COORD_SECTION" not in line:
|
||||
line = infile.readline()
|
||||
|
||||
for line in infile.readlines():
|
||||
line = line.replace("\n", "")
|
||||
if line and 'EOF' not in line:
|
||||
line = [float(x) for x in line.lstrip().split(" ", 1)[1].split(" ") if x]
|
||||
coords.append(line)
|
||||
return coords
|
||||
|
||||
def timeout_handler(signum, frame):
|
||||
print("Timeout")
|
||||
raise Exception("Timeout")
|
||||
139
template/utils/tsp.py
Normal file
139
template/utils/tsp.py
Normal file
@@ -0,0 +1,139 @@
|
||||
import os
|
||||
import signal
|
||||
import json
|
||||
import math
|
||||
import timeit
|
||||
|
||||
from utils.load_data import load_data
|
||||
from utils.load_data import log
|
||||
|
||||
def timeout_handler(signum, frame):
|
||||
raise Exception("Timeout")
|
||||
|
||||
def dist(node_0, node_1, coords):
|
||||
"""
|
||||
Euclidean distance between two nodes.
|
||||
"""
|
||||
coord_0, coord_1 = coords[node_0], coords[node_1]
|
||||
return math.sqrt((coord_0[0] - coord_1[0]) ** 2 + (coord_0[1] - coord_1[1]) ** 2)
|
||||
|
||||
def fitness(solution, coords):
|
||||
N = len(coords)
|
||||
cur_fit = 0
|
||||
for i in range(len(solution)):
|
||||
cur_fit += dist(solution[i % N], solution[(i + 1) % N], coords)
|
||||
return cur_fit
|
||||
|
||||
def TSP_Bench(tsp_file, model, *args, max_it=1000, timeout=60):
|
||||
|
||||
start = timeit.default_timer()
|
||||
|
||||
# Model Running
|
||||
best_solution, fitness_list = TSP(tsp_file, model, *args, max_it=max_it,timeout=timeout)
|
||||
# Model End
|
||||
|
||||
stop = timeit.default_timer()
|
||||
print('[*] Running for: {time:.2f} seconds'.format(time=(stop - start)))
|
||||
|
||||
print()
|
||||
return best_solution, fitness_list, (stop - start)
|
||||
|
||||
def TSP_Bench_ALL(tsp_file_path, model, *args, max_it=1000, timeout=60):
|
||||
best_solutions = []
|
||||
fitness_lists = []
|
||||
times = []
|
||||
for root, _, files in os.walk(tsp_file_path):
|
||||
if(files):
|
||||
for f in files:
|
||||
# Get input file name
|
||||
tsp_file = str(root) + '/' + str(f)
|
||||
log(tsp_file)
|
||||
|
||||
# Run TSP
|
||||
best_solution, fitness_list, time = TSP_Bench(tsp_file, model, *args, max_it=max_it,timeout=timeout)
|
||||
best_solutions.append(best_solution)
|
||||
fitness_lists.append(fitness_lists)
|
||||
times.append(time)
|
||||
|
||||
return best_solutions, fitness_lists, times
|
||||
|
||||
def TSP(tsp_file, model, *args, max_it=1000, timeout=60):
|
||||
|
||||
best_solution = []
|
||||
fitness_list = []
|
||||
|
||||
nodes = load_data(tsp_file)
|
||||
|
||||
# Set timeout
|
||||
signal.signal(signal.SIGALRM, timeout_handler)
|
||||
signal.alarm(timeout)
|
||||
|
||||
if not os.path.exists('output'):
|
||||
os.makedirs('output')
|
||||
|
||||
# Try your algorithm
|
||||
try:
|
||||
model.init(nodes, *args)
|
||||
best_solution, fitness_list = model.fit(max_it)
|
||||
except Exception as exc:
|
||||
if(str(exc) == "Timeout"):
|
||||
log("Timeout -3")
|
||||
with open('output/' + os.path.splitext(os.path.basename(tsp_file))[0] + '.txt', "w") as outfile:
|
||||
outfile.write("-3")
|
||||
best_solution = [-1] * len(nodes)
|
||||
else:
|
||||
print(exc)
|
||||
log("Unkown -4")
|
||||
with open('output/' + os.path.splitext(os.path.basename(tsp_file))[0] + '.txt', "w") as outfile:
|
||||
outfile.write("-4")
|
||||
|
||||
signal.alarm(0)
|
||||
|
||||
# Collect results
|
||||
if(len(fitness_list) > 0):
|
||||
log("[Node] " + str(len(best_solution)) + ", [Best] " + str(fitness_list[fitness_list.index(min(fitness_list))]))
|
||||
|
||||
if (len(best_solution) == 0):
|
||||
log("No Answer -1")
|
||||
with open('output/' + os.path.splitext(os.path.basename(tsp_file))[0] + '.txt', "w") as outfile:
|
||||
outfile.write("-1")
|
||||
elif (len(best_solution) != len(nodes)):
|
||||
log("Invalid -2")
|
||||
with open('output/' + os.path.splitext(os.path.basename(tsp_file))[0] + '.txt', "w") as outfile:
|
||||
outfile.write("-2")
|
||||
else:
|
||||
# log("Writing the best solution to file" )
|
||||
with open('output/' + os.path.splitext(os.path.basename(tsp_file))[0] + '.txt', "w") as outfile:
|
||||
outfile.write(str(model.fitness(best_solution)))
|
||||
outfile.write("\n")
|
||||
outfile.write(", ".join(str(item) for item in best_solution))
|
||||
|
||||
# Write to JSON
|
||||
data = {}
|
||||
|
||||
data['nodes'] = []
|
||||
for i in range(len(nodes)):
|
||||
data['nodes'].append({
|
||||
'title': str(i),
|
||||
'id': i,
|
||||
'x': int(nodes[i][0]),
|
||||
'y': int(nodes[i][1])
|
||||
})
|
||||
|
||||
data['edges'] = []
|
||||
for i in range(len(best_solution)):
|
||||
if i == len(best_solution)-1:
|
||||
data['edges'].append({
|
||||
'source': best_solution[i],
|
||||
'target': best_solution[0]
|
||||
})
|
||||
else:
|
||||
data['edges'].append({
|
||||
'source': best_solution[i],
|
||||
'target': best_solution[i+1]
|
||||
})
|
||||
|
||||
with open('output/' + os.path.splitext(os.path.basename(tsp_file))[0] + '.json', 'w') as outfile:
|
||||
json.dump(data, outfile)
|
||||
|
||||
return best_solution, fitness_list
|
||||
64
template/utils/visualize_tsp.py
Normal file
64
template/utils/visualize_tsp.py
Normal file
@@ -0,0 +1,64 @@
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
def plot_learning(fitness_list):
|
||||
"""
|
||||
Plot the fitness through iterations.
|
||||
"""
|
||||
plt.plot([i for i in range(len(fitness_list))], fitness_list)
|
||||
plt.ylabel("Fitness")
|
||||
plt.xlabel("Iteration")
|
||||
plt.show()
|
||||
|
||||
|
||||
def plotTSP(paths, points, num_iters=1):
|
||||
|
||||
"""
|
||||
path: List of lists with the different orders in which the nodes are visited
|
||||
points: coordinates for the different nodes
|
||||
num_iters: number of paths that are in the path list
|
||||
|
||||
"""
|
||||
|
||||
# Unpack the primary TSP path and transform it into a list of ordered
|
||||
# coordinates
|
||||
|
||||
x = []; y = []
|
||||
for i in paths[0]:
|
||||
x.append(points[i][0])
|
||||
y.append(points[i][1])
|
||||
|
||||
plt.plot(x, y, 'co')
|
||||
|
||||
# Set a scale for the arrow heads (there should be a reasonable default for this, WTF?)
|
||||
# a_scale = float(max(x))/float(100)
|
||||
|
||||
# Draw the older paths, if provided
|
||||
if num_iters > 1:
|
||||
|
||||
for i in range(1, num_iters):
|
||||
|
||||
# Transform the old paths into a list of coordinates
|
||||
xi = []; yi = [];
|
||||
for j in paths[i]:
|
||||
xi.append(points[j][0])
|
||||
yi.append(points[j][1])
|
||||
|
||||
plt.arrow(xi[-1], yi[-1], (xi[0] - xi[-1]), (yi[0] - yi[-1]),
|
||||
color = 'r', length_includes_head = True, ls = 'dashed',
|
||||
width = 0.001/float(num_iters))
|
||||
for i in range(0, len(x) - 1):
|
||||
plt.arrow(xi[i], yi[i], (xi[i+1] - xi[i]), (yi[i+1] - yi[i]),
|
||||
color = 'r', length_includes_head = True,
|
||||
ls = 'dashed', width = 0.001/float(num_iters))
|
||||
|
||||
# Draw the primary path for the TSP problem
|
||||
plt.arrow(x[-1], y[-1], (x[0] - x[-1]), (y[0] - y[-1]),
|
||||
color ='g', length_includes_head=True)
|
||||
for i in range(0,len(x)-1):
|
||||
plt.arrow(x[i], y[i], (x[i+1] - x[i]), (y[i+1] - y[i]),
|
||||
color = 'g', length_includes_head = True)
|
||||
|
||||
#Set axis too slitghtly larger than the set of x and y
|
||||
# plt.xlim(min(x)*1.1, max(x)*1.1)
|
||||
# plt.ylim(min(y)*1.1, max(y)*1.1)
|
||||
plt.show()
|
||||
Reference in New Issue
Block a user