【问题标题】:How best to trigger code after each move in optaplanner?在 optaplanner 中每次移动后如何最好地触发代码?
【发布时间】:2020-01-08 00:11:58
【问题描述】:

我需要在每次移动结束时将计算运行到内存中,然后根据此更新分数。计算的结果需要是有状态的,因为它在其他地方引用(存储在解决方案中)。

文档建议这应该是一个 PlanningEntity 更新为一个 ShadowVariable 在主实体上有一个 VariableListener 但当然这自然会触发每个实体更改,不必要地重新计算。

  1. 如何在 move 结束时触发,而不是按 variable 触发?来自流口水?这不是黑客行为吗?
  2. 如果不使用 VariableListener,它将不再是 PlanningEntity。不是把它变成一个与文档相反的ProblemFact吗?有什么缺点?

更多信息:

  • “计算”是对规划期间流量网络值的预测,其中流量水平取决于任务的当前位置。
  • 我们正在使用实时计划,因此计划周期窗口会根据任务集大小进行调整,并随时间变化。

【问题讨论】:

  • 计算代表什么?如果我更好地理解用例,我可能会建议最佳方法或同意它是否是 optaplanner 中的 API 差距。
  • @GeoffreyDeSmet 它在计划期间预测流量网络的值,其中流量级别取决于影响流量的任务的位置。我会把这个添加到问题中。
  • 您可能需要保留一组影响流程的任务。只是 count++ 和 count-- 并不总是正确的,例如在与自身交换某些东西时。
  • @GeoffreyDeSmet 任务具有是否需要重新计算流的属性,该属性在变量侦听器中进行检查。所以它只针对它所依赖的实体触发。

标签: drools optaplanner


【解决方案1】:

1) 听起来您应该使用阴影变量。请注意,您仍然需要一个正常的约束,也根据该影子变量的状态更新分数。

请注意,您可以有一个影子实体类,它是一个单例(每个问题的解决方案),它有一个影子变量,如果任何计划实体发生变化,该变量就会更新。在 @PlanningSolution 类的字段上使用 @PlanningEntityProperty(不带 Collection)。

在移动结束时,每个移动调用triggerShadowVariableListeners(),而不是在中间。所以如果你担心性能,你不应该担心。 如果您担心正确性 - 因为调用次数会影响您的计算 - 那就不要这样设计/实现它......

2) ProblemFacts 在求解过程中不能改变(不包括实时计划)。没有一个领域。否则它是一个 PlanningEntity。

0) 故意不存在 MoveListener(有充分的理由),甚至在内部也不存在(即使是非常内部的 PhaseLifecycleListener 也只侦听步骤,而不是移动)。

【讨论】:

  • 谢谢杰弗里。这很好,因为它证实了我做出的决定。我有一个单例 PlanningEntityProperty,它在调用 triggerShadowVariableListeners 后更新了一个影子变量。但是,如果移动更改了多个计划变量(例如交换移动或影响多个实体的自定义移动),afterVariableChanged 是否不会运行多次?
  • 它可以工作,并且用这种方法表现得更好。感谢 Geoffrey 的帮助和时间。
  • 终于完成了这项工作,需要更加小心,以确保任何变量侦听器正确更新相对于触发它的实体的影子变量。但是我仍然设法通过检查影子实体上的状态变量,每次移动只运行一次计算来降低复杂性。感谢您的帮助和耐心@GeoffreyDeSmet!
  • 影子变量有据可查,并且有典型用例的好例子;在此基础上进行扩展时,想法实验的学习曲线非常陡峭。很难知道该寻求什么帮助,并且不知道自己走在正确的轨道上,这在时间上是昂贵的。 FULL_ASSERT 并逐渐重新构建这个想法是关键,就像自定义动作一样。错误消息非常详细,但需要学习底层行为才能理解。只是观察,不是批评。 Optaplanner 的核心功能和初始设置非常快速和直观。
  • 只有我能想到的建议:1)更明确地强调“影子实体”的概念,鼓励将其用作可接受的做法。 2) 在开发自定义动作、影子变量等期间以某种方式鼓励/强制使用 FULL_ASSERT?从长远来看可以节省时间。也许您应该在满意后必须覆盖每个自定义移动/变量侦听器的完整断言?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多