简体   繁体   English

不同起点站和终点站时间窗的车辆路径问题

[英]Vehicle routing problem with time windows at different start and end depot

I am trying to write a trip planner for which I am using Google's ORtools.我正在尝试编写一个旅行计划,我正在使用 Google 的 ORtools。 The problem that I am trying to solve is that each vehicle has a different start and end depot and all the services have a different start and end time.我试图解决的问题是每辆车都有不同的起点和终点站,所有的服务都有不同的起点和终点时间。 Even the depots have a different start and end time, which need to be added as a constraint.即使是 depot 也有不同的开始和结束时间,需要将其添加为约束。 I have been following there two examples from google's documentation:我一直在关注谷歌文档中的两个例子:

I have scoured through all of documentations that are available for ortools, but have not been able to find a reason as to why this error is occurring.我已经浏览了所有可用于 ortools 的文档,但无法找到发生此错误的原因。 According to the documentation, what I am trying to do is possible and the code that I have written should give a correct result.根据文档,我正在尝试做的事情是可能的,并且我编写的代码应该给出正确的结果。

Here is a sample code of what I am doing:这是我正在做的示例代码:

"""Simple Vehicles Routing Problem."""

from __future__ import print_function
from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp


def create_data_model():
    """Stores the data for the problem."""
    data = {}
    data['time_matrix'] = [
        [0, 6, 7, 9, 7, 3, 6, 2, 3, 2, 6, 6, 4, 4, 5, 9, 7, 0],
        [6, 0, 8, 3, 2, 6, 8, 4, 8, 8, 13, 7, 5, 8, 12, 12, 14, 6],
        [7, 8, 0, 11, 10, 6, 3, 9, 5, 8, 4, 15, 14, 13, 9, 18, 9, 15],
        [9, 3, 11, 0, 3, 7, 10, 6, 10, 10, 14, 6, 7, 9, 14, 6, 16, 14],
        [7, 2, 10, 3, 0, 6, 9, 4, 8, 9, 13, 4, 6, 8, 12, 8, 14, 9],
        [3, 6, 6, 7, 6, 0, 2, 8, 2, 2, 7, 9, 7, 7, 6, 12, 8, 3],
        [6, 8, 3, 10, 9, 2, 0, 6, 2, 5, 4, 12, 10, 10, 6, 11, 5, 10],
        [2, 4, 9, 6, 4, 8, 6, 0, 4, 4, 8, 5, 4, 13, 7, 8, 10, 12],
        [3, 8, 5, 10, 8, 2, 2, 4, 0, 3, 4, 9, 8, 7, 3, 13, 6, 5],
        [2, 8, 8, 10, 9, 2, 5, 4, 3, 0, 4, 6, 5, 4, 3, 9, 5, 8],
        [6, 13, 4, 14, 13, 7, 4, 8, 4, 4, 0, 10, 9, 8, 4, 13, 4, 9],
        [6, 7, 15, 6, 4, 9, 12, 5, 9, 6, 10, 0, 1, 3, 7, 13, 10, 11],
        [4, 5, 14, 7, 6, 7, 10, 4, 8, 5, 9, 1, 0, 2, 16, 4, 8, 1],
        [4, 8, 13, 9, 8, 7, 10, 13, 7, 4, 8, 3, 2, 0, 4, 5, 6, 2],
        [5, 12, 9, 14, 12, 6, 6, 7, 3, 3, 4, 7, 16, 4, 0, 9, 12, 4],
        [9, 12, 18, 6, 8, 12, 11, 8, 13, 9, 13, 13, 4, 5, 9, 0, 9, 10],
        [7, 14, 9, 16, 14, 8, 5, 10, 6, 5, 4, 10, 8, 6, 12, 9, 0, 13],
        [0, 6, 15, 14, 9, 3, 10, 12, 5, 8, 9, 11, 1, 2, 4, 10, 13, 0]
    ]
    data['time_windows'] = [
        (0, 22),  # depot
        (7, 12),  # 1
        (10, 15),  # 2
        (6, 8),  # 3
        (10, 13),  # 4
        (0, 5),  # 5
        (5, 10),  # 6
        (0, 4),  # 7
        (5, 7),  # 8
        (0, 3),  # 9
        (10, 16),  # 10
        (10, 15),  # 11
        (0, 9),  # 12
        (5, 10),  # 13
        (7, 10),  # 14
        (10, 15),  # 15
        (11, 15),  # 16
        (18, 25)  # 17
    ]
    data['num_days'] = 3
    data['start'] = [0,0,0]#, 0, 0, 0]  # ,17,0,17]
    data['end'] = [17,17,17]#, 17, 17, 17]
    return data

def print_solution(data, manager, routing, assignment):
    # prints the final routing solution on the console
    time_dimension = routing.GetDimensionOrDie('Time')
    total_time = 0
    for vehicle_id in range(data['num_days']):
        index = routing.Start(vehicle_id)
        plan_output = 'Route for vehicle {}:\n'.format(vehicle_id)
        while not routing.IsEnd(index):
            time_var = time_dimension.CumulVar(index)
            plan_output += '{0} Time({1},{2}) -> '.format(
                manager.IndexToNode(index), assignment.Min(time_var),
                assignment.Max(time_var))
            index = assignment.Value(routing.NextVar(index))
        time_var = time_dimension.CumulVar(index)
        plan_output += '{0} Time({1},{2})\n'.format(
            manager.IndexToNode(index), assignment.Min(time_var),
            assignment.Max(time_var))
        plan_output += 'Time of the route: {}min\n'.format(
            assignment.Min(time_var))
        print(plan_output)
        total_time += assignment.Min(time_var)
    print('Total time of all routes: {}min'.format(total_time))


