繁体   English   中英

如何在Google Or-Tools中限制路线持续时间?

[英]How to limit route duration in Google Or-Tools?

我正在研究路线优化问题,但发现自己陷入了僵局。 我使用or-tools作为.Net核心的求解器。

问题如下:当我处理时间窗口约束时,可能会发生一些等待以适应某个位置时间窗口的情况。 这很好。 求解器倾向于将时间窗口受约束的位置用作第一节点。 也可以 但是这样一来,我们可能希望将车辆的出发日期放一些完美的延迟。 因此,当我将路线持续时间限制设置为8小时,并且开始时有2小时的等待时间时,结果是要花6个小时才能完成,这并不是最佳选择。 我无法弄清楚如何通知求解器第一个节点的等待时间正在增加总持续时间。

这是文档链接: https : //developers.google.com/optimization/routing/vrp

//这是我的时间维度

        _routingModel.AddDimension(
            evaluator_index: _absoluteTimeCallbackIndex,
            slack_max: (long)TimeSpan.FromDays(1).TotalSeconds,
            capacity: (long)TimeSpan.FromDays(1).TotalSeconds,
            fix_start_cumul_to_zero: true,
            name: PlannerConstants.TIME_DIMENSION_NAME);

//这一段代码正在设置时间窗口和持续时间约束

        var timeDimension = _routingModel.GetDimensionOrDie(PlannerConstants.TIME_DIMENSION_NAME);

        for (int locationNodeIndex = 0; locationNodeIndex < _targets.Count; locationNodeIndex++)
        {
            var location = _targets[locationNodeIndex].Location;
            var index = _manager.NodeToIndex(locationNodeIndex);

            var timeWindowMatch = new TimeWindowMatcher(_departureDate, location.TimeSlots.ToList())
                .GetTimeWindowsWithGaps();

            var start = (long)timeWindowMatch.WideTimeRange.From.TotalSeconds;
            var end = (long)timeWindowMatch.WideTimeRange.To.TotalSeconds;

            timeDimension
                .CumulVar(index)
                .SetRange(start, end);

            timeWindowMatch.TimeGaps.ForEach(gap =>
            {
                timeDimension
                    .CumulVar(index)
                    .RemoveInterval((long)gap.From.TotalSeconds, (long)gap.To.TotalSeconds);
            });
        }


        for (int vehicleNodeIndex = 0; vehicleNodeIndex < _vehicles.Count; vehicleNodeIndex++)
        {
            _routingModel
                .solver()
                .Add(RelativeDuration.DoesNotExeedLimit(_settings.MaximumRouteDuration, _routingModel, vehicleNodeIndex, _vehicles[vehicleNodeIndex]));
        }
public class RelativeDuration
    {
        public static Constraint DoesNotExeedLimit(TimeSpan limit, RoutingModel routing, int vehicleIndex, RoutingVehicle vehicle)
        {
            var timeDimension = routing.GetDimensionOrDie(PlannerConstants.TIME_DIMENSION_NAME);

            var startSerconds = timeDimension.CumulVar(routing.Start(vehicleIndex));
            var endSeconds = timeDimension.CumulVar(routing.End(vehicleIndex));

            if (vehicle.Type == VehicleType.Virual)
                return endSeconds < (long) PlannerConstants.INFINITIVE_WORKDAY_SECONDS;

            return endSeconds <= (long) limit.TotalSeconds + startSerconds;
        }
    }

我还尝试为持续时间限制约束添加单独的维度,以将范围设置为目标限制,但会导致相同的问题。

魔术应该发生在DidNotExeedLimit方法中。 恕我直言,我应该将startSeconds设置为SlackVar,但这会导致访问内存异常。 GC可能会以某种方式删除此变量。

你们有什么想法吗? 很抱歉很长的帖子,但问题很复杂:)

好的! 经过一周的搜索,终于找到了发布在此处的解决方案: OR-TOOLS RL VRPTW问题中的移位长度约束?

谢谢@ihadanny!

我所需要的只是在时间维度上使用SetSpanUpperBoundForVehicle方法,而StartCumulZero为false。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM