Я пытаюсь построить многодневную маршрутизацию транспортных средств на основе примеров маршрутизации транспортных средств optaplanner. Я создаю класс VehicleDay для моделирования автомобиля для однодневной поездки. Класс VehicleDay представлял собой объединение объекта Vehicle и объекта Day. Вот классы:
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 с днем 1 (понедельник)
- Идентификатор автомобиля 1 с днем 2 (ВТОРНИК)
- Идентификатор автомобиля 2 с днем 1 (понедельник)
- Идентификатор автомобиля 2 с днем 2 (ВТОРНИК)
- Идентификатор автомобиля 3 с днем 1 (понедельник)
- Идентификатор автомобиля 3 с днем 2 (ВТОРНИК)
- Идентификатор автомобиля 4 с днем 1 (понедельник)
- Идентификатор автомобиля 4 с днем 2 (ВТОРНИК)
Но когда я попытался запустить его, в результате некоторые транспортные средства из Дня 1 не используются, и вместо этого планировщик использует некоторые транспортные средства из Дня 2 (cvrp-72customers-edited-solved.xml). Я пытаюсь добиться того, чтобы планировщик сначала использовал транспортное средство с днем 1, после того, как все транспортное средство использовалось с днем 1, а затем планировщик начал использовать транспортное средство в день 2. Я попытался использовать Comparator и создал класс StandstillDifficultyComparator:
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 я добавляю свой класс компаратора следующим образом:
<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)
Как я могу заставить планировщик использовать все транспортные средства сначала в первый день, а затем использовать транспортное средство во второй день?