Python OR-tools 使用开始和终结点设置初始路由将生成 None



>我有一个路由问题,我正在使用谷歌OR工具解决。它运行良好,我一直在尝试调整我的代码以满足开始和结束位置。

问题是当我设置它时,routing.ReadAssignmentFromRoutes产生None,下面是 用于重现场景的代码快照:

from ortools.constraint_solver import pywrapcp
import pandas as pd
# Please excuse the long code here to make a data example
cost_df = pd.DataFrame({"A0000": {"A0000": 0.0, "A0001": 540.0, "C1621": 401.0, "C1725": 462.0, "C1918": 337.0, "C3413": 230.0, "C3722": 402.0, "C3814": 257.0, "C3827": 493.0, "C4029": 534.0, "C4408": 188.0, "C4429": 545.0}, "A0001": {"A0000": 540.0, "A0001": 0.0, "C1621": 236.0, "C1725": 168.0, "C1918": 256.0, "C3413": 312.0, "C3722": 161.0, "C3814": 298.0, "C3827": 92.0, "C4029": 100.0, "C4408": 417.0, "C4429": 141.0}, "C1621": {"A0000": 401.0, "A0001": 236.0, "C1621": 0.0, "C1725": 78.0, "C1918": 66.0, "C3413": 229.0, "C3722": 234.0, "C3814": 255.0, "C3827": 265.0, "C4029": 304.0, "C4408": 362.0, "C4429": 341.0}, "C1725": {"A0000": 462.0, "A0001": 168.0, "C1621": 151.0, "C1725": 0.0, "C1918": 201.0, "C3413": 338.0, "C3722": 286.0, "C3814": 351.0, "C3827": 290.0, "C4029": 322.0, "C4408": 469.0, "C4429": 363.0}, "C1918": {"A0000": 337.0, "A0001": 256.0, "C1621": 103.0, "C1725": 165.0, "C1918": 0.0, "C3413": 204.0, "C3722": 246.0, "C3814": 234.0, "C3827": 299.0, "C4029": 342.0, "C4408": 336.0, "C4429": 374.0}, "C3413": {"A0000": 230.0, "A0001": 312.0, "C1621": 266.0, "C1725": 302.0, "C1918": 204.0, "C3413": 0.0, "C3722": 211.0, "C3814": 84.0, "C3827": 301.0, "C4029": 343.0, "C4408": 170.0, "C4429": 357.0}, "C3722": {"A0000": 402.0, "A0001": 161.0, "C1621": 252.0, "C1725": 231.0, "C1918": 227.0, "C3413": 192.0, "C3722": 0.0, "C3814": 147.0, "C3827": 92.0, "C4029": 150.0, "C4408": 277.0, "C4429": 166.0}, "C3814": {"A0000": 257.0, "A0001": 298.0, "C1621": 310.0, "C1725": 333.0, "C1918": 252.0, "C3413": 102.0, "C3722": 147.0, "C3814": 0.0, "C3827": 238.0, "C4029": 333.0, "C4408": 177.0, "C4429": 343.0}, "C3827": {"A0000": 493.0, "A0001": 92.0, "C1621": 320.0, "C1725": 272.0, "C1918": 317.0, "C3413": 319.0, "C3722": 92.0, "C3814": 238.0, "C3827": 0.0, "C4029": 99.0, "C4408": 403.0, "C4429": 131.0}, "C4029": {"A0000": 534.0, "A0001": 100.0, "C1621": 322.0, "C1725": 267.0, "C1918": 323.0, "C3413": 324.0, "C3722": 150.0, "C3814": 296.0, "C3827": 62.0, "C4029": 0.0, "C4408": 401.0, "C4429": 60.0}, "C4408": {"A0000": 188.0, "A0001": 417.0, "C1621": 399.0, "C1725": 433.0, "C1918": 336.0, "C3413": 170.0, "C3722": 296.0, "C3814": 159.0, "C3827": 385.0, "C4029": 420.0, "C4408": 0.0, "C4429": 385.0}, "C4429": {"A0000": 545.0, "A0001": 141.0, "C1621": 359.0, "C1725": 308.0, "C1918": 355.0, "C3413": 338.0, "C3722": 166.0, "C3814": 306.0, "C3827": 94.0, "C4029": 60.0, "C4408": 385.0, "C4429": 0.0}})
def create_data_model():
    """Stores the data for the problem."""
    data = {}
    data['distance_matrix'] = cost_df.values.tolist()
    data['initial_routes'] = [
        [4, 3, 2, 5, 7, 6, 8, 9, 10, 11] # Note, I do not include the start and end here
    ]
    data['num_vehicles'] = 1
    data['starts'] = [0] # This corresponds to the 0 index of distance_matrix: A0000
    data['ends'] = [1] # This corresponds to the 1 index of distance_matrix: A0001
    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: {}mn'.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))
# Instantiate the data problem
data = create_data_model()
# Create the routing index manager
manager = pywrapcp.RoutingIndexManager(
    len(data['distance_matrix']),
    data['num_vehicles'],
    data['starts'],
    data['ends']
)
# Create Routing Model
routing = pywrapcp.RoutingModel(manager)
# Create and register a transit callback
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]
# Define cost of each arc
transit_callback_index = routing.RegisterTransitCallback(distance_callback)
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
initial_solution = routing.ReadAssignmentFromRoutes(data['initial_routes'], True)
initial_solution is None # True
#Commented code, will yield AttributeError: 'NoneType' object has no attribute 'Value'
#print_solution(data, manager, routing, initial_solution)

我正在使用:

  • 蟒蛇 3.6
  • ORTOOLS 7.3.7083

感谢任何帮助

运行您的代码时收到警告

E1122 17:32:44.085536  7503 routing.cc:3444] Invalid index: 11

我认为您可能在create_data_model函数中使用 1 索引而不是 0 索引来获取数据['initial_routes']。将 11 替换为 1,如

data['initial_routes'] = [
        [1, 4, 3, 2, 5, 7, 6, 8, 9, 10]  # Note, I do not include the start and end here
    ]

我得到输出

Route for vehicle 0:
 0 ->  2 ->  5 ->  4 ->  3 ->  6 ->  8 ->  7 ->  9 ->  10 ->  11 -> 1
Distance of the route: 2875m
Maximum of the route distances: 2875m

这更有意义吗?

最新更新