1

我只是想知道你们中是否有人知道什么更快,

L=[1,2,3,4,5], all_different(L). % needs use_module(library(clpfd)).

或者

L=[1,2,3,4,5], is_set(L).

有谁知道?我的数独求解器需要更快的解决方案。谢谢!

4

2 回答 2

2

all_diff/1is_set/1之间的区别在于前者使用“约束逻辑”并且可以在列表的条目完全实例化之前施加预期限制,这样当 Prolog 引擎被迫统一或分配相等时会发生故障列表参数的两个条目的值。

我们可以用以下一对查询来说明all_diff的“约束逻辑” :

?- length(L,5), all_different(L), L=[1,2,3,4,5].
L = [1, 2, 3, 4, 5].

?- length(L,5), all_different(L), L=[1,2,3,4,1].
false.

有必要为all_different提供一个适当的列表,但不要拥有完全绑定或“基本”条目之一。上面表明all_diff可以预期地对列表的条目施加约束。

将结果与is_set进行比较:

?- length(L,5), is_set(L), L=[1,2,3,4,5].
L = [1, 2, 3, 4, 5].

?- length(L,5), is_set(L), L=[1,2,3,4,1].
L = [1, 2, 3, 4, 1].

一旦is_set成功,它就不能阻止将来创建相同条目的绑定。

所以谓词all_different依赖于约束逻辑库中的额外机制来完成is_set不能做的事情,并且在大多数情况下,这种额外的机制会增加开销。然而,在 viktor 的问题中使用了简单的方法,额外的机器并没有使用太多。检查是在完全绑定的条件下进行的,而不是以预期的方式进行的,并且效率是可比的。

于 2011-06-04T07:00:37.913 回答
2

使用谓词 time/1 来衡量推理次数和进行计算所花费的实际时间。在你的例子中,你会做类似的事情

time((L=[1,2,3,4,5], all_different(L))) vs. time((L=[1,2,3,4,5], is_set(L)))

请注意,测量的时间取决于第一次成功。

于 2011-06-03T13:28:45.117 回答