我是 OptaPlanner 的新手,我正在尝试在我的项目中对其进行配置以解决 CVRPTW 问题。我当前的配置与您在项目源代码中可以找到的示例非常相似,但我的要求不同。我的应用程序收到持续交付请求,其中:
- 平均服务时间为 5 分钟
- DueTime - ReadyTime = 10 分钟
- 地点之间的平均距离(时间)约为 2.5 分钟
- 只有1个仓库
我的想法是每次收到新请求时都重新运行求解算法。我有必要了解该请求是否可行,或者是否需要及时向前或向后移动。如果您考虑以下问题陈述(位置省略,但与仓库位置相当等距):
CUST_ID READY_TIME DUE_TIME SERV_DUR DEMAND
1 12:45:00 12:55:00 00:05:00 1
2 12:35:00 12:45:00 00:05:00 8
3 12:25:00 12:35:00 00:05:00 5
4 13:25:00 13:35:00 00:05:00 5
考虑到有 2 辆车可用,容量均为 10 辆,我得到以下解决方案(每辆车的时间表):
**Vehicle 1 Capacity 10 - delivery sequence starting from Depot [1]**
Cust[3] D: 5 Ar.T: 12:25:00 Ap.T: 12:23:08 Prev.D: 00:01:52 Next.D: 00:03:46
Cust[4] D: 5 Ar.T: 12:33:56 Ap.T: 12:30:00 Prev.D: 00:03:56 Next.D: --:--:--
**Vehicle 2 Capacity 10 - delivery sequence starting from Depot [1]**
Cust[2] D: 8 Ar.T: 12:35:00 Ap.T: 12:33:03 Prev.D: 00:01:57 Next.D: 00:03:05
Cust[1] D: 1 Ar.T: 12:42:47 Ap.T: 12:40:00 Prev.D: 00:02:47 Next.D: --:--:--
其中 D 是 Demand,Ar.T 是 Arrival Time,Ap.T 是 Approaching Time(需要离开前一个位置才能准时到达所选位置的时间),Prev.D 是与前一个位置的距离(时间) Next.D 是距以下位置的距离(时间)。
可以看到,客户 4 收货太早了(到货时间是 12:33:56,而准备时间是 13:25:00)。我理解规则arrivalBeforeReadyTime是一个额外的软约束,但我希望计划者建议我使用预留的交付方式向客户4 交付。将规则arrivalBeforeReadyTime设置为额外的硬约束,大多数时候我得到以下异常:
org.drools.core.RuntimeDroolsException: java.lang.NullPointerException
at org.drools.core.base.accumulators.SumAccumulateFunction.reverse(SumAccumulateFunction.java:85)
我有两个问题:
- 当我得到上述异常时,我是否必须将其视为“未解决的问题”?还是我必须调整我的配置?这是我不应该得到的东西吗?
- 我应该如何管理持续交付场景?我是否必须定义不同的大时间窗口来独立解决?但是如何定义这些窗口的边界呢?以及如何管理跨边界计划的交付?(这个解决方案对我来说似乎不正确)
编辑1:
将 OptaPlanner 版本从 6.0.0.CR3 更新到 6.0.0.CR4-Pre1 解决了 NullPointerException。文档对实时规划很清楚,我已经考虑在实时模式下运行我的规划器。但由于在上面的示例中结果并不好,我试图了解我还能做些什么来管理这种情况。我将规则arrivalBeforeReadyTime从软约束切换到硬约束,现在我没有得到NullPointerException,时间安排似乎管理得当,结果如下(例如):
问题陈述:
CUSTID RTIME DTIME SERVDUR DEMAND
1 12:45:00 12:55:00 00:05:00 5
2 12:35:00 12:45:00 00:05:00 3
3 12:25:00 12:35:00 00:05:00 10
4 14:25:00 14:35:00 00:05:00 2
解决方案
**Vehicle 1 Capacity 10 - delivery sequence starting from Depot [1]**
Cust[3] D: 10 Ar.T: 12:25:00 Ap.T: 12:23:08 Prev.D: 00:01:52 Next.D: 00:02:26
Cust[2] D: 3 Ar.T: 12:32:26 Ap.T: 12:30:00 Prev.D: 00:02:26 Next.D: 00:03:05
Cust[1] D: 5 Ar.T: 12:42:47 Ap.T: 12:40:00 Prev.D: 00:02:47 Next.D: --:--:--
**Vehicle 2 Capacity 10 - delivery sequence starting from Depot [1]**
Cust[4] D: 2 Ar.T: 14:25:00 Ap.T: 14:22:53 Prev.D: 00:02:07 Next.D: --:--:--
如您所见,第一次交付是不可行的,因为需求的总和超出了车辆的容量。我应该假设它是正确的吗?我的意思是,在这种情况下,一个好的解决方案是使用这两种车辆来管理客户 1、2、3。我使用与示例相同的配置,将 vehicleCapacity 作为硬约束。此外,客户 2 和 1 会在准备好时间之前提供服务,如果我对其使用硬约束也是如此。