Prolog 关于使用置换的8皇后解的一些解释
我正在为一个关于SWI Prolog实现的大学考试学习Prolog 我对这个版本的8皇后问题如何使用排列来解决这个问题有一些疑问:Prolog 关于使用置换的8皇后解的一些解释,prolog,n-queens,Prolog,N Queens,我正在为一个关于SWI Prolog实现的大学考试学习Prolog 我对这个版本的8皇后问题如何使用排列来解决这个问题有一些疑问: solution(Queens) :- permutation([1,2,3,4,5,6,7,8], Queens), safe(Queens). permutation([],[]). permutation([Head|Tail],PermList) :- permutation(Tail,PermTail), del(Head,PermList,P
solution(Queens) :-
permutation([1,2,3,4,5,6,7,8], Queens),
safe(Queens).
permutation([],[]).
permutation([Head|Tail],PermList) :-
permutation(Tail,PermTail),
del(Head,PermList,PermTail).
del(Item,[Item|List],List).
del(Item,[First|List],[First|List1]) :-
del(Item,List,List1).
safe([]).
safe([Queen|Others]) :-
safe(Others),
noattack(Queen,Others,1).
noattack(_,[],_).
noattack(Y,[Y1|Ylist],Xdist) :-
Y1-Y=\=Xdist,
Y-Y1=\=Xdist,
Dist1 is Xdist + 1,
noattack(Y,Ylist,Dist1).
在以前的解决方案中,我使用了这个解决方案模板:[1\Y1,2\Y2,3\Y3,4\Y4,5\Y5,6\Y6,7\Y7,8\Y8],它简单地说每个皇后必须在不同的行上,X计算可以被约束
这个版本的程序有很大的不同,因为我们可以观察到,为了防止垂直攻击,所有的皇后必须在不同的行上,所以每行有一个皇后
因此,在不丢失信息的情况下,我可以说,解决方案将是列表的排列:[1,2,3,4,5,6,7,8],其中每个元素表示女王的Y坐标
因此,在本例中,我仅通过Y坐标(其行索引)表示皇后位置
因此,我有解的关系,而不是说如果queen是[1,2,3,4,5,6,7,8]原始列表的预置换,并且如果这个置换是安全的(这个置换列表中的每个皇后都不会攻击其他皇后),那么列表queen就是一个解
好的,这很清楚…现在定义了安全关系
有一个基本情况表明,如果列表为空,那么这是安全的,因为没有攻击
通常情况下,列表不是空的。如果列表不是空的,我可以将其划分为[Queen | Others],其中Queen是列表中的第一个Queen,而Others是剩余的子列表……因此原始列表[Queen | Others]是安全的,如果子列表本身就是一个解决方案(如果它是安全的,如果其他人没有攻击)并且如果第一个项目皇后不攻击其他子列表中的其他皇后
好吧…直到现在我觉得我很清楚
现在我对noattack关系的定义有一些问题
问题是,我只通过它的Y坐标和X坐标来表示皇后位置
不明确地存在
我了解到,为了规避RAP演示文稿的这一限制,有以下概括(我希望理解得很好……我不太确定……)**我还知道,董事会的每一列上都必须有一个皇后,因此与列表中第一个皇后(皇后)和子列表中其他皇后的X距离必须为1**
其中,与第一个项目皇后和子列表Others的距离是与第一个项目皇后和离它最近的皇后的X距离,这符合我的推理吗
因此,如果皇后位于不同的列上,则noattack关系为真(对于构造而言始终为真),我可以表示必须位于不同的行上,表示与皇后和其他子列表中最近皇后的X距离为1
但是,如果我的推理是正确的,那么我在试图理解rap如何在代码的这一部分中表达这一点时会遇到很多困难:
noattack(Y,[Y1|Ylist],Xdist) :-
Y1-Y=\=Xdist,
Y-Y1=\=Xdist,
Dist1 is Xdist + 1,
noattack(Y,Ylist,Dist1).
我认为你的问题只在于这两行:
Y-Y1=/=Xdist,
Y1-Y=/=Xdist,
它检查具有Y的皇后是否以对角线方式以Xdist距离攻击该行中的皇后。(|Y-Y1 |=Xdist-->对角线攻击
)
攻击其他皇后的另一种方法是将它们放在同一行中,这不会简单地发生,因为解决方案是[1,2,3,4,5,6,7,8]
的排列。所以像[1,1,3,4,5,6,7,8]
这样的事情永远不会发生,这足以检查对角线
我希望它解决了这个问题
p、 请注意,Y1
是规则Safe/1
中Others
头部的Y坐标。因此它是一个皇后,其Xdist
首先为1,然后返回到其他行
澄清
我们讨论的是noattack/3
。您给它三个参数:
第一个:Y
当前女王的坐标
second:最右边的列表[Y1 | Ylist]
从列表中Y
之后的某个地方开始,并继续到主列表的末尾。(是,这是解决方案的子列表),以及
third:Xdist
是当前皇后(有Y)和皇后(有Y1,是第二个参数的头)之间的索引距离
第三个参数是必要的,因为没有它,我们无法检查当前皇后和具有Y1的皇后之间的对角交互。这是真正的基础数学,坐标系中只有两个点,只有自然数。假设这两个点以对角方式相互攻击,当且仅当abs(x1-x2)=abs(y1-y2)
如果你能很好地理解我的解释,请检查它是否被接受
P1=(3,4)和P2=(1,2)-->
这些点具有对角攻击,因为abs(3-1)=abs(4-2)=2
示例2
P1=(3,4)和P2=(7,0)-->
这些点具有对角攻击,因为abs(3-7)=abs(4-0)=4
这就是为什么我们同时检查Y1-Y=\=Xdist
和Y-Y1=\=Xdist
。因为每当有对角线攻击时,其中至少有一个是true
。当其中没有一个是true时,这意味着Y
的女王和Y1
的女王之间没有对角线攻击。因此我们可以继续d检查下一个皇后,即Ylist
的头
我希望这就足够了。这是一个非常简单的问题,只要仔细阅读它,如果你不能再次理解,试着自己在一张纸上追踪算法。这是一种总是有效的方法。我有