简体   繁体   English

如何解释从 Google OR Tools 返回的 Vehicle Routing Problem 解决方案?

[英]How do I interpret the Vehicle Routing Problem solution returned from Google OR Tools?

I have a working Vehicle Routing Problem solution implemented using Google's OR Tools python library.我有一个使用 Google 的 OR 工具 python 库实现的有效车辆路由问题解决方案。 I have a time matrix of 9 locations, and time windows for each location.我有一个包含 9 个位置的时间矩阵,每个位置的时间为 windows。 All values are in units of seconds .所有值都以为单位。

(For example, the first time window is from 28800 to 28800. 28800 seconds is equivalent to 8:00am. I want this location, the depot , to be visited at exactly 8:00am) (例如,第一次 window 是从 28800 到 28800。28800 秒相当于上午 8:00。我希望在上午 8:00 准确地访问这个位置,仓库

I am intentionally solving this with just one vehicle (essentially solving a Traveling Salesperson Problem).我有意只用一辆车来解决这个问题(主要是解决旅行销售员问题)。 I believe that I have added my dimension correctly, but I could certainly have made a mistake with that - my intention is to allow the vehicle to wait at any location for as long as it would like, as along as it allows it to solve the vehicle routing problem.相信我已经正确添加了我的尺寸,但我肯定会犯错 - 我的目的是让车辆在任何位置等待只要它愿意,只要它允许它解决车辆路线问题。 I set the upper bound maximum value as 86400 because there are 86400 seconds in a day, and I figure that would be a sufficiently high number given this data.我将上限最大值设置为 86400,因为一天有 86400 秒,我认为考虑到这些数据,这将是一个足够高的数字。

Source资源

from ortools.constraint_solver import pywrapcp
from ortools.constraint_solver import routing_enums_pb2

Matrix = [
  [0,557,763,1156,813,618,822,700,112],       # Depot
  [523,0,598,1107,934,607,658,535,589],       # 1 - Location
  [631,480,0,968,960,570,451,135,582],        # 2 - Location
  [1343,1247,1367,0,1270,1289,809,1193,1253], # 3 - Location
  [746,1000,1135,1283,0,1003,1186,1071,776],  # 4 - Location
  [685,627,810,1227,990,0,712,709,550],       # 5 - Location
  [869,718,558,732,1105,650,0,384,821],       # 6 - Location
  [679,528,202,878,1008,618,412,0,630],       # 7 - Location
  [149,626,762,1124,696,532,821,698,0]        # 8 - Location
]

Windows = [
  [ 28800, 28800 ], # Depot
  [ 43200, 43200 ], # 1 - Location
  [ 50400, 50400 ], # 2 - Location
  [ 21600, 79200 ], # 3 - Location
  [ 21600, 79200 ], # 4 - Location
  [ 21600, 79200 ], # 5 - Location
  [ 21600, 79200 ], # 6 - Location
  [ 21600, 79200 ], # 7 - Location
  [ 21600, 79200 ]  # 8 - Location
]

# Create the routing index manager.
manager = pywrapcp.RoutingIndexManager(len(Matrix), 1, 0)

# Create Routing Model.
routing = pywrapcp.RoutingModel(manager)

# Create and register a transit callback.
def time_callback(from_index, to_index):
  # Returns the travel time between the two nodes.
  # Convert from routing variable Index to time matrix NodeIndex.
  from_node = manager.IndexToNode(from_index)
  to_node = manager.IndexToNode(to_index)
  return Matrix[from_node][to_node]

transit_callback_index = routing.RegisterTransitCallback(time_callback)

# Define cost of each arc.
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)

# Add Time Windows constraint.
routing.AddDimension(
    transit_callback_index,
    86400,  # An upper bound for slack (the wait times at the locations).
    86400,  # An upper bound for the total time over each vehicle's route.
    False,  # Determine whether the cumulative variable is set to zero at the start of the vehicle's route.
    'Time')
time_dimension = routing.GetDimensionOrDie('Time')

# Add time window constraints for each location except depot.
for location_idx, time_window in enumerate(Windows):
  if location_idx == 0:
    continue
  index = manager.NodeToIndex(location_idx)
  time_dimension.CumulVar(index).SetRange(time_window[0], time_window[1])

# Add time window constraints for each vehicle start node.
index = routing.Start(0)
time_dimension.CumulVar(index).SetRange(Windows[0][0],Windows[0][1])

# Instantiate route start and end times to produce feasible times.
routing.AddVariableMinimizedByFinalizer(time_dimension.CumulVar(routing.Start(0)))
routing.AddVariableMinimizedByFinalizer(time_dimension.CumulVar(routing.End(0)))

# Setting first solution heuristic. 
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)

# Setting local search metaheuristics:
search_parameters.local_search_metaheuristic = (routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)
search_parameters.time_limit.seconds = 5
search_parameters.log_search = False

# Solve the problem.
solution = routing.SolveWithParameters(search_parameters)

# Return the solution.
time = 0
index = routing.Start(0)
print("Locations:")
while not routing.IsEnd(index):
  time = time_dimension.CumulVar(index)
  print("{0} ({1}, {2})".format(manager.IndexToNode(index),solution.Min(time),solution.Max(time)))
  index = solution.Value(routing.NextVar(index))
print("{0} ({1}, {2})".format(manager.IndexToNode(index),solution.Min(time),solution.Max(time)))

