当前位置: 首页 > 知识库问答 >
问题:

OR-无约束VRP工具错误分组

海雪松
2023-03-14

我正在使用或工具解决VRP没有任何约束。以下是源代码:

def create_data_model():
    """Stores the data for the problem."""
    data = {}
    data['distance_matrix'] = [
        [0, 20079, 2613, 8005, 19277, 12468, 13701],
        [0, 0, 21285, 16012, 32574, 35394, 28806],
        [0, 18233, 0, 5392, 19965, 19650, 13064],
        [0, 15013, 5639, 0, 22883, 22570, 15982],
        [0, 32991, 19256, 21815, 0, 18414, 9112],
        [0, 34348, 16976, 23122, 15678, 0, 14647],
        [0, 27652, 13917, 16476, 8043, 14820, 0]
    ]
    data['time_matrix'] = [
        [0, 1955, 508, 1331, 1474, 1427, 1292],
        [0, 0, 1795, 1608, 2057, 2410, 2036],
        [0, 1485, 0, 823, 1370, 1541, 1100],
        [0, 1402, 924, 0, 1533, 1637, 1263],
        [0, 2308, 1663, 1853, 0, 1766, 1104],
        [0, 2231, 1373, 1660, 1441, 0, 1554],
        [0, 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,
        0,  # 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, manager, routing, solution)

    return HttpResponse('')
    null

上面代码的结果如下所示:

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

为了验证上面的输出,我在google地图中标记了点。其编号顺序与距离矩阵的顺序相同。

地图上的库

很明显,从Watthana出发,最便宜的路线应该是2-1-3次。但Google OR将其返回为两次旅行(如车辆0和3的路线)。这也可以通过手动添加距离来验证。

从家到2到1到3=2613+5392+15013=23018m

0和3号车辆的DIS=20079+8005=28084M

我做错了什么?我怎样才能让谷歌不分离出第一点?同样请注意,理想情况下点E,F,D也可以被分组,但它们不是。

提前感谢!

共有1个答案

应和光
2023-03-14

从问题来看,我认为你想要的是减少所有车辆的累计行驶距离。

    distance_dimension.SetGlobalSpanCostCoefficient(35394)

相反,该代码通过在以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
 类似资料:
  • 我想为VRP创建一个过度约束规划的增量分数。我创建了一个传统的虚拟车辆,其中包括所有计划外的客户。 示例: Optaplanner将Customer1从Vehicle1移动到Vehicle2: 当我得到AfterVariableChanged:previousStandstill(Customer1)时,在Customer.getVehicle()中,我有旧车辆的价值,我不知道是否需要添加软成本(

  • 问题内容: 在MySQL中创建非NULL约束以使fieldA和fieldB不能都为NULL的最佳方法是什么。我不在乎任何一个本身是否为NULL,只要另一个字段具有非NULL值即可。而且,如果它们都具有非NULL值,那就更好了。 问题答案: MySQL 5.5引入了SIGNAL,因此我们不再需要Bill Karwin的答案中的额外列。Bill指出您还需要一个更新触发器,因此我也将其包括在内。

  • 我有两张桌子。第一个是人口;第二个是空的。 我希望第二个有一个外键,它引用第一个中的一列。 null 架构: 填充。为空。 不能成为的外键: MySQL没有提供错误的原因;不返回: 我拥有所需的数据库权限。 我已经仔细检查了列(甚至表)是否具有相同的排序规则(字符集不适用于INT列): MySQL无法添加外键约束 MySQL:错误1215(HY000):无法添加外键约束 无法添加外键约束-MySQ

  • 我正在将错误消息添加到登录屏幕。 虽然代码运行良好,并且执行我希望它执行的操作。它会在执行时导致约束错误。 以下是受影响的约束: 下面是导致errorView出现的函数。 如何在不破坏约束的情况下更改约束? 我尝试self.view.update约束()-但是什么也没有做。我还尝试在添加约束之前删除它们,但是仍然有一个错误。 任何帮助都将不胜感激! 编辑: 我找到了一个Objective-c解决方

  • 我是新的Cognito。我试图使用Lambda实现AWS Cognito。这是我正在遵循的教程。 这是我在setIdtyPoolId中使用的池ID 这是JUnit测试 这是输出 但是我得到以下错误,因此,语句失败

  • 问题内容: 我发现了有关该错误的一些线索。但是所有解决方案都不适合我。 我为用户表创建了2个表,为文章创建了1个表。现在,我要存储创建文章的用户和最后一个修饰符的用户。 我收到以下错误,但我不明白为什么要为此添加索引。 错误代码:1822。无法添加外键约束。引用表“ users”中约束“ fk_articles_users1”的缺少索引 我活跃 但这不会显示任何错误。 问题答案: 不能引用,因为出

  • 问题内容: 我正在尝试将新模式转发工程到我的数据库服务器上,但是我不知道为什么会收到此错误。我试图在这里搜索答案,但是我发现的所有内容都说是将db引擎设置为Innodb或确保要用作外键的键是它们自己表中的主键。如果我没记错的话,我都做过这两件事。你们还有其他帮助吗? SQL脚本执行完成:语句:成功7次​​,失败1次 这是父表的SQL。 问题答案: 我猜,和/或不完全相同的数据类型和。 也许父表中的

  • 引用的表是“组”(InnoDB)。 它有一个“id”列,定义为INT(11),不可为空,自动递增,主键 引用表为“用户(InnoDB)” 它的group_id列定义为INT(11),不可为空。 在引用表中已经存在一个基于“group_id”列的唯一索引 但是whn正在执行 我出错了 错误:1215无法添加外键约束 我添加db转储 检查清单 Db是InnoDB吗?是的 所有表都是InnoDB吗?是的