如何解决无约束的 VRP 的 OR 工具错误地分组
我正在使用 OR 工具来解决 VRP,没有任何限制。这是源代码:
def create_data_model():
"""Stores the data for the problem."""
data = {}
data['distance_matrix'] = [
[0,20079,2613,8005,19277,12468,13701],[0,21285,16012,32574,35394,28806],18233,5392,19965,19650,13064],15013,5639,22883,22570,15982],32991,19256,21815,18414,9112],34348,16976,23122,15678,14647],27652,13917,16476,8043,14820,0]
]
data['time_matrix'] = [
[0,1955,508,1331,1474,1427,1292],1795,1608,2057,2410,2036],1485,823,1370,1541,1100],1402,924,1533,1637,1263],2308,1663,1853,1766,1104],2231,1373,1660,1441,1554],1998,1353,1543,764,1550,0]
]
data['num_vehicles'] = 6
data['depot'] = 0
return data
def print_solution(data,manager,routing,solution):
"""Prints solution on console."""
max_route_distance = 0
for vehicle_id in range(data['num_vehicles']):
index = routing.Start(vehicle_id)
plan_output = 'Route for vehicle {}:\n'.format(vehicle_id)
route_distance = 0
while not routing.IsEnd(index):
plan_output += ' {} -> '.format(manager.IndexToNode(index))
prevIoUs_index = index
index = solution.Value(routing.Nextvar(index))
route_distance += routing.GetArcCostForVehicle(
prevIoUs_index,index,vehicle_id)
plan_output += '{}\n'.format(manager.IndexToNode(index))
plan_output += 'distance of the route: {}m\n'.format(route_distance)
print(plan_output)
max_route_distance = max(route_distance,max_route_distance)
print('Maximum of the route distances: {}m'.format(max_route_distance))
def test(request):
# Instantiate the data problem.
data = create_data_model()
# Create the routing index manager.
manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']),data['num_vehicles'],data['depot'])
# Create Routing Model.
routing = pywrapcp.RoutingModel(manager)
def distance_callback(from_index,to_index):
"""Returns the distance between the two nodes."""
# Convert from routing variable Index to distance matrix NodeIndex.
from_node = manager.IndexToNode(from_index)
to_node = manager.IndexToNode(to_index)
return data['distance_matrix'][from_node][to_node]
transit_callback_index = routing.RegisterTransitCallback(distance_callback)
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
dimension_name = 'distance'
routing.AddDimension(
transit_callback_index,# no slack
1000000000,# vehicle maximum travel distance
True,# start cumul to zero
dimension_name)
distance_dimension = routing.GetDimensionorDie(dimension_name)
distance_dimension.SetGlobalSpanCostCoefficient(35394)
# Setting first solution heuristic.
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (
routing_enums_pb2.FirstSolutionStrategy.PATH_CHEApest_ARC)
# Solve the problem.
solution = routing.solveWithParameters(search_parameters)
# Print solution on console.
if solution:
print_solution(data,solution)
return HttpResponse('')
以上所有内容均从 google 示例中复制粘贴而来,但以下内容除外:
- 我自己的距离矩阵和车辆数量
- AddDimension 函数中非常大的车辆最大行驶距离
- SetGlobalSpanCostCoefficient(35394)
- 我按照 OR-Tools solve traveling salesman (TSP) without returning to the home node 将所有节点到 0(仓库)的距离设置为 0。
以上代码的结果如下所示:
Route for vehicle 0:
0 -> 1 -> 0
distance of the route: 20079m
Route for vehicle 1:
0 -> 5 -> 0
distance of the route: 12468m
Route for vehicle 2:
0 -> 4 -> 0
distance of the route: 19277m
Route for vehicle 3:
0 -> 2 -> 3 -> 0
distance of the route: 8005m
Route for vehicle 4:
0 -> 6 -> 0
distance of the route: 13701m
Route for vehicle 5:
0 -> 0
distance of the route: 0m
Maximum of the route distances: 20079m
为了验证上面的输出,我在谷歌地图上标记了点。编号顺序与距离矩阵的顺序相同。
仓库(起点)在 Watthana,可以在标记 B 附近看到。
显然,从 Watthana 出发,单次旅行中最便宜的路径应该是 2-1-3。但是 Google OR 将其返回为两次行程(如车辆 0 和 3 的路线所示)。这也可以通过手动添加距离来验证。
从家到 2 到 1 到 3 的距离 = 2613+5392+15013 = 23018m
车辆 0 和 3 的距离 = 20079+8005 = 28084m
我做错了什么?我怎样才能让谷歌不把第 1 点分开?另请注意,理想情况下,点 E、F、D 也可以分组,但它们没有。
提前致谢!
解决方法
从问题来看,我认为您想要的是减少所有车辆行驶的累计距离。
distance_dimension.SetGlobalSpanCostCoefficient(35394)
相反,此代码通过将 Span Cost 添加到由 35394 加权的目标函数来确保每辆车行驶的距离最小化。
global_span_cost =
coefficient * (Max(dimension end value) - Min(dimension start value))
在您的情况下,这不是一个非常高的优先级,因此解决方案是注释该行或将系数减少到一个小的值,例如 1 或 2,降低它的唯一重要性。
详细了解GSpanCoeff
现在的解决方案应该是
Route for vehicle 0:
0 -> 2 -> 3 -> 1 -> 0
Distance of the route: 23018m
Route for vehicle 1:
0 -> 6 -> 4 -> 0
Distance of the route: 21744m
Route for vehicle 2:
0 -> 5 -> 0
Distance of the route: 12468m
Maximum of the route distances: 23018m
Sum of the route distances: 57230m
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。