Output Output

Locations:
0 (28800, 28800)
8 (28912, 42041)
5 (29444, 42573)
1 (43200, 43200)
2 (50400, 50400)
7 (50535, 50535)
6 (50947, 50947)
3 (51679, 51679)
4 (52949, 52949)
0 (52949, 52949)

My question is in regards to the output that the solution has calculated for me.我的问题是关于解决方案为我计算的 output。 I am confused about the time windows for the second and third locations in the solution.我对解决方案中第二个和第三个位置的时间 windows 感到困惑。 I expected all of the time windows to look like the rest of the result.我一直期望 windows 看起来像结果的 rest。 What do the solution.Min() and solution.Max() values mean in the scope of this problem when I'm processing my solution?当我处理我的解决方案时,这个问题的 scope 中的solution.Min()solution.Max()值是什么意思? Are there any blatant errors in my usage of OR Tools?我在使用 OR Tools 时是否有任何明显的错误?

What I understand of this tuples is that you have我对这个元组的理解是你有

(Min_time, Max_time)

Where Min_time is the minimum time that you should arrive to satisfy the Time Window.其中Min_time是您应该到达以满足时间 Window 的最短时间。 For the Max_time is exactly the same logic.对于Max_time也是完全一样的逻辑。

The program outputs a range when you can arrive to the node satisfying the constraints.当您可以到达满足约束的节点时,程序会输出一个范围。

Locations:
0 (28800, 28800) // must arrive and leave no later than 28800
8 (28912, 42041) // must arrive at or after 28912 and leave no later than 42041
5 (29444, 42573) // must arrive at or after 29444and leave no later than 42573
1 (43200, 43200) // must arrive and leave no later than 43200
2 (50400, 50400) // must arrive and leave no later than 50400

See the comments I have added.请参阅我添加的评论。 When the arrival time is a range as, say node 8 or 5, it basically means the arrival time needs to fall in that time range.当到达时间是一个范围时,比如说节点 8 或 5,它基本上意味着到达时间需要落在那个时间范围内。 The solution remains feasible so long that condition is met.只要满足该条件,该解决方案仍然可行。

You can verify it as follows:您可以按如下方式进行验证:

Depot [28800, 28800] -> Travel (0, 8) 112-> Loc 8 [21600, 79200] -> Travel (8, 5) 532 -> Loc 5 [21600, 79200] -> Travel (5, 1) 685 -> Loc 1 [43200, 43200]

Departing at the depot at time 28800 with a travel time of 112 will have you arrive at loc 8 at time 28912 (the min value in your solution), departing immediately with a travel time of 532 will have you reach loc 5 at time 29444.在时间 28800 出发,行程时间为 112,您将在时间 28912(您的解决方案中的最小值)到达地点 8(您的解决方案中的最小值),立即出发,行程时间为 532,您将在时间 29444 到达地点 5。

Now, loc 1 has a single time slot available, which is 43200 .现在, loc 1有一个可用的时隙,即43200 So if the vehicle were to leave at time 29444 with a travel time of 627 it would reach loc 1 at time 30071 , which is not a valid arrival time.因此,如果车辆在时间29444离开,行程时间为627 ,它将在时间30071到达loc 1 ,这不是有效的到达时间。 But if the vehicle were to depart at 43200-627= 42573 it would arrive on time.但如果车辆在43200-627= 42573出发,它将准时到达。 So this means the vehicle needs to be idle (slack) for a little while before it can go.所以这意味着车辆需要闲置(松弛)一段时间才能go。 As both loc 8 and loc 5 have a range, the solution is stating that there is some slack available at those locations.由于loc 8loc 5都有一个范围,解决方案是说明在这些位置有一些可用的 slack。 So what the min and max values are really telling you is the solution is feasible so long the arrival and departure are within those ranges.所以最小值和最大值真正告诉你的是,只要到达和离开在这些范围内,解决方案是可行的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何绘制谷歌或工具车辆路线问题解决方案? - How to graph Google OR Tools Vehicle Routing Problem Solution? 不同车速的车辆路线(谷歌或工具) - Vehicle Routing with Different Vehicle Speed (Google OR Tools) 使用 Google OR 工具解决车辆路径问题 (CVRPTW) 所需的时间取决于车辆容量的排序 - Time taken to solve a Vehicle Routing Problem (CVRPTW) using Google OR Tools depends on the ordering of vehicle capacity 在 Or 工具中设置距离维度以解决车辆路径问题 - Setting distance Dimension in Or tools for vehicle routing problem 如何使用 or-tools 在车辆路径问题中仅让部分行程返回车辆段? - How to make only some tours return to depot in vehicle routing problem with or-tools? 如何让 Google OR 工具部署更多车辆 - How to make Google OR Tools Deploy More Vehicle 更改目标 Function 以解决 Google ortools 中的车辆路径问题 - Change Objective Function for Vehicle Routing Problem in Google's ortools 车辆路线问题 - 如何完成/确定何时访问某些位置? - Vehicle Routing Problem - How to finish/determine when certain locations are visited? 如何使用 or-tools 和 google-distance matrix 创建车辆路线优化问题,同时仅取消终点位置? - How to create a vehicle route optimization problem using or-tools and google-distance matrix while nullifying the end location only? Or-tools带有中断的Python车辆路由问题 - Or-tools Python Vehicle Routing Prob with Breaks
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM