我试图理解来自N-Queens Problem..How far can we go?的这个n-queens Prolog解决方案是如何工作的(原始页面上没有评论)。我试图在我能理解的地方添加评论:
generate([],_). % A LIST BEING GENERATED
generate([H|T],N) :-
H in 1..N , % NOT CLEAR IF IT INCLUDES ALL COMBINATIONS OR PERMUTATIONS
generate(T,N).
lenlist(L,N) :-
lenlist(L,0,N).
lenlist([],N,N).
lenlist([_|T],P,N) :-
P1 is P+1,
lenlist(T,P1,N).
queens(N,L) :- % MAIN FN: SEND NUMBER OF QUEENS AND GET ANSWER LIST OF LISTS
generate(L,N),lenlist(L,N), % GENERATE LIST BASED ON N OF ALL COMBINATIONS
safe(L), % CHECK WHICH ONES ARE SAFE (NON-ATTACKING)
!,
labeling([ffc],L). % CHOOSE CORRECT ONES (WHY NEEDED IF ALREADY FOUND SAFE?)
notattack(X,Xs) :- % FNS TO FIND QUEENS NOT ATTACKING
notattack(X,Xs,1).
notattack(X,[],N).
notattack(X,[Y|Ys],N) :-
X #\= Y,
X #\= Y - N,
X #\= Y + N,
N1 is N + 1,
notattack(X,Ys,N1).
safe([]). % RECURSIVE FN TO FIND LISTS WITH NON-ATTACKING QUEENS
safe([F|T]) :-
notattack(F,T),
safe(T).
我很清楚如何生成初始列表。它是一个所有排列列表还是只是一个随机列表?此外,为什么需要安全和标签功能?感谢您的帮助。
答案 0 :(得分:3)
你的假设:
safe(L), % check which ones are safe (non-attacking)
(小写)错误:safe(L)
不检查两个皇后是否正在攻击:它会添加约束,以便皇后不会攻击(以及之后)标签。
Safe是一种递归方法,对于列表[A, B, C]
添加约束:
A #\= B,
A #\= B - 1,
A #\= B + 1,
A #\= C,
A #\= C - 2,
A #\= C + 2,
B #\= C,
B #\= C - 1,
B #\= C + 1.
这些约束是不立即执行,因为这些约束将值分配给A
,B
和C
:这些约束被添加并且从那时起变量的域被修改,约束将旨在减少所涉及的其他变量的域。
例如,如果约束为A #\= B
且A in 1..3
和B in 1..3
,labeling/2
将分配A = 1
,则约束将触发,并将B
的域名缩减为B in 2..3
。因为它不再具有值1。
在safe(L)
之后,我们将所有约束添加到约束存储中,然后labeling/2
可以开始搜索解决方案。