多日车辆路线 - 使用具有较小日指数的车辆
Multi Day Vehicle Routing - Use Vehicle With Smaller Day Index
我尝试基于 optaplanner 车辆路线示例构建多日车辆路线。我创建了 VehicleDay class 来为一日游的车辆建模。 VehicleDay class 是 Vehicle 对象和 Day 对象的连接。
这是 classes:
public class Day extends AbstractPersistable {
protected int dayIndex;
protected int dayInt;
protected String day;
// getter and setter methods
...
}
public class Vehicle extends AbstractPersistable {
protected int capacity;
protected Depot depot;
// getter and setter methods
...
}
public class VehicleDay extends AbstractPersistable implements Standstill {
protected Vehicle vehicle;
protected Day day;
// Shadow variables
protected Customer nextCustomer;
// getter and setter methods
...
}
我将规划实体从 Vehicle 移到了 VehicleDay。然后我尝试创建一个示例数据集 (cvrp-72customers-edited.xml),其中包含 8 个车辆日和 71 个客户。我从 cvrp-72customers 中获取这个示例数据集,并将车辆容量修改为原始数据的 3/4 (22000)。 8 个车辆日包括:
- 第 1 天(星期一)的车辆 ID 1
- 第 2 天(星期二)的车辆 ID 1
- 第 1 天(星期一)的车辆 ID 2
- 第 2 天(星期二)的车辆 ID 2
- 第 1 天(星期一)的车辆 ID 3
- 第 2 天(星期二)的车辆 ID 3
- 第 1 天(星期一)的车辆 ID 4
- 第 2 天(星期二)的车辆 ID 4
但是当我尝试 运行 时,结果是第 1 天的一些车辆没有被使用,而是计划者使用了第 2 天的一些车辆 (cvrp-72customers-edited-solved.xml)。我尝试实现的是,计划者首先使用第 1 天的车辆,在所有使用第 1 天的车辆之后,然后计划者在第 2 天开始使用车辆。我尝试使用 Comparator 并创建 StandstillDifficultyComparator class :
public class StandstillDifficultyComparator implements Comparator<Standstill>, Serializable {
@Override
public int compare(Standstill a, Standstill b) {
if (a instanceof Customer) {
return new CompareToBuilder()
.append(((Customer)a).getId(), ((Customer)b).getId())
.toComparison();
} else {
return new CompareToBuilder()
.append(((VehicleDay)a).getDay().getDayIndex(), ((VehicleDay)b).getDay().getDayIndex())
.append(((VehicleDay)a).getId(), ((VehicleDay)b).getId())
.toComparison();
}
}
}
然后在 unionMoveSelector 配置中,我像这样添加比较器 class:
<unionMoveSelector>
<changeMoveSelector>
<entitySelector>
<cacheType>PHASE</cacheType>
<selectionOrder>SORTED</selectionOrder>
<sorterComparatorClass>org.optaplanner.examples.vehiclerouting.domain.solver.StandstillDifficultyComparator</sorterComparatorClass>
<sorterOrder>ASCENDING</sorterOrder>
</entitySelector>
</changeMoveSelector>
<swapMoveSelector>
<entitySelector>
<cacheType>PHASE</cacheType>
<selectionOrder>SORTED</selectionOrder>
<sorterComparatorClass>org.optaplanner.examples.vehiclerouting.domain.solver.StandstillDifficultyComparator</sorterComparatorClass>
<sorterOrder>ASCENDING</sorterOrder>
</entitySelector>
</swapMoveSelector>
<tailChainSwapMoveSelector>
<entitySelector>
<cacheType>PHASE</cacheType>
<selectionOrder>SORTED</selectionOrder>
<sorterComparatorClass>org.optaplanner.examples.vehiclerouting.domain.solver.StandstillDifficultyComparator</sorterComparatorClass>
<sorterOrder>ASCENDING</sorterOrder>
</entitySelector>
</tailChainSwapMoveSelector>
<subChainChangeMoveSelector>
<selectReversingMoveToo>true</selectReversingMoveToo>
<entitySelector>
<cacheType>PHASE</cacheType>
<selectionOrder>SORTED</selectionOrder>
<sorterComparatorClass>org.optaplanner.examples.vehiclerouting.domain.solver.StandstillDifficultyComparator</sorterComparatorClass>
<sorterOrder>ASCENDING</sorterOrder>
</entitySelector>
</subChainChangeMoveSelector>
<subChainSwapMoveSelector>
<selectReversingMoveToo>true</selectReversingMoveToo>
<entitySelector>
<cacheType>PHASE</cacheType>
<selectionOrder>SORTED</selectionOrder>
<sorterComparatorClass>org.optaplanner.examples.vehiclerouting.domain.solver.StandstillDifficultyComparator</sorterComparatorClass>
<sorterOrder>ASCENDING</sorterOrder>
</entitySelector>
</subChainSwapMoveSelector>
</unionMoveSelector>
当我运行它时,抛出异常如下:
Exception in thread "main" java.lang.IllegalArgumentException: Unmarshalling of solverConfigResource (org/optaplanner/examples/vehiclerouting/solver/vehicleRoutingSolverConfig.xml) fails on line number (53).
at org.optaplanner.core.impl.solver.XStreamXmlSolverFactory.configure(XStreamXmlSolverFactory.java:123)
at org.optaplanner.core.api.solver.SolverFactory.createFromXmlResource(SolverFactory.java:90)
at org.optaplanner.examples.common.app.CommonApp.createSolver(CommonApp.java:102)
at org.optaplanner.examples.common.app.CommonApp.createSolutionBusiness(CommonApp.java:97)
at org.optaplanner.examples.common.app.CommonApp.init(CommonApp.java:84)
at org.optaplanner.examples.common.app.CommonApp.init(CommonApp.java:80)
at org.optaplanner.examples.vehiclerouting.app.VehicleRoutingApp.main(VehicleRoutingApp.java:34)
Caused by: " com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$UnknownFieldException: No such field org.optaplanner.core.config.heuristic.selector.move.generic.chained.SubChainChangeMoveSelectorConfig.entitySelector
---- Debugging information ----
message : No such field org.optaplanner.core.config.heuristic.selector.move.generic.chained.SubChainChangeMoveSelectorConfig.entitySelector
field : entitySelector
class : org.optaplanner.core.config.heuristic.selector.move.generic.chained.SubChainChangeMoveSelectorConfig
required-type : org.optaplanner.core.config.heuristic.selector.move.generic.chained.SubChainChangeMoveSelectorConfig
converter-type : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
line number : 53
class[1] : org.optaplanner.core.config.heuristic.selector.move.composite.UnionMoveSelectorConfig
class[2] : org.optaplanner.core.config.localsearch.LocalSearchPhaseConfig
class[3] : org.optaplanner.core.config.solver.SolverConfig
version : 1.4.10
-------------------------------
at org.optaplanner.core.impl.solver.XStreamXmlSolverFactory.configure(XStreamXmlSolverFactory.java:123)
at org.optaplanner.core.api.solver.SolverFactory.createFromXmlResource(SolverFactory.java:90)
at org.optaplanner.examples.common.app.CommonApp.createSolver(CommonApp.java:102)
at org.optaplanner.examples.common.app.CommonApp.createSolutionBusiness(CommonApp.java:97)
at org.optaplanner.examples.common.app.CommonApp.init(CommonApp.java:84)
at org.optaplanner.examples.common.app.CommonApp.init(CommonApp.java:80)
at org.optaplanner.examples.vehiclerouting.app.VehicleRoutingApp.main(VehicleRoutingApp.java:34)
如何让计划员先在第 1 天使用所有车辆,然后在第 2 天使用车辆?
我认为您需要创建一个评分规则来奖励 OptaPlanner 按顺序安排日期。因此,在规则中,您可以说,如果第 X-1 天尚未满员,则对于第 X 天安排的每辆车减一分。
我尝试基于 optaplanner 车辆路线示例构建多日车辆路线。我创建了 VehicleDay class 来为一日游的车辆建模。 VehicleDay class 是 Vehicle 对象和 Day 对象的连接。 这是 classes:
public class Day extends AbstractPersistable {
protected int dayIndex;
protected int dayInt;
protected String day;
// getter and setter methods
...
}
public class Vehicle extends AbstractPersistable {
protected int capacity;
protected Depot depot;
// getter and setter methods
...
}
public class VehicleDay extends AbstractPersistable implements Standstill {
protected Vehicle vehicle;
protected Day day;
// Shadow variables
protected Customer nextCustomer;
// getter and setter methods
...
}
我将规划实体从 Vehicle 移到了 VehicleDay。然后我尝试创建一个示例数据集 (cvrp-72customers-edited.xml),其中包含 8 个车辆日和 71 个客户。我从 cvrp-72customers 中获取这个示例数据集,并将车辆容量修改为原始数据的 3/4 (22000)。 8 个车辆日包括:
- 第 1 天(星期一)的车辆 ID 1
- 第 2 天(星期二)的车辆 ID 1
- 第 1 天(星期一)的车辆 ID 2
- 第 2 天(星期二)的车辆 ID 2
- 第 1 天(星期一)的车辆 ID 3
- 第 2 天(星期二)的车辆 ID 3
- 第 1 天(星期一)的车辆 ID 4
- 第 2 天(星期二)的车辆 ID 4
但是当我尝试 运行 时,结果是第 1 天的一些车辆没有被使用,而是计划者使用了第 2 天的一些车辆 (cvrp-72customers-edited-solved.xml)。我尝试实现的是,计划者首先使用第 1 天的车辆,在所有使用第 1 天的车辆之后,然后计划者在第 2 天开始使用车辆。我尝试使用 Comparator 并创建 StandstillDifficultyComparator class :
public class StandstillDifficultyComparator implements Comparator<Standstill>, Serializable {
@Override
public int compare(Standstill a, Standstill b) {
if (a instanceof Customer) {
return new CompareToBuilder()
.append(((Customer)a).getId(), ((Customer)b).getId())
.toComparison();
} else {
return new CompareToBuilder()
.append(((VehicleDay)a).getDay().getDayIndex(), ((VehicleDay)b).getDay().getDayIndex())
.append(((VehicleDay)a).getId(), ((VehicleDay)b).getId())
.toComparison();
}
}
}
然后在 unionMoveSelector 配置中,我像这样添加比较器 class:
<unionMoveSelector>
<changeMoveSelector>
<entitySelector>
<cacheType>PHASE</cacheType>
<selectionOrder>SORTED</selectionOrder>
<sorterComparatorClass>org.optaplanner.examples.vehiclerouting.domain.solver.StandstillDifficultyComparator</sorterComparatorClass>
<sorterOrder>ASCENDING</sorterOrder>
</entitySelector>
</changeMoveSelector>
<swapMoveSelector>
<entitySelector>
<cacheType>PHASE</cacheType>
<selectionOrder>SORTED</selectionOrder>
<sorterComparatorClass>org.optaplanner.examples.vehiclerouting.domain.solver.StandstillDifficultyComparator</sorterComparatorClass>
<sorterOrder>ASCENDING</sorterOrder>
</entitySelector>
</swapMoveSelector>
<tailChainSwapMoveSelector>
<entitySelector>
<cacheType>PHASE</cacheType>
<selectionOrder>SORTED</selectionOrder>
<sorterComparatorClass>org.optaplanner.examples.vehiclerouting.domain.solver.StandstillDifficultyComparator</sorterComparatorClass>
<sorterOrder>ASCENDING</sorterOrder>
</entitySelector>
</tailChainSwapMoveSelector>
<subChainChangeMoveSelector>
<selectReversingMoveToo>true</selectReversingMoveToo>
<entitySelector>
<cacheType>PHASE</cacheType>
<selectionOrder>SORTED</selectionOrder>
<sorterComparatorClass>org.optaplanner.examples.vehiclerouting.domain.solver.StandstillDifficultyComparator</sorterComparatorClass>
<sorterOrder>ASCENDING</sorterOrder>
</entitySelector>
</subChainChangeMoveSelector>
<subChainSwapMoveSelector>
<selectReversingMoveToo>true</selectReversingMoveToo>
<entitySelector>
<cacheType>PHASE</cacheType>
<selectionOrder>SORTED</selectionOrder>
<sorterComparatorClass>org.optaplanner.examples.vehiclerouting.domain.solver.StandstillDifficultyComparator</sorterComparatorClass>
<sorterOrder>ASCENDING</sorterOrder>
</entitySelector>
</subChainSwapMoveSelector>
</unionMoveSelector>
当我运行它时,抛出异常如下:
Exception in thread "main" java.lang.IllegalArgumentException: Unmarshalling of solverConfigResource (org/optaplanner/examples/vehiclerouting/solver/vehicleRoutingSolverConfig.xml) fails on line number (53).
at org.optaplanner.core.impl.solver.XStreamXmlSolverFactory.configure(XStreamXmlSolverFactory.java:123)
at org.optaplanner.core.api.solver.SolverFactory.createFromXmlResource(SolverFactory.java:90)
at org.optaplanner.examples.common.app.CommonApp.createSolver(CommonApp.java:102)
at org.optaplanner.examples.common.app.CommonApp.createSolutionBusiness(CommonApp.java:97)
at org.optaplanner.examples.common.app.CommonApp.init(CommonApp.java:84)
at org.optaplanner.examples.common.app.CommonApp.init(CommonApp.java:80)
at org.optaplanner.examples.vehiclerouting.app.VehicleRoutingApp.main(VehicleRoutingApp.java:34)
Caused by: " com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$UnknownFieldException: No such field org.optaplanner.core.config.heuristic.selector.move.generic.chained.SubChainChangeMoveSelectorConfig.entitySelector
---- Debugging information ----
message : No such field org.optaplanner.core.config.heuristic.selector.move.generic.chained.SubChainChangeMoveSelectorConfig.entitySelector
field : entitySelector
class : org.optaplanner.core.config.heuristic.selector.move.generic.chained.SubChainChangeMoveSelectorConfig
required-type : org.optaplanner.core.config.heuristic.selector.move.generic.chained.SubChainChangeMoveSelectorConfig
converter-type : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
line number : 53
class[1] : org.optaplanner.core.config.heuristic.selector.move.composite.UnionMoveSelectorConfig
class[2] : org.optaplanner.core.config.localsearch.LocalSearchPhaseConfig
class[3] : org.optaplanner.core.config.solver.SolverConfig
version : 1.4.10
-------------------------------
at org.optaplanner.core.impl.solver.XStreamXmlSolverFactory.configure(XStreamXmlSolverFactory.java:123)
at org.optaplanner.core.api.solver.SolverFactory.createFromXmlResource(SolverFactory.java:90)
at org.optaplanner.examples.common.app.CommonApp.createSolver(CommonApp.java:102)
at org.optaplanner.examples.common.app.CommonApp.createSolutionBusiness(CommonApp.java:97)
at org.optaplanner.examples.common.app.CommonApp.init(CommonApp.java:84)
at org.optaplanner.examples.common.app.CommonApp.init(CommonApp.java:80)
at org.optaplanner.examples.vehiclerouting.app.VehicleRoutingApp.main(VehicleRoutingApp.java:34)
如何让计划员先在第 1 天使用所有车辆,然后在第 2 天使用车辆?
我认为您需要创建一个评分规则来奖励 OptaPlanner 按顺序安排日期。因此,在规则中,您可以说,如果第 X-1 天尚未满员,则对于第 X 天安排的每辆车减一分。