1. 解析路由模型解的内容,生成线路。
- 客户的运输线路和顺序。
routes = []
for route_nbr in range(self.routing.vehicles()):
index = self.routing.Start(route_nbr)
route = [self.manager.IndexToNode(index)]
while not self.routing.IsEnd(index):
index = solution.Value(self.routing.NextVar(index))
route.append(self.manager.IndexToNode(index))
routes.append(route)
- 客户的到达时间、等待时间
time_dimension = self.routing.GetDimensionOrDie('Time')
cumul_datas = []
for i in range(self.data["params"]["vehicle_nums"]):
cumul_data = []
_times = {}
# 返回车辆的开始索引
index = self.routing.Start(i)
_times["wait_time"] = 0
_times["arrive_time"] = solution.Min(time_dimension.CumulVar(index))
cumul_data.append(_times)
while not self.routing.IsEnd(index):
# 返回下一个节点
index = solution.Value(self.routing.NextVar(index))
_times = {}
# 下一个节点的等待时间
_times["wait_time"] = solution.Min(time_dimension.SlackVar(index)) if not self.routing.IsEnd(index) else 0
# 下一个节点的到达时间
_times["arrive_time"] = solution.Min(time_dimension.CumulVar(index))
cumul_data.append(_times)
cumul_datas.append(cumul_data)
- 客户的早晚到时间
for i in range(len(routes)):
route = routes[i]
for j in range(len(route)):
index = route[j]
if index == 0:
route_times[i][j]["early_hours"] = 0
route_times[i][j]["late_hours"] = 0
else:
route_times[i][j]["early_hours"] = max(0, self.data["time_windows"][index][0] - route_times[i][j]["arrive_time"])
route_times[i][j]["late_hours"] = max(0, route_times[i][j]["arrive_time"] - self.data["time_windows"][index][1])
2. 转换为精确求解需要的形式。
ini_solution = {} # 储存初始解
vehicle_ids = [] # 储存车辆信息
# 字典形式保存初始解
_x_value, _t_value, _w_value, _e_value, _l_value = {}, {}, {}, {}, {}
for i in range(len(routes)):
if len(routes[i]) > 2:
vehicle_ids.append(i)
route = routes[i]
route_times = all_times[i]
for j in range(1, len(route)):
if j > 0:
_x_value[(route[j - 1], route[j], start_vehicle_id)] = 1
_t_value[(route[j - 1], start_vehicle_id)] = route_times[j - 1]["arrive_time"]
_w_value[(route[j - 1], start_vehicle_id)] = route_times[j - 1]["wait_time"]
_e_value[(route[j - 1], start_vehicle_id)] = route_times[j - 1]["early_hours"]
_l_value[(route[j - 1], start_vehicle_id)] = route_times[j - 1]["late_hours"]
start_vehicle_id += 1
ini_solution.update({"x_values": _x_value, "t_values": _t_value, "w_values": _w_value, "e_values": _e_value, "l_values": _l_value})
3. 以ortools为例,初始解赋值。
solution = self.initial_solutions
if self.solver_name == "cp_sat":
variables = self.model._CpModel__model.variables
if self.solver_name != "cp_sat":
variables = self.model.variables()
pattern = re.compile(r'[(](.*?)[)]', re.S)
if solution is not None:
x_values = solution["x_values"]
w_values = solution["w_values"]
t_values = solution["t_values"]
e_values = solution["e_values"]
l_values = solution["l_values"]
all_vars = []
all_values = []
for i, field in enumerate(variables):
if self.solver_name == "cp_sat":
name = field.name
if self.solver_name != "cp_sat":
name = variables[i].name()
if len(re.findall(pattern, name)) > 0:
key = tuple([int(i) for i in re.findall(pattern, name)[0].split(",")])
if "x" in name:
if x_values.get(key, None):
if self.solver_name == "cp_sat":
self.model.AddHint(i, x_values.get(key))
if self.solver_name != "cp_sat":
all_vars.append(self.model.variable(i))
all_values.append(x_values.get(key))
else:
if self.solver_name == "cp_sat":
self.model.AddHint(i, 0)
if self.solver_name != "cp_sat":
all_vars.append(self.model.variable(i))
all_values.append(0)
elif "w" in name:
if w_values.get(key, None):
if self.solver_name == "cp_sat":
self.model.AddHint(i, w_values.get(key))
if self.solver_name != "cp_sat":
all_vars.append(self.model.variable(i))
all_values.append(w_values.get(key))
elif "t" in name:
if t_values.get(key, None):
if self.solver_name == "cp_sat":
self.model.AddHint(i, t_values.get(key))
if self.solver_name != "cp_sat":
all_vars.append(self.model.variable(i))
all_values.append(t_values.get(key))
elif "e" in name:
if e_values.get(key, None):
if self.solver_name == "cp_sat":
self.model.AddHint(i, e_values.get(key))
if self.solver_name != "cp_sat":
all_vars.append(self.model.variable(i))
all_values.append(e_values.get(key))
elif "l" in name:
if l_values.get(key, None):
if self.solver_name == "cp_sat":
self.model.AddHint(i, l_values.get(key))
if self.solver_name != "cp_sat":
all_vars.append(self.model.variable(i))
all_values.append(l_values.get(key))
else:
pass
if self.solver_name != "cp_sat":
self.model.SetHint(all_vars, all_values)