OR-工具路由约束,比较需求和容量

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

目前正在解决路由问题,我们的运输有一个特定的条件 - 它不能半满行驶(输送危险液体),所以基本上在访问第一个节点后它应该是空的或几乎是空的。我如何添加这样一个约束,可以比较节点的需求和卡车的容量,我见过的所有约束都只适用于车辆容量?

我们有多个迭代生成的容量限制,因为卡车可以运送多种类型的液体。不过,我真的不知道如何添加新的约束。

按类型划分的需求是不同需求的列表

按类型划分的容量也是每辆车的列表

    def demand_callback(type):
        def callback(from_index):
            from_node = manager.IndexToNode(from_index)
            return data["demands_by_types"][type][from_node]

        return callback

    for type in range(len(data["demands_by_types"])):  #
        routing.AddDimensionWithVehicleCapacity(
            routing.RegisterUnaryTransitCallback(demand_callback(type)),
            0,  # null capacity slack
            data["capacities_by_type"][type],  # vehicle maximum capacities
            True,  # start cumul to zero
            f'Capacity_type_{type}'
        )
python routes constraints or-tools
1个回答
0
投票

为了确保车辆在访问第一个节点后是空的或几乎是空的,您可以创建自定义约束。逻辑应将第一个节点的需求与车辆的容量进行比较。考虑到您的问题具有多种类型的液体和迭代容量限制的复杂性,实现此类约束可能需要采取细致入微的方法。

这是在当前设置中引入此类约束的潜在方法:

创建一个新的回调来计算剩余容量:

此回调可设计为在访问每种液体的第一个节点后计算车辆的剩余容量。

def remaining_capacity_callback(type):
    def callback(from_index, to_index):
        from_node = manager.IndexToNode(from_index)
        to_node = manager.IndexToNode(to_index)
        if to_node == 1:  # Assuming node 1 is the first node to be visited
            remaining_capacity = data["capacities_by_type"][type] - data["demands_by_types"][type][from_node]
            return remaining_capacity
        return 0  # return 0 for other nodes, or handle other cases as needed
    return callback
    

注册此回调并添加新维度:

for type in range(len(data["demands_by_types"])):
    remaining_capacity_callback_index = routing.RegisterTransitCallback(
        remaining_capacity_callback(type)
    )
    routing.AddDimension(
        remaining_capacity_callback_index,
        0,  # null capacity slack
        data["capacities_by_type"][type],  # vehicle maximum capacities
        True,  # start cumul to zero
        f'Remaining_Capacity_type_{type}'
    )

在新维度上添加约束:

您现在可以添加约束以确保第一个节点之后的剩余容量为零或接近于零。

remaining_capacity_dimension = routing.GetDimensionOrDie(f'Remaining_Capacity_type_{type}')
for vehicle_id in range(data['num_vehicles']):
    first_node_index = routing.Start(vehicle_id)
    routing.solver().Add(
        remaining_capacity_dimension.CumulVar(first_node_index) <= threshold  # your defined threshold
    )

在上面的代码片段中:

定义了一个新的回调remaining_capacity_callback,用于计算访问第一个节点后的剩余容量。 此回调已注册,并且新维度 Remaining_Capacity_type_{type} 已添加到路由模型中。 添加约束以确保第一个节点的剩余容量低于某个阈值。 这应该确保根据您的要求,在访问第一个节点后车辆是空的或几乎是空的。请根据需要调整逻辑,以匹配您的路由问题的确切行为和结构

© www.soinside.com 2019 - 2024. All rights reserved.