optaplanner域设计中多对多关系的最佳方法

时间:2016-03-11 19:18:30

标签: optaplanner

您好我想问一下在为我想要解决的问题设计域时采取什么方法,正如我在示例中看到的那样,设计往往像实体关系模型,例如多对多通过在两个实体之间放置一个关联实体来解决关系。 我的问题是为什么它对性能有帮助,我应该遵循这种设计模式吗?

1 个答案:

答案 0 :(得分:1)

双方都是问题属性的多对多关系(例如,如果两个类都是问题事实)

关联实体的使用是可选的:它是您的设计电话。 OptaPlanner并不关心,但Drools确实如此,因此它会影响你的分数DRL的表现。

例如,我们假设EmployeeSkill之间存在多对多的关系。员工拥有多种技能,多名员工可以获得技能。我写了大部分示例,我更喜欢使用关联实体 - 所以我在这里使用SkillAttained类(尽管新示例taskassigning将避免这些关联实体作为演示和提高测试覆盖率。)

至于性能影响,它是关于散列和组合计数的全部内容。以及它如何影响增量分数计算(请参阅有关最后一个概念的文档)。 在任何情况下,请避免在DRL 中不需要accumulatescollect,因为他们还没有完全按照增量工作,因此会减少增量分数计算。

使用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还不支持多对多的规划变量关系。 Vote for this jira.因此,目前需要一个关联实体来解决这个问题。