Лучший подход для многих ко многим отношениям в дизайне доменов optaplanner

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

1 ответ

Решение

Отношения многие ко многим, где обе стороны являются проблемным свойством (например, если оба класса являются проблемным фактом)

Использование ассоциированной сущности необязательно: это ваш проектный вызов. OptaPlanner не волнует, но Drools заботится, так что это может повлиять на эффективность ваших DRL.

Например, давайте предположим, что между многими Employee и Skill, Сотрудник имеет несколько навыков, а навык достигается несколькими сотрудниками. Я написал большинство примеров, и я предпочитаю использовать ассоциированные объекты - поэтому я бы использовал SkillAttained класс здесь (хотя новый пример, taskassigning будет избегать этих ассоциированных организаций в качестве демонстрации и улучшить охват тестами).

Что касается влияния на производительность, все зависит от того, как хеширование и комбинация учитываются. И как это влияет на вычисление добавочной оценки (см. Документы об этой последней концепции). В любом случае, избегайте ненужного accumulates а также collect Находится в ДХО, так как они еще не полностью работают в пошаговом режиме и, следовательно, снижают коэффициент усиления при расчете добавочного балла.

С SkillAttained обычно легче получить хорошую производительность и разработать правила.

when
    ShiftAssignment($s : shift, $e : employee) // The when side must always contain a planning entity
    SkillRequired(shift == $s, $s : skill) // Small perf opportunity: ShiftAssigment.getEmployee().getRequiredSkills() would avoid a lookup
    not SkillAttained(employee == $e, skill == $s) // Good: the skill matching uses hashing for scalability if there are many skills
then
    ...addHard(-1); // Fires once per 1 missing skill

Без этого часто труднее писать - без использования накоплений или сборов. Однако такой метод, как Employee.hasSkill(Skill) (предполагая, что навыки работника находятся в LinkedHashSet) очень эффективно.

when
    ShiftAssignment($c : countMissingSkills())
then
    ...addHard(- $c); // Fires once per ShiftAssignment with at least 1 missing skill

Так что в этом примере ShiftAssignment.countMissingSkills() должен быть действительно эффективным (например, использовать LinkedHashSet/Maps и т. д.).

Многие ко многим отношениям, которые являются @PlanningVariabe

В настоящее время OptaPlanner 6.4 пока не поддерживает много-много взаимосвязей переменных планирования. Проголосуй за эту джиру. Таким образом, для решения этой проблемы требуется ассоциированная организация.

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