将不同组节点中每种类型节点的访问节点数限制为 or-tools for CVRP 中的预定义值

问题描述 投票:0回答:1

我已经为容量车辆路径问题实施或工具(python)并且它正在运行。我心里只有另一个目标:我想建立一个回调函数,给每条路由一个上限,在给定不同的节点集合的情况下,访问某组节点中的各种类型的节点。 我有这些参数集:

% 我们有两组节点 组 = [0,1]

% 组 0 具有类型 0、1、2 的节点,组 1 具有类型 3 和 4 的节点。 节点类型 = [[0,1,2], [3,4]]

% 我有 9 个节点,每种类型是: 节点类型 = [0, 0,2,2,1,3,3,3,4] % 每个节点属于一个组 node_group_type = [0,0,0,0,0,1,1,1,1]

% 来自第 0 组,我应该有最多 2 种不同类型,而来自第 1 组,我最多可以有 1 种类型的节点。 max_visits_per_type_group = [2, 1]

visits_per_type = [0 for _ in range(len(max_visits_per_type))]

所以我的车辆可以包含 0,2,0,2,3,3 或 2,1,4,或 2,3,1,3,3 但它不能包含 2,1,3,4,因为来自第 1 组我们有两种不同的类型,如 3 和 4。

我把回调函数写成:

# Define your callback function to be called after each feasible solution is found
def limit_node_visits(from_index, to_index):
    from_node = manager.IndexToNode[from_index]
    to_node = manager.IndexToNode[to_index]
    
    from_node_type_group = node_group_type[from_node]
    to_node_type_group = node_group_type[to_node]
     
    from_node_type = node_type[from_node]
    to_node_typ = node_type[to_node]
   

    if (from_node_type == to_node_type):
        return 0  # No cost for same type nodes

    elif visits_per_type[from_node_type] >= max_visits_per_type[from_node_type]:
        return routing.solver().InfeasibleCost()  # Prevent further exploration of this solution
    else:
        visits_per_type[from_node_type_group] += 1
        return 1  # Increment the visit count for the from_node_type

limit_node_visits_index = routing.RegisterUnaryTransitCallback(limit_node_visits)
routing.AddDimensionWithVehicleCapacity(
                                        limit_node_visits_index,
                                         0,
                                         max_visits_per_type_group,
                                         True,
                                         'node_visit') 

但是,代码不起作用并且崩溃了。 routing.AddDimensionWithVehicleCapacity() 函数中的 max_visits_per_type_group 似乎有问题。我不确定我是否也正确定义了 call_back 函数。如果你能帮我把这两个函数写好,我将不胜感激。

python-3.7 or-tools vehicle-routing
1个回答
0
投票

将此视为容量限制可能会奏效。

data['vehicle_capacities'] = [[2, 2, 2], [1, 1, 1]] # Assuming 3 vehicles 

def group_zero_callback(from_index):
    from_node = manager.IndexToNode(from_index)
    return 1 if from_node in group_zero else 0

callback_index = routing.RegisterUnaryTransitCallback(group_zero_callback)
routing.AddDimensionWithVehicleCapacity(
    callback_index,
    0,  # null capacity slack
    data['vehicle_capacities'][0],  # Group 0 should have max 2 different types
    'group_zero')
© www.soinside.com 2019 - 2024. All rights reserved.