Spaces:
Running
Running
import numpy as np | |
import scipy | |
from models.solvers.lkh.lkh_base import LKHBase | |
class LKHCVRPTW(LKHBase): | |
def __init__(self, large_value=1e+6, scaling=False, max_trials=1000, seed=1234, lkh_dir="models/solvers/lkh/", io_dir="lkh_io_files"): | |
problem = "cvrptw" | |
super().__init__(problem, large_value, scaling, max_trials, seed, lkh_dir, io_dir) | |
def write_data(self, node_feats, f): | |
""" | |
Paramters | |
--------- | |
node_feats: dict of np.array | |
coords: np.array [num_nodes x coord_dim] | |
demand: np.array [num_nodes x 1] | |
capacity: np.array [1] | |
time_window: np.array [num_nodes x 2(start, end)] | |
""" | |
coords = node_feats["coords"] | |
demand = node_feats["demand"] | |
capacity = node_feats["capacity"][0] | |
time_window = node_feats["time_window"] | |
num_nodes = len(coords) | |
if self.scaling: | |
coords = coords * self.large_value | |
time_window = time_window * self.large_value | |
# VEHICLES | |
# As the number of unused vehicles is also included to penalty in default, | |
# we have to modify Penalty_CVRTW.c in LKH SRC directory. | |
# Comment out the following part, which corresponds to penaly of unsed vehicles: | |
# 42 if (MTSPMinSize >= 1 && Size < MTSPMinSize) | |
# 43 P += MTSPMinSize - Size; | |
# 44 if (Size > MTSPMaxSize) | |
# 45 P += Size - MTSPMaxSize; | |
# After the modification, we can automatically obtain optimal vehicle size | |
# by setting large vehicle size (e.g. >20) here | |
f.write("VEHICLES : 20\n") | |
# CAPACITY | |
f.write("CAPACITY : " + str(capacity) + "\n") | |
# EDGE_WEIGHT_SECTION | |
f.write("EDGE_WEIGHT_TYPE : EUC_2D\n") | |
# NODE_COORD_SECTION | |
f.write("NODE_COORD_SECTION\n") | |
for i in range(num_nodes): | |
f.write(f" {i + 1} {str(coords[i][0])[:10]} {str(coords[i][1])[:10]}\n") | |
# DEMAND_SECTION | |
f.write("DEMAND_SECTION\n") | |
for i in range(num_nodes): | |
f.write(f" {i + 1} {str(demand[i])}\n") | |
# TIME_WINDOW_SECTION | |
f.write("TIME_WINDOW_SECTION\n") | |
f.write("\n".join([ | |
"{}\t{}\t{}".format(i + 1, l, u) | |
for i, (l, u) in enumerate(time_window) | |
])) | |
# DEPOT SECTION | |
f.write("DEPOT_SECTION\n") | |
f.write("1\n") |