我的问题是对Capacitated Vehicle Routing Problem (CVRP)的修改,最终还将包括时间窗口。
由于时间窗口已内置在示例中,因此我不难理解它们。但是,我需要更改CVRP示例中的核心约束之一,我对如何做到这一点有些迷惑。
在我要建模的系统中,Vehicle
可以保留其Depot
,转到多个不同的Customers
,然后加载材料。但是,我的模型与示例不同的地方是Vehicle
可以访问任何Depot
中间链以存放其当前负载。
我一直在研究documentation,试图弄清楚该如何做,到目前为止,我的基本理解是我必须将Depot
的定义(可能是通过实现Standstill
)更改为可以成为车辆探访地点链的一部分,并且/或者可以通过某种特殊的规则将Depot
集成到Customer
中,即访问Depot
会清空车辆而不是增加需求。
我也一直在研究shadow variables和variable listeners,但是我不知道这是否是正确的方法。一切都令人困惑。
任何人都可以提供一些提示或建议,或者在我将自己深深陷进一个洞之前,向我指出从哪里开始的正确方向?
根据Geoffrey的建议,将Vehicle
类重命名为VehicleTrip
,并通过给它一个值previousVehicleTrip
并给它一个可变的开始时间和结束时间来使其指向上一趟旅程(Kotlin中的代码示例):
class VehicleTrip(
...,
var startTime: LocalDateTime? = null,
var endTime: LocalDateTime? = null,
val previousVehicleTrip?: VehicleTrip = null
) {
...
}
在Customer
类中,您应该有一个变量arrivalTime
(类似于CVRPTW示例),它是一个自定义阴影变量。在此变量的侦听器类中,您通常通常只更新车辆到达客户的时间,现在您还应该在此处更新VehicleTrip
的开始时间或结束时间(这是可能的,因为每个Customer
都知道VehicleTrip
所属)。
[当您的客户是此行程中的第一位,即previousStandstill
为VehicleTrip
时,您可以将此行程的开始时间设置为输入所指定的开始时间(如果是第一行程)或结束否则previousVehicleTrip
的时间。
[当您的客户是此行程的最后一位,即nextCustomer
为null
时,您将此行程的结束时间更新为此集装箱的出发时间,加上返回仓库的时间。] >
注意
当您最终得到空的VehicleTrip
时,此功能将不起作用。当nextCustomer
的VehicleTrip
属性为null
时,开始时间和结束时间不匹配(即使它们应该匹配)。一种变通方法是让您创建的旅行数量紧凑,即创建尽可能少的旅行。当我找到合适的解决方案时,我将更新此答案。