Google OR 工具 - 设置时间窗口尺寸失败并出现低级错误
Posted
技术标签:
【中文标题】Google OR 工具 - 设置时间窗口尺寸失败并出现低级错误【英文标题】:Google OR Tools - Setting time window dimensions fails with low level error 【发布时间】:2021-05-21 07:46:52 【问题描述】:所以我尝试使用https://developers.google.com/optimization/routing/vrptw 的 VRPTW 示例作为我自己的一些代码的基础。
在我的情况下,我想安排多天的多辆车(每辆车都在司机家开始/返回)。 在该示例中,假设在某一天所有车辆都从一个站点出发。时间矩阵的第一列是站点编号,我相信该代码中的 0 索引是因为所有车辆都从站点离开/返回。
// Add time window constraints for each vehicle start node.
for (int i = 0; i < data.VehicleNumber; ++i)
long index = routing.Start(i);
timeDimension.CumulVar(index).SetRange(data.TimeWindows[0, 0], data.TimeWindows[0, 1]);
所以在我的情况下,假设我有三天的两辆车交付时间,在我的时间矩阵中,我有列:
第 1 天 - 车辆 1(从位置 A 开始/返回) 第 1 天 - 车辆 2(从位置 B 开始/返回) 第 2 天 - 车辆 1(从位置 A 开始/返回) 第 2 天 - 车辆 2(从位置 B 开始/返回) 第 3 天 - 车辆 1(从位置 A 开始/返回) 第 3 天 - 车辆 2(从位置 B 开始/返回)然后我有一个车辆开始和结束节点数组,指向这些条目。所有这些都运行良好,我对所提供的结果或工具感到满意。
我有一个问题是我现在想为每辆车设置时间窗口。所以应该是这样的:
第 1 天 - 车辆 1 时间窗口 0-1440 第 1 天 - 车辆 2 时间窗口 0-1440 第 2 天 - 车辆 1 时间窗口 1440-2880 第 2 天 - 车辆 2 时间窗口 1440-2880 第 3 天 - 车辆 1 时间窗口 2880-4320 第 3 天 - 车辆 2 时间窗口 2880-4320所以我把上面的示例代码改成了下面的代码。我认为代码看起来没问题,但它在指示行出现“无法获取您的数据。失败”(这似乎是一个相当低级的错误)。
var useIndex = 0;
for (int i = 0; i < data.DayCount; i++)
var fromTime = i * 1440;
var toTime = (i + 1) * 1440;
for (int j = 0; j < data.VehicleCount; ++j)
long index = routing.Start(useIndex);
timeDimension.CumulVar(index).SetRange(fromTime, toTime); <---- FAILS HERE
useIndex++;
第一天正常,将值设置为 0-1440。当它执行第二个循环并尝试将值设置为 1440-2880 时,它会失败。如果我在每个循环上将所有值都设置为 0-1440,那就没问题了。因此,只有当我尝试更改值时才会出现问题。有什么想法吗?
编辑 1 错误消息的堆栈跟踪显示错误发生在这里:
在 Google.OrTools.ConstraintSolver.IntExpr.SetRange(Int64 l, Int64 u)
我正在使用 Google.OrTools 9.0.9048
编辑 2 看起来 from 值必须以 0 开头(0-1440 很好)。如果我尝试将所有范围分配给 1440-2880,它会立即失败。
【问题讨论】:
【参考方案1】:TLDR:SetRange()
检查请求的新范围是否在域中,否则失败。
问题:时间维度的车辆容量(又名地平线)是多少? 必须至少为 4320 !
即当你使用这样的东西时
routing.AddDimension(
transit_evaluator_index,
X, # max Slack time aka waiting time here
Y, # <=== HERE vehicle capacity
False, # Force start cumul to zero (not wanted for time dimension)
"Time") # name of the dimension and used as uid
我的意思是,所有范围值都必须小于或等于 Y。
【讨论】:
我将 Y 设置为 100,000。我正在尝试将范围设置为 1440-2880,所以应该没问题。但是,对于我认为正确的第 4 个属性,您的错误是错误的。如果我把它设为假,我将不再收到错误。 让它成为现实,意味着你将强制 time_dimension.CumulVar(any_start_node) 为零,但如果同时你有一个起始节点的范围为 [1440-2880] 或 [ 2880-4320] 你只是让你的问题不可行,因为 0 不在范围内......【参考方案2】:不要使用 SetRange。使用 Solver.Add(solver.MakeBetweenCt())。 SetRange API 旨在用于搜索。
【讨论】:
我不得不回到developers.google.com/optimization/routing/cvrptw_resources 的资源约束示例来弄清楚你在这里得到了什么以及它是如何工作的。我想我知道你从哪里来,我可以看到它在我仍然需要做的一些其他事情中的用途,但是根据我对 Mizux 答案的评论,从时间窗口约束示例推断并设置 true 为 false,我想我是目前可以不使用 MakeBetweenCt,除非我错过了一些令人信服的理由。以上是关于Google OR 工具 - 设置时间窗口尺寸失败并出现低级错误的主要内容,如果未能解决你的问题,请参考以下文章