-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSampleLKH3.py
131 lines (114 loc) · 4.22 KB
/
SampleLKH3.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import subprocess
import os
LKH_PATH = "/Users/debojjalbagchi/Documents/LKH3_Solver/LKH-3.0.10/LKH" # TODO: Replace with the actual path
def clear_logs():
if os.path.exists('lkh3_logs'):
for file in os.listdir('lkh3_logs'):
os.remove(os.path.join('lkh3_logs', file))
else:
os.mkdir('lkh3_logs')
def get_edge_list(distance_matrix):
edge_list = []
dimension = len(distance_matrix)
for i in range(dimension):
for j in range(dimension):
if i != j:
edge_list.append([i + 1, j + 1, distance_matrix[i][j]]) # Nodes are 1-indexed in TSPLIB format
return edge_list
def tsplib_TSP(filename, distance_matrix):
dimension = len(distance_matrix)
with open(f"lkh3_logs/{filename}", 'w') as f:
f.write("NAME: TSP\n")
f.write("TYPE: ATSP\n")
f.write(f"DIMENSION: {dimension}\n")
f.write("EDGE_WEIGHT_TYPE: EXPLICIT\n")
f.write("EDGE_WEIGHT_FORMAT: FULL_MATRIX\n")
f.write("EDGE_WEIGHT_SECTION\n")
for row in distance_matrix:
f.write(" ".join(map(str, row)) + "\n")
f.write("EOF\n")
def tsplib_STTSP(filename, edge_list, terminals):
dimension = max(max(edge[0], edge[1]) for edge in edge_list)
with open(f"lkh3_logs/{filename}", 'w') as f:
f.write("NAME: STSP_75-1over3\n")
f.write("TYPE: STTSP\n")
f.write(f"DIMENSION: {dimension}\n")
f.write("EDGE_DATA_FORMAT: EDGE_LIST\n")
f.write("EDGE_DATA_SECTION\n")
for edge in edge_list:
f.write(" ".join(map(str, edge)) + "\n")
f.write("-1\n")
f.write("REQUIRED_NODES_SECTION\n")
for terminal in terminals:
f.write(f"{terminal}\n")
f.write("-1\n")
f.write("EOF\n")
def tsplib_TSPTW(filename, distance_matrix, time_windows, depot):
dimension = len(distance_matrix)
with open(f"lkh3_logs/{filename}", 'w') as f:
f.write("NAME : tsp time windows\n")
f.write("TYPE : TSPTW\n")
f.write(f"DIMENSION : {dimension}\n")
f.write("EDGE_WEIGHT_TYPE : EXPLICIT\n")
f.write("EDGE_WEIGHT_FORMAT : FULL_MATRIX\n")
f.write("EDGE_WEIGHT_SECTION\n")
for row in distance_matrix:
f.write(" ".join(map(str, row)) + "\n")
f.write("TIME_WINDOW_SECTION\n")
for node, start, end in time_windows:
f.write(f"{node} {start} {end}\n")
f.write("DEPOT_SECTION\n")
f.write(f"{depot}\n")
f.write("-1\n")
f.write("EOF\n")
def par_file(filename, tsp_filename):
with open(filename, 'w') as f:
f.write(f"PROBLEM_FILE = lkh3_logs/{tsp_filename}\n")
f.write("OUTPUT_TOUR_FILE = lkh3_logs/tour.txt\n")
def read_tour(filename):
with open(f'lkh3_logs/{filename}', 'r') as f:
lines = f.readlines()
tour_start = lines.index("TOUR_SECTION\n") + 1
tour_end = lines.index("-1\n")
tour = lines[tour_start:tour_end]
tour = [int(node.strip()) for node in tour]
return tour
def run_lkh(par_filename):
lkh_path = LKH_PATH
subprocess.run([lkh_path, par_filename])
if __name__ == "__main__":
clear_logs()
pr_type = 'TSP' # 'TSP', 'STTSP', 'TSPTW', 'Clear'
distance_matrix = [
[0, 10, 15, 20, 25],
[5, 0, 9, 10, 15],
[6, 13, 0, 12, 8],
[8, 8, 9, 0, 10],
[15, 5, 6, 9, 0]
]
if pr_type == 'Clear':
quit()
if pr_type == "TSP":
tsp_filename = "tsp_data.atsp"
tsplib_TSP(tsp_filename, distance_matrix)
if pr_type == 'STTSP':
edge_list = get_edge_list(distance_matrix)
terminals = [1, 3, 4]
tsp_filename = "steiner_tsp_data.sttsp"
tsplib_STTSP(tsp_filename, edge_list, terminals)
if pr_type == 'TSPTW':
depot = 1
time_windows = [
(1, 0, 9600000),
(2, 430000, 2830000),
(3, 360000, 2760000),
(4, 330000, 2730000),
(5, 330000, 2730000)
]
tsp_filename = "tsptw_data.tsptw"
tsplib_TSPTW(tsp_filename, distance_matrix, time_windows, depot)
par_filename = "params.par"
par_file(par_filename, tsp_filename)
run_lkh(par_filename)
tour = read_tour("tour.txt")
print("Optimal tour:", tour)