daisuke.kikuta
first commit
719d0db
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")