You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OR-Tools求解车辆路径规划(VRP)返回错误0距离结果问题求助

车辆路径规划(VRP)结果总距离显示为0的问题排查与解决

问题现象

使用首行首列设为0的距离矩阵运行OR-Tools VRP代码后,出现车辆遍历所有地点总距离为0的错误结果,调整车辆最大行驶距离和全局跨度成本系数后异常仍存在。

问题代码

def create_data_model():
    """Stores the data for the problem."""
    data = {}
    data["distance_matrix"] = [[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
                                [0.0, 0.0, 14.0, 201.0, 154.0, 154.0],
                                [0.0, 46.0, 0.0, 165.0, 118.0, 118.0],
                                [0.0, 70.0, 54.0, 0.0, 110.0, 110.0],
                                [0.0, 24.0, 26.0, 187.0, 0.0, 140.0],
                                [0.0, 28.0, 0.0, 199.0, 152.0, 0.0]]
    data["num_vehicles"] = 3
    data["depot"] = 0
    return data

def print_solution(data, manager, routing, solution):
    """Prints solution on console."""
    print(f"Objective: {solution.ObjectiveValue()}")
    max_route_distance = 0
    for vehicle_id in range(data["num_vehicles"]):
        index = routing.Start(vehicle_id)
        plan_output = f"Route for vehicle {vehicle_id}:\n"
        route_distance = 0
        while not routing.IsEnd(index):
            plan_output += f" {manager.IndexToNode(index)} -> "
            previous_index = index
            index = solution.Value(routing.NextVar(index))
            route_distance += routing.GetArcCostForVehicle(
                previous_index, index, vehicle_id
            )
        plan_output += f"{manager.IndexToNode(index)}\n"
        plan_output += f"Distance of the route: {route_distance}m\n"
        print(plan_output)
        max_route_distance = max(route_distance, max_route_distance)
    print(f"Maximum of the route distances: {max_route_distance}m")

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["distance_matrix"]), data["num_vehicles"], data["depot"]
    )

    # 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]

    transit_callback_index = routing.RegisterTransitCallback(distance_callback)

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

    # Add Distance constraint.
    dimension_name = "Distance"
    routing.AddDimension(
        transit_callback_index,
        0,  # no slack
        5000,  # vehicle maximum travel distance
        True,  # start cumul to zero
        dimension_name,
    )
    distance_dimension = routing.GetDimensionOrDie(dimension_name)
    distance_dimension.SetGlobalSpanCostCoefficient(100)

    # 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, manager, routing, solution)
    else:
        print("No solution found !")

错误输出

Objective: 0
Route for vehicle 0:
 0 -> 0
Distance of the route: 0m

Route for vehicle 1:
 0 -> 0
Distance of the route: 0m

Route for vehicle 2:
 0 ->  5 ->  4 ->  3 ->  2 ->  1 -> 0
Distance of the route: 0m

Maximum of the route distances: 0m

错误原因

OR-Tools的Routing模块默认使用整数类型处理成本/距离值,当传入浮点数时,会被自动截断为整数。你的距离矩阵中所有值都是带.0的浮点数,被截断后全部变成0,导致所有路径的成本计算为0,最终出现异常结果。

首行首列设为0的操作本身没有问题,问题核心在于浮点数与OR-Tools整数成本机制不兼容。

解决方法

将距离矩阵中的浮点数改为整数,或者在距离回调函数中将浮点数转换为整数,确保传入OR-Tools的成本值为整数类型。

修正后的代码示例

修改create_data_model函数中的distance_matrix,去掉.0使用整数:

def create_data_model():
    """Stores the data for the problem."""
    data = {}
    data["distance_matrix"] = [[0, 0, 0, 0, 0, 0],
                                [0, 0, 14, 201, 154, 154],
                                [0, 46, 0, 165, 118, 118],
                                [0, 70, 54, 0, 110, 110],
                                [0, 24, 26, 187, 0, 140],
                                [0, 28, 0, 199, 152, 0]]
    data["num_vehicles"] = 3
    data["depot"] = 0
    return data

或者如果需要保留浮点数计算,在回调函数中转换为整数(比如乘以100保留两位小数后转整,根据需求调整):

def distance_callback(from_index, to_index):
    """Returns the distance between the two nodes."""
    from_node = manager.IndexToNode(from_index)
    to_node = manager.IndexToNode(to_index)
    # 转换为整数,这里直接取整,可根据精度需求调整
    return int(data["distance_matrix"][from_node][to_node])

修正后效果

运行修正后的代码,系统会正确计算路径距离,输出的路由距离不再为0,Objective值也会对应实际的路径成本总和。

内容的提问来源于stack exchange,提问作者Charles T

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 04:02:02