时间折叠求解器默认根据约束的优先级/顺序(来自 ConstraintProvider)应用约束?

问题描述 投票:0回答:1

Timefold Solver 是否按照 ConstraintProvider 默认定义的顺序(或优先级)应用(并检查)约束?或者,更准确地说,当求解器尝试解决特定问题时,它的约束如何工作?

考虑以下具有 2 个约束的情况:

  • 约束A(具有复杂的实现)
  • 约束 B(具有简单的实现;即简单的条件检查)

这两个约束的应用顺序是什么?

还有一种方法可以在 ConstraintProvider 中对约束进行排序,以便更有效地应用约束?

例如:

情况a):约束的顺序是约束A,约束B

应用约束 A(并执行必要的移动以获得更好的解决方案)后,在约束 B 中将有机会不受惩罚。

情况b):约束的顺序是约束B,约束A

应用约束 B(并执行必要的移动以获得更好的解决方案)后,在约束 A 中将有可能受到额外的惩罚。

我希望这些问题有意义。如果没有,请随时编辑这篇文章。任何帮助将不胜感激。

constraints optaplanner timefold
1个回答
0
投票

从命令式编程的角度来看,这有点难以理解,但是约束没有顺序,因为所有约束都存在于一个大桶中。单独存在不存在任何约束。

考虑两个约束流:

A: forEach(Visit.class)
       .penalize(ONE_SOFT)
B: forEach(Visit.class)
       .filter(visit -> !visit.isApplicable())
       .penalize(ONE_HARD)

请注意,他们有一些共同点:

forEach(Visit.class)

这意味着求解器将首先将所有

Visit
发送到那里。 (因此这两个约束只会处理
Visit
一次,而不是两次!) 从那里开始,
Visit
s 将继续:

A2: penalize(ONE_SOFT)
B2: filter(...)

在A2中,所有

Visit
实例都将因惩罚而终止。 然而,在 B2 中,所有与过滤器匹配的
Visit
实例都会继续:

B3: penalize(ONE_HARD)

就这样,所有

Visit
处理终于完成了。

换句话说 - 约束构建了一个节点图;源是

forEach()
节点,汇是惩罚。然后求解器通过该图发送所有问题事实和实体。

由此,我希望你能看到,没有约束顺序。所有的约束都被打破,变成一个节点网络,最后会受到惩罚。这几乎就是 https://en.wikipedia.org/wiki/Rete_algorithm 的作用。

© www.soinside.com 2019 - 2024. All rights reserved.