Timefold Solver 是否按照 ConstraintProvider 默认定义的顺序(或优先级)应用(并检查)约束?或者,更准确地说,当求解器尝试解决特定问题时,它的约束如何工作?
考虑以下具有 2 个约束的情况:
这两个约束的应用顺序是什么?
还有一种方法可以在 ConstraintProvider 中对约束进行排序,以便更有效地应用约束?
例如:
情况a):约束的顺序是约束A,约束B
应用约束 A(并执行必要的移动以获得更好的解决方案)后,在约束 B 中将有机会不受惩罚。
情况b):约束的顺序是约束B,约束A
应用约束 B(并执行必要的移动以获得更好的解决方案)后,在约束 A 中将有可能受到额外的惩罚。
我希望这些问题有意义。如果没有,请随时编辑这篇文章。任何帮助将不胜感激。
从命令式编程的角度来看,这有点难以理解,但是约束没有顺序,因为所有约束都存在于一个大桶中。单独存在不存在任何约束。
考虑两个约束流:
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 的作用。