Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
处理Prolog代码输出_Prolog_Clpfd - Fatal编程技术网

处理Prolog代码输出

处理Prolog代码输出,prolog,clpfd,Prolog,Clpfd,我试图在这个页面上运行代码:在Linux终端上以swipl运行 :- use_module(library(clpfd)). n_queens(N, Qs) :- length(Qs, N), Qs ins 1..N, safe_queens(Qs). safe_queens([]). safe_queens([Q|Qs]) :- safe_queens(Qs, Q, 1), safe_queens(Qs). safe_queens([], _, _

我试图在这个页面上运行代码:在Linux终端上以swipl运行

:- use_module(library(clpfd)).

n_queens(N, Qs) :-
    length(Qs, N),
    Qs ins 1..N,
    safe_queens(Qs).

safe_queens([]).
safe_queens([Q|Qs]) :-
    safe_queens(Qs, Q, 1),
    safe_queens(Qs).

safe_queens([], _, _).
safe_queens([Q|Qs], Q0, D0) :-
    Q0 #\= Q,
    abs(Q0 - Q) #\= D0,
    D1 #= D0 + 1,
    safe_queens(Qs, Q0, D1).
以下命令工作:

?- n_queens(4, Qs), labeling([ff], Qs).
但不仅仅是n皇后区(4,Qs):

为什么这里需要
标记
零件?没有
标记
零件,能否获得正确的输出

对于较大的数字,只能得到解决方案的初始部分:

?- n_queens(20, Qs), labeling([ff], Qs).
Qs = [1, 3, 5, 14, 17, 4, 16, 7, 12|...] ;
Qs = [1, 3, 5, 18, 16, 4, 10, 7, 14|...] ;
...

如何获得较大数字的完整列表输出?此外,如何将所有数字汇总在一起,而不必按空格键来计算每个解?谢谢您的帮助。

确实解决了n个queens的n个queens问题:它构造了约束编程问题:它构造了n个变量(queens的列),并在这些queens之间添加了约束:例如,两个queens不能放在同一行上,也不是在同一条对角线上。如果我们将问题输出改写为更方便的输出,就会看到这一点:

A in 1..4,
abs(A-D)#\=3,
A#\=D,
abs(A-C)#\=2,
A#\=C,
abs(A-B)#\=1,
A#\=B,
D in 1..4,
abs(C-D)#\=1,
C#\=D,
abs(B-D)#\=2,
B#\=D,
C in 1..4,
abs(B-C)#\=1,
B#\=C,
B in 1..4.
所以我们看到了四个皇后(
A
B
C
D
)。每个皇后都应该在域
1..4
中,此外,我们还看到了不相等的约束,如
A\35;\=D
,以防止第一个皇后
A
与最后一个皇后
D
共享一列。最后,我们看到了像
abs(A-C)\=2
这样的约束,以防止第一个皇后
A
和第三个皇后
C
区分两列(诊断攻击)

下一步
标记/2
实际上将解决问题:它执行松弛(减少域)以及分支(为变量选取值或值的子范围)和回溯,以防约束失败。它将一直持续到找到解决方案为止,我们可以使用Prolog的回溯机制让
labeling/2
想出更多的解决方案

标记
因此给出了一个变量列表,旨在标记它们:为它们指定一个超出范围的值,以便满足所有约束

因此,与实际求解部分相比,问题构造部分通常速度非常快:很容易生成O(N)变量和O(N2)约束,但要找到一个满足所有约束的解决方案可能需要指数时间O(DN)

此外,如何将所有数字汇总在一起,而不必按空格键来计算每个解

您可以使用元谓词
findall/3
来实现:

all_n_queens(N,LL) :-
    findall(L,(n_queens(N,L), labeling([ff], L)),LL).
如何获得较大数字的完整列表输出

您可以设置
answer\u write\u选项
标志:

?- set_prolog_flag(answer_write_options,[max_depth(0)]).
true.

?- all_n_queens(5,LL).
LL = [[1,3,5,2,4],[1,4,2,5,3],[2,4,1,3,5],[2,5,3,1,4],[3,1,4,2,5],[3,5,2,4,1],[4,1,3,5,2],[4,2,5,3,1],[5,2,4,1,3],[5,3,1,4,2]].

不,n_queens的思想是构造一个约束编程问题<代码>标签
进行真正的放松和分支,并寻找解决方案。答案很好。谢谢为什么在这个解决方案中没有使用“标签”:@rnso:有。在
queens/2
谓词的末尾,它调用
标记([ffc],L)。
。当然,你可以在构造它的谓词中调用
标签
。我应该仔细检查一下。这个问题的解决方案是否与另一页上的解决方案基本相同:@rnso:是的,区别在于这个问题中的约束看起来像
abs(X-Y)\=2
,等等。而在另一个问题中,它看起来像
X\\=Y-2
X\\=Y+2
?- all_n_queens(5,LL).
LL = [[1, 3, 5, 2, 4], [1, 4, 2, 5, 3], [2, 4, 1, 3, 5], [2, 5, 3, 1, 4], [3, 1, 4, 2|...], [3, 5, 2|...], [4, 1|...], [4|...], [...|...]|...].
?- set_prolog_flag(answer_write_options,[max_depth(0)]).
true.

?- all_n_queens(5,LL).
LL = [[1,3,5,2,4],[1,4,2,5,3],[2,4,1,3,5],[2,5,3,1,4],[3,1,4,2,5],[3,5,2,4,1],[4,1,3,5,2],[4,2,5,3,1],[5,2,4,1,3],[5,3,1,4,2]].