def main():
    """Entry point of the program."""
    # Instantiate the data problem.
    data = create_data_model()

    # Create the routing index manager.
    manager = pywrapcp.RoutingIndexManager(len(data['time_matrix']), data['num_days'], data['start'], data['end'])

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


    # Create and register a transit callback.
    def time_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['time_matrix'][from_node][to_node]

    transit_callback_index = routing.RegisterTransitCallback(time_callback)

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

    # Add time constraint.
    dimension_name = 'time'
    routing.AddDimension(
        transit_callback_index,
        30,  # no slack
        1000000000,  # vehicle maximum travel distance
        False,  # start cumul to zero
        dimension_name)
    time_dimension = routing.GetDimensionOrDie(dimension_name)
    # add time window constraints
    for location_idx, time_window in enumerate(data['time_windows']):
        if location_idx == 17 or 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.
    for vehicle_id in range(data['num_days']):
        index = routing.Start(vehicle_id)
        end_index = routing.End(vehicle_id)
        print(end_index)
        time_dimension.CumulVar(index).SetRange(data['time_windows'][0][0],
                                                data['time_windows'][0][1])
        time_dimension.CumulVar(end_index).SetRange(data['time_windows'][17][0],
                                                    data['time_windows'][17][1])

    for i in range(data['num_days']):
        routing.AddVariableMinimizedByFinalizer(time_dimension.CumulVar(routing.Start(i)))
        routing.AddVariableMinimizedByFinalizer(time_dimension.CumulVar(routing.End(i)))

    time_dimension.SetSpanCostCoefficientForAllVehicles(200)

    # 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)
    # Print solution on console.
    if solution:
        print_solution(data, manager, routing, solution)


if __name__ == '__main__':
    main()

Every time I run the code for more than 2 vehicles this is the error that I am getting:每次我为超过 2 辆车运行代码时,这就是我得到的错误:

RuntimeError: SWIG std::function invocation failed.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/travelapp/PycharmProjects/TravelApp/venv/lib/python3.7/site-packages/ortools/constraint_solver/pywrapcp.py", line 2136, in <lambda>
    __setattr__ = lambda self, name, value: _swig_setattr(self, Assignment, name, value)
  File "/Users/travelapp/PycharmProjects/TravelApp/venv/lib/python3.7/site-packages/ortools/constraint_solver/pywrapcp.py", line 71, in _swig_setattr
    return _swig_setattr_nondynamic(self, class_type, name, value, 0)
  File "/Users/travelapp/PycharmProjects/TravelApp/venv/lib/python3.7/site-packages/ortools/constraint_solver/pywrapcp.py", line 55, in _swig_setattr_nondynamic
    if type(value).__name__ == 'SwigPyObject':
SystemError: <class 'type'> returned a result with an error set

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/travelapp/Library/Preferences/PyCharmCE2019.1/scratches/scratch.py", line 150, in <module>
    main()
  File "/Users/travelapp/Library/Preferences/PyCharmCE2019.1/scratches/scratch.py", line 142, in main
    solution = routing.SolveWithParameters(search_parameters)
  File "/Users/travelapp/PycharmProjects/TravelApp/venv/lib/python3.7/site-packages/ortools/constraint_solver/pywrapcp.py", line 3464, in SolveWithParameters
    return _pywrapcp.RoutingModel_SolveWithParameters(self, search_parameters, solutions)
SystemError: <built-in function RoutingModel_SolveWithParameters> returned a result with an error set

For 1 or 2 vehicles I am getting None as the solution.对于 1 或 2 辆车,我得到None作为解决方案。 This may be due to infeasibility of a trip for 2 vehicles.这可能是由于 2 辆车的行程不可行。

For each vehicle create one dummy node for the start, and one for the end, then restrict the vehicle var of these nodes to the vehicle.对于每辆车,为开始创建一个虚拟节点,为结束创建一个虚拟节点,然后将这些节点的车辆变量限制为车辆。 make these nodes optional.使这些节点可选。

Now tweak the distance matrix such that there are no arcs between the depot and any nodes.现在调整距离矩阵,使得仓库和任何节点之间没有弧线。 There are only arcs from the depot to the dummy start nodes, and from the dummy end nodes to the depot.只有从仓库到虚拟起始节点,以及从虚拟结束节点到仓库的弧。

Now, it should be easy to add time constraints on these dummy nodes.现在,应该很容易在这些虚拟节点上添加时间限制。

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

相关问题 时间窗口崩溃的有能力车辆路线问题 - Capacitated Vehicle Routing Problem with Time Windows crashing 如何使用 or-tools 在车辆路径问题中仅让部分行程返回车辆段? - How to make only some tours return to depot in vehicle routing problem with 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 不同车速的车辆路线(谷歌或工具) - Vehicle Routing with Different Vehicle Speed (Google OR Tools) 为每辆车设置不同的时间 windows 和掉落惩罚 [or-tools] - Set different time windows and dropping penalties for each vehicle [or-tools] 如何将服务时间约束添加到具有时间窗口约束的车辆路径问题 - How to add a servicing time constraint to a vehicle routing problem with time window constraints 在 Or 工具中设置距离维度以解决车辆路径问题 - Setting distance Dimension in Or tools for vehicle routing problem 带时间窗的车辆路线选择Python实现 - Vehicle routing with time window Implementation in Python 获取 pandas 中不同时期的开始和结束时间 - Get start and end time for different periods in pandas 车辆路线问题 - 如何完成/确定何时访问某些位置? - Vehicle Routing Problem - How to finish/determine when certain locations are visited?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM