OR-Tools VRP:限制要由同一车辆提供服务的位置

时间:2019-12-28 07:16:30

标签: modeling or-tools vehicle-routing

我想限制同一辆车要服务的位置。 我使用了容量限制来实现这一目标。假设我们有l = [[1,2], [3,4]],这意味着位置1、2必须由同一辆车服务,而位置3、4也必须。所以1、2以route_1结尾,而3、4以route_2

结尾

我实现此目的的代码是:

for idx, route_constraint in enumerate(l):
    vehicle_capacities = [0] * NUM_VEHICLES
    vehicle_capacities[idx] = len(route_constraint)
    route_dimension_name = 'Same_Route_' + str(idx)

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

    same_routes_callback_index = routing.RegisterUnaryTransitCallback(callback)

    routing.AddDimensionWithVehicleCapacity(
        same_routes_callback_index,
        0,  # null capacity slack
        vehicle_capacities,  # vehicle maximum capacities
        True,  # start cumul to zero
        route_dimension_name)

这个想法是1,2具有每个1个单位的容量需求(所有其他单位为零)。由于只有车辆1的容量为2,因此它是唯一能够提供1,2的车辆。

如果len(l)== 1,这似乎很好用。如果更大,但即使我在没有上述代码的情况下将l对位于同一路线上的成对位置放进去,求解器也无法找到解决方案(因此,如果没有,以上容量限制。

  1. 是否有更优雅的方式来建模我的需求?
  2. 为什么求解器无法找到解决方案?

我还考虑了放弃访问的可能性(高昂的代价),从而使求解器有可能从放弃访问的解决方案开始,从而使他可以从这一点找到解决方法,而不会产生任何下降。我没有运气。

谢谢。

1 个答案:

答案 0 :(得分:0)

每个站点都有一个车辆变量,其值确定了允许哪个车辆访问站点。如果要让车辆0为第1和第2站点服务,请在每个站点的车辆变量上使用成员约束,并将其设置为[0]。由于您可能还有其他一些限制条件,这些限制条件使止动站成为可选操作,因此请将值-1添加到列表中。这是一个特殊的值,表示车辆不对停车站进行维修。

在Python中:

n2x = index_manager.NodeToIndex
cpsolver = routing_model.solver()

for stop in [1,2]:
    vehicle_var = routing_model.VehicleVar(n2x(stop))
    values = [-1, 0]
    cpsolver.Add(cpsolver.MemberCt(vehicle_var, values))