骑士';Prolog中的s巡视:超出堆栈限制

骑士';Prolog中的s巡视:超出堆栈限制,prolog,swi-prolog,knights-tour,Prolog,Swi Prolog,Knights Tour,在我尝试使用Warnsdorff规则优化程序后,编译器开始发出超出堆栈限制的命令。所有部分似乎都单独工作,但我不知道如何对其进行优化。我正在一台32位windows的旧笔记本电脑上编写一个程序,所以我不能像官方网站上写的那样手动增加堆栈的大小 knightpath(董事会[1/1|Path]):- 跳跃是板,板, |路(跳跃,[1/1|路径])。 方式(1,[X/Y]):- 在(1,5,X)之间, 介于(1,5,Y)之间。 |路(跳跃[X1/Y1,X2/Y2|路]:- Jumps1是Jumps-

在我尝试使用Warnsdorff规则优化程序后,编译器开始发出超出堆栈限制的命令。所有部分似乎都单独工作,但我不知道如何对其进行优化。我正在一台32位windows的旧笔记本电脑上编写一个程序,所以我不能像官方网站上写的那样手动增加堆栈的大小

knightpath(董事会[1/1|Path]):-
跳跃是板,板,
|路(跳跃,[1/1|路径])。
方式(1,[X/Y]):-
在(1,5,X)之间,
介于(1,5,Y)之间。
|路(跳跃[X1/Y1,X2/Y2|路]:-
Jumps1是Jumps-1,
|路(跳线1、[X2/Y2|路],
warnsdorff(X2/Y2,路径X1/Y1)。
跳转(X1/Y1,X2/Y2):-
((X1是X2+2;
X1是X2-2),
(Y1为Y2+1;
Y1为Y2-1);
(X1是X2+1;
X1是X2-1),
(Y1为Y2+2;
Y1是Y2-2),
在(1,5,X1)之间,
介于(1,5,Y1)之间。
warnsdorff(X1/Y1,路径,X2/Y2):-
查找可能性(X1/Y1,路径,位置),
找到最佳位置(ux1/Y1路径),位置,X2/Y2)。
找到最佳(N,路径,[X/Y],X/Y):-
查找可能性(X/Y,路径,位置),
长度(位置N)。
找到最佳(N1,路径,[X/Y |列表],X/Y):-
找到最佳(N2,路径,列表,u),
查找可能性(X/Y,路径,位置),
长度(位置N1),
N1=N2。
查找位置(X1/Y1,路径,位置):-
findall(X2/Y2,跳跃(X2/Y2,X1/Y1),所有,
过滤路径(所有路径、路径、位置)。
过滤器路径([],[],[])。
过滤器路径([X/Y |全部切换],路径[X/Y |位置]:-
非(成员(X/Y,路径)),
过滤路径(所有路径、路径、位置)。
过滤器路径([X/Y全切],路径,位置):-
成员(X/Y,路径),
过滤路径(所有路径、路径、位置)。
这就是编译器产生的结果

ERROR: Stack limit (0.5Gb) exceeded
ERROR:   Stack sizes: local: 0.1Gb, global: 42.7Mb, trail: 0Kb
ERROR:   Stack depth: 1,863,822, last-call: 0%, Choice points: 3
ERROR:   In:
ERROR:     [1,863,822] user:the_way(-1863788, [length:1|_22365890])
ERROR:     [1,863,821] user:the_way(-1863787, '<garbage_collected>')
ERROR:     [1,863,820] user:the_way(-1863786, '<garbage_collected>')
ERROR:     [1,863,819] user:the_way(-1863785, '<garbage_collected>')
ERROR:     [1,863,818] user:the_way(-1863784, '<garbage_collected>')
错误:超出堆栈限制(0.5Gb)
错误:堆栈大小:本地:0.1Gb,全局:42.7Mb,跟踪:0Kb
错误:堆栈深度:1863822,上次调用:0%,选择点:3
错误:在:
错误:[1863822]用户:路径(-1863788,[长度:1 | 22365890])
错误:[1863821]用户:路径(-1863787,,)
错误:[1863820]用户:路径(-1863786,,)
错误:[1863819]用户:路径(-1863785,,)
错误:[1863818]用户:路径(-1863784,,)

回溯已经显示出错误:调用
的方法是:


问题是,Warnsdorff的规则没有为第一个(堆栈的最后一个)平方为1/1的情况提供解决方案。我得写信

knightpath(Answ) :-
    Jumps is Board * Board,
    the_way(Jumps, Path),
    reverse(Path, Answ).
...

the_way(1, [1/1]).

顺便说一句,如果我按照Willem Van Onsem的建议编写,那么就可以避免错误,编译器只会输出'false'。

您可能忘了检查方块是否已经被访问过,因此,骑士在两个方块之间无休止地跳跃。此外,您不必签入
,如果
跳跃
,则路径
仍然比
1
大。一切都变得简单多了,但感谢您的回答,这确实有助于找到解决方案。
[1,863,822] user:the_way(-1863788, [length:1|_22365890])
the_way(1, [X / Y]) : -
    between(1, 5, X),
    between(1, 5, Y).
the_way(Jumps, [X1 / Y1, X2 / Y2 | Path]) : -
    Jumps > 1,
    Jumps1 is Jumps - 1,
    the_way(Jumps1, [X2 / Y2 | Path]),
    warnsdorff(X2 / Y2, Path, X1 / Y1).
knightpath(Answ) :-
    Jumps is Board * Board,
    the_way(Jumps, Path),
    reverse(Path, Answ).
...

the_way(1, [1/1]).