Вопрос А очень прост.
Вопрос Б не так.
Что касается 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
получить что-то вроде этого:
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
s.
Однако это, безусловно, не самый элегантный метод, поскольку его временная сложность равна O(n)
, где n
- общее количество планирующих объектов. хороший способ сделать это состоит в том, чтобы реализовать так называемую структуру данных обслуживания заказов для клиентов по транспортному средству. Эта структура данных поддерживает операции
- Вставка (x, y): вставка нового клиента в существующую цепочку
- Удалить (x): это удаление клиента из существующей цепочки, см. Вопрос А.
- Порядок (x, y): определите, предшествует ли x порядку y в цепочке - это то, что вам нужно.
Состояние современных алгоритмов (см., Например, «Бендер М.А., Коул Р., Демейн Э.Д., Фарах-Колтон М., Зито Дж. (2002) Два упрощенных алгоритма для поддержания порядка в списке». В: Мёринг R., Raman R. (eds) Алгоритмы - ESA 2002. ESA 2002. Конспект лекций в области компьютерных наук, том 2461. Springer, Berlin, Heidelberg ") поддерживает O(1)
амортизированное время вставки / удаления и O(1)
запрос в худшем случае время, намного лучше, чем система, предложенная выше (но гораздо больше работы). Посмотрите на транзитивность утилит , если вы заинтересованы в реализации. Мне было бы очень интересно, если бы такая структура данных была включена в виде теневых переменных из коробки в optaplanner - вопрос о том, находится ли один объект перед другим в цепочке, является повсеместным.