我有一个问题,对我来说真的很难解决。我想使用OptaPlanner解决具有优先级和车辆故障的CVRPTW。到目前为止,我所做的就是获取标准示例并在GUI中解决它,然后保存结果。比起我,我在python中修改了.xml文件,以手动删除车辆并释放客户。我知道正确的方法是制作一个ProblemFact,但是我不知道如何执行此操作。我看到了一些答案,但是我需要更多帮助或如何完成的示例。
第二件事是如何建模优先级。因此,客户“ A”必须先于客户“ B”。 (唯一的例子是在另一个称为项目作业计划的问题中)
非常感谢您!
答案 0 :(得分:3)
问题A非常简单。
问题B不是。
对于A,您需要位于可以访问对象图的位置(例如,在反序列化解决方案之后)。然后,您获得了该车辆的第一个客户,将其previousStandstill
设置为null
:
Customer nextCustomer = vehicle.getNextCustomer();
if (nextCustomer != null){
scoreDirector.beforeVariableChanged(nextCustomer, "previousStandstill");
nextCustomer.setPreviousStandstill(null);
scoreDirector.afterVariableChanged(nextCustomer, "previousStandstill");
scoreDirector.triggerVariableListeners();
}
我相信问题B应该引起更多关注。这样做的默认方法是实现一个OrderListener
,该previousStandstill
在客户的previousStandstill
上触发,只要在任何客户上更改@CustomShadowVariable(variableListenerClass = OrderListener.class,
sources = {@PlanningVariableReference(variableName = "previousStandstill")})
public Integer getPositionInVehicleChain() {
return position;
}
时,侦听器都会更新车辆链中的所有客户:
OrderListener
,然后在afterVariableChanged
的{{1}}方法中添加如下内容:
while (nextCustomer != null) {
if (position == nextTe.getPositionInVehicleChain()) break;
scoreDirector.beforeVariableChanged(nextCustomer, "position");
nextCustomer.setPositionInStapelabschnitt(pos);
scoreDirector.afterVariableChanged(nextCustomer, "position");
pos++;
nextCustomer = nextCustomer.getNextCustomer();
}
然后,在isBeforeCustomer(Customer otherCustomer)
类中实现一个Customer
,在其中比较两个position
。
但是,这肯定不是最优雅的方法,因为它的时间复杂度为O(n)
,其中n
是计划实体的总数。 好的方法是在每辆车的客户身上实施所谓的订单维护数据结构。该数据结构支持操作
最先进的算法(例如,参见“ Bender MA,Cole R.,Demaine ED,Farach-Colton M.,Zito J.(2002年),两种简化算法以维护列表中的顺序。在:Möhring中R.,拉曼R.(eds)算法-ESA2002。ESA2002。计算机科学讲座,第2461卷,Springer,柏林,海德堡“)支持O(1)
摊销的插入/删除时间和O(1)
最坏情况的查询时间,比上面建议的系统要好得多(但工作量大得多)。如果您对实现感兴趣,请浏览 transitivity utils 。如果将这样的数据结构作为影子变量包含在optaplanner中,我将非常有兴趣-一个实体是否在链中的另一个之前普遍存在的问题。