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

如何在Google或Tools中限制路由持续时间?

林鹏鹍
2023-03-14

我正在研究路由优化问题,我发现自己陷入了一些僵局。我正在使用或工具作为解算器。净核心。

问题如下:当我处理时间窗口约束时,可能需要等待一些时间来适应某个位置时间窗口。这很好。解算器倾向于使用时间窗口约束位置作为第一个节点。这也很好。但这样的话,我们可能想把车辆的出发日期推迟一些。因此,当我将路线持续时间限制设置为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;
        }
    }

我还尝试为工期限制添加单独的维度,设置地平线到目标的限制,但导致了相同的问题。

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

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

共有1个答案

夏侯衡
2023-03-14

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

谢谢@ihadanny!

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

 类似资料:
  • 在我的应用程序中,用户需要能够输入持续时间,包括分钟和秒。 我正在考虑使用Windows中的控件来更改时间,虽然我只需要几分钟和几秒钟,而且箭头也很好,但不是必需的。 JavaFX 2中是否已经有此控件 如果没有,我如何创建这样的控件 上述Windows控件的屏幕截图: 谢谢你的提示!

  • 问题内容: 有谁知道如何在react-router中限制对特定路由的访问?我想在允许访问特定路由之前检查用户是否已登录。我以为这很简单,但是文档尚不清楚该怎么做。 这是我应该在定义组件的位置设置的东西,还是应该在组件处理程序中处理的东西? 问题答案: 更新(2019年8月16日) 在react-router v4和使用React Hooks中,这看起来有些不同。让我们从开始。 我们正在使用一个库来

  • 我想把24小时表示为“持续时间”。也就是说,应该是从00:00:00到24:00:00。像今天上午12点到明天上午12点这样的事情是不好的。这也是24小时,但这不是我想要的。此外,这个“持续时间”不应该附带日期或日期的概念。 如何使用Joda Time完成此操作? 编辑- 用例——“我想创建一个调度程序。24小时的“周期”被分成任意大小的切片,如20分钟、30分钟或1小时。我只想用Joda创建一个

  • 我在写一个地牢风格的游戏,地牢基本上是一个网格窗格。我想让玩家每0.5秒移动一格,如果他保持控制键。但我不知道如何做到这一点。我读过JavaFX:如何检测钥匙是否被按下。但这个问题与我的问题并没有特别的关系(除了我可以追踪发生了多少关键事件,或许可以在此基础上做更多)。所以我跟随这篇文章并尝试使用线程。sleep()解决了我的问题,但事实证明玩家只是停了几秒钟,然后突然移动了几格。 有人知道怎么解

  • 问题内容: 我想记录实际的时间花了多长时间。目前,我正在这样做: 但是,如果在运行SQL查询(或任何其他查询)时调整了时间,那将失败(产生不正确的结果)。 我不想仅仅对其进行基准测试。我想将其记录在实时应用程序中,以便查看实时系统上的趋势。 我想要类似clock_gettime(CLOCK_MONOTONIC,…)的东西,但是在Python中。并且最好不必编写一个调用clock_gettime()

  • 问题内容: 有谁知道Java库可以像C#一样以毫秒为单位打印数字? 例如,最长的123456 ms将被打印为4d1h3m5s。 问题答案: Joda Time使用PeriodFormatterBuilder有一个很好的方法。 快速获胜: 例如