Несогласованная цепочка после добавления ProblemFactChange в Ssolution при планировании в реальном времени

Некоторое время я работал с optaplanner, но впервые делаю планирование в реальном времени, проблема заключается в довольно простой цепочке VRP с временными окнами, но я точно знаю, что у меня проблема.

Поработав некоторое время, когда я удаляю несколько Standstill с помощью последовательности документации (ScoreDirector#beforeEntityRemoved, удаляя объект из списка и обновляя экземпляр списка, ScoreDirector#afterEntityRemoved, а затем ScoreDirector#triggerVariableListeners) из цепочки, цепочка становится несогласованной, следующая остановка предыдущегоStandStill не такая же что текущий застой, а иногда даже null

Но все это происходит только когда я удалил более 2 или 3 Standstills, если я удалю только 1, он продолжает работать

PD: Об удалении объекта: я пробовал с удалением и без удаления ссылки на объект из текущей цепочки, но когда я удаляю элемент из цепочки вручную, иногда появляется ошибка, сообщающая мне, что ссылки неправильные, но я не понимаю почему, когда я обнаруживаю, что цепочка непоследовательна, optaplanner не обнаруживает этого.

for (int i = 0; i < visitsToRemove.size(); i++) {
    OptimizingVisit visit = visitsToRemove.get( i );
    OptimizingVisit solverReference = scoreDirector.lookUpWorkingObject( visit );
    scoreDirector.beforeEntityRemoved( solverReference );
    solution.getVisits().remove( solverReference ); //working equals method is implemented here
    solution.setVisits( new ArrayList<>( solution.getVisits() ) );
    scoreDirector.afterEntityRemoved( solverReference );
    logger.info( String.format("Order #%s (%s) was removed from the solution",visit.getOrderNumber(),visit.getOrderId()) );
}

Я знаю, что вам, ребята, может понадобиться дополнительная информация, и я дам ее вам по мере необходимости, но я, честно говоря, не знаю, что вам может понадобиться, моя проблема в значительной степени является копией примера с некоторыми идентификаторами для ссылки на сущности моего домена.

заранее спасибо


person JorgeGarza    schedule 13.07.2020    source источник
comment
В любом случае solution.setVisits( new ArrayList<>( solution.getVisits() ) ); должен быть перед циклом for и особенно перед solution.getVisits().remove( solverReference ).   -  person Geoffrey De Smet    schedule 14.07.2020


Ответы (1)


Недостаточно удалить посещение A из списка visitList. Также нужно удалить A из цепей. Любое посещение B, у которого есть previous ссылка, указывающая на A, теперь должно указывать на A. Любое посещение C (= A.предыдущее), для которого C.next указывает на A, теперь должно указывать на A.next (= B).

Да, это ПИТА. Когда-нибудь упрощение VRP сделает это намного проще.

person Geoffrey De Smet    schedule 14.07.2020
comment
На самом деле я сделал это, прежде чем вы мне ответили, я собирался отредактировать свой вопрос, но мне приятно получить ваш ответ на этот вопрос, спасибо - person JorgeGarza; 14.07.2020