我目前正在解决一个特定的肯恩问题,我注意到它需要大约5秒才能解决。这是一个较小的拼图。但是,我还需要解决一个更大的问题,我担心解决方案需要花费太长时间才能找到。这是我的代码中最相关的部分(我删除了多余的部分,它们是预期的形式):
getlarger(First, Second, First) :- First >= Second.
getlarger(First, Second, Second) :- First < Second.
getsmaller(First, Second, Second) :- First >= Second.
getsmaller(First, Second, First) :- First < Second.
subtractsmallerfromlarger(First, Second, Result) :- getlarger(First, Second, Larger),
getsmaller(First, Second, Smaller), Result is Larger - Smaller.
intdividelargerbysmaller(First, Second, Result) :- getlarger(First, Second, Larger),
getsmaller(First, Second, Smaller), Result is Larger // Smaller.
groupof4(List) :- nodups(List).
allrowsof4([X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16]) :-
groupof4([X1, X5, X9, X13]), groupof4([X2, X6, X10, X14]), %snip....
allcolumnsof4([X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16]) :-
groupof4([X1, X2, X3, X4]), groupof4([X5, X6, X7, X8]), %snip....
validnumbers4([X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16]) :-
validnumber4(X1), validnumber4(X2), %.....
kenken([X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16]) :-
%snip...
validnumbers4([X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16]),
X5 * X1 * X2 =:= 2,
%Additional Arithmetic contraints removed
intdividelargerbysmaller(X11, X15, 2), %Dividend =:= 2,
subtractsmallerfromlarger(X12, X16, 3), %Difference =:= 3,
X13 * X14 =:= 6,
allcolumnsof4([X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16]),
allrowsof4([X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16]).
对于已经定义的值,我使用语法:X1 is 5
,我把它放在我的代码的顶部,认为它会加快查找速度。
不必让我的代码变得非常复杂,有什么地方可以让它更有效率吗?
另外,我注意到将intdividelargerbysmaller和subtractsmallerfromlarger“Result is”更改为“Result =”会使查询花费很长时间/不解决,而如果我在第三个插槽中使用变量则会解决这两个问题。 / p>
此外,我注意到如果我将行和列检查移动到开头附近,查询会花费很长时间。
答案 0 :(得分:2)
您似乎正在使用 generate-then-test 方法,该方法首先生成候选项,然后检查它们是否是有效的解决方案。
将约束用于此任务会更有效。考虑使用有限域约束,它们由SWI-Prolog中的library(clpfd)
提供。
约束允许您在搜索具体解决方案之前以声明方式声明所有要求。他们可以在搜索之前和搜索过程中过滤不一致的元素,这通常会带来巨大的性能提升。