Маршрутизация транспортных средств на несколько дней — используйте транспортное средство с меньшим индексом дня

Я пытаюсь построить многодневную маршрутизацию транспортных средств на основе примеров маршрутизации транспортных средств 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. Идентификатор автомобиля 1 с днем ​​2 (ВТОРНИК)
  3. Идентификатор автомобиля 2 с днем ​​1 (понедельник)
  4. Идентификатор автомобиля 2 с днем ​​2 (ВТОРНИК)
  5. Идентификатор автомобиля 3 с днем ​​1 (понедельник)
  6. Идентификатор автомобиля 3 с днем ​​2 (ВТОРНИК)
  7. Идентификатор автомобиля 4 с днем ​​1 (понедельник)
  8. Идентификатор автомобиля 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)

Как я могу заставить планировщик использовать все транспортные средства сначала в первый день, а затем использовать транспортное средство во второй день?


person the.wizard    schedule 04.12.2017    source источник
comment
Извините, StackOverflow не является службой отладки. Вы должны определить конкретную проблему более подробно, чем результат не соответствует ожидаемому и общее расплывчатое описание неправильного вывода.   -  person Jim Garrison    schedule 04.12.2017
comment
Извините @JimGarrison за более подробную информацию о выводе. Я записал более подробно о выводе (я даже загружаю файл, состоящий из вывода). Я надеюсь, что благодаря этому мой вопрос будет достойным того, чтобы его здесь задали.   -  person the.wizard    schedule 04.12.2017
comment
Кажется, у вас есть логическая ошибка в вашем коде, поскольку он не делает то, что вы хотите. Однако вы не опубликовали код, содержащий какую-либо логику обработки. Я не понимаю, на какую помощь вы рассчитываете. Это все равно, что позвонить механику, которого вы никогда не видели, и сказать ему/ей, что ваша машина не доставит вас от дома до работы, но отказываясь предоставить что-либо, кроме марки и модели.   -  person Jim Garrison    schedule 04.12.2017
comment
Для начала нужно пройтись по коду в отладчике IDE, по одной строке за раз, наблюдая за изменением переменных, пока не дойдете до места, где произойдет что-то неожиданное. Вы должны иметь некоторое представление о том, что делает ваш алгоритм, и должны быть в состоянии найти место в вашей программе, где он сбивается с пути. МЫ, конечно, не найдем это место для вас.   -  person Jim Garrison    schedule 04.12.2017
comment
Что ж, @JimGarrison, я добавил всю информацию, которую ты хочешь. Надеюсь, вы примете мой вопрос :)   -  person the.wizard    schedule 04.12.2017
comment
Привет @JimGarrison, не могли бы вы отменить минус, который вы поставили в моем вопросе? Я выполнил все требования для хорошего вопроса. Пожалуйста, рассмотрите возможность удаления вашего отрицательного голоса. Спасибо и с уважением.   -  person the.wizard    schedule 12.12.2017


Ответы (1)


Я думаю, вам нужно создать правило подсчета очков, которое вознаграждает OptaPlanner за планирование дней по порядку. Таким образом, в правиле вы можете сказать, что за каждое транспортное средство, запланированное на день X, вычитается один балл, если день X-1 еще не заполнен.

person code4dc    schedule 04.12.2017
comment
Звучит как хорошая идея.. Тогда я попробую.. Спасибо, @code4dc.. - person the.wizard; 05.12.2017