Как использовать алгоритм минимального конфликта с optaplanner

Есть ли в optaplanner алгоритм минимального конфликта? или как это сделать?

Как насчет того, чтобы использовать его как часть выбора окрестностей, например:

  1. Определите собственную фабрику подкачки, которая создает соседство следующим образом
  2. Получить все нарушения для каждой переменной для оптимизации, поэтому требуется вызов метода ScoreDirector.calculateScore, а затем анализ / обработка constraintMatches
  3. Упорядочить по переменным наименьшее количество баллов или наибольшее количество нарушений
  4. Построить окрестности, сначала поменяв местами эти переменные

Если это целесообразно, есть ли способ получить constraintMatches без необходимости повторного вызова calcScore, чтобы ускорить процесс

2 ответа

Этот алгоритм еще не поддерживается из коробки OptaPlanner. Я бы назвал это Управляемым локальным поиском. Но это не так сложно добавить себя. На самом деле, дело не в изменении алгоритма, а в изменении селекторов сущностей.

Примерно так должно работать:

<swapMoveSelector>
  <entitySelector>
    <cacheType>STEP</cacheType>
    <probabilityWeightFactoryClass>...MyProbabilityWeightFactory</probabilityWeightFactoryClass>
  </entitySelector>
</swapMoveSelector>

Прочитайте о расширенной конфигурации swapMoveSelector, селекторе сущностей, сортированном выборе и выборе вероятности.

Класс обратного вызова, который вы реализуете для вероятностного или сортированного выбора, должен определять приоритеты объектов, которые являются частью конфликта.

Я бы определенно использовал отсортированный или вероятностный выбор на селекторе сущностей, а не на весь swapMoveSelector, потому что это излишнее, ресурсоемкое и памяти.

Я бы предпочел вероятностный отбор, а не отсортированный. Несмотря на то, что отсортированный выбор лучше отражает ваш псевдокод, я считаю (но не доказал), что вероятностный выбор будет работать лучше, учитывая характер метаэвристики. Попробуйте оба, запустите некоторые тесты с Benchmarker и дайте нам знать, что работает лучше;)

Не уверен, как решить вашу общую проблему, но для вашего последнего пункта:

Вы можете создать PhaseLifecycleListener и прикрепить его через ((DefaultSolver) solver).addPhaseLifecycleListener

В stepStarted или stepEnded(в зависимости от ваших потребностей) вы можете позвонить

stepScope.getScoreDirector().getConstraintMatchTotals()

чтобы получить суммы ограничений.

Надеюсь, это поможет.

Другие вопросы по тегам