这个n-queens Prolog解决方案如何运作?

时间:2017-09-11 16:46:38

标签: algorithm prolog n-queens

我试图理解来自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).

我很清楚如何生成初始列表。它是一个所有排列列表还是只是一个随机列表?此外,为什么需要安全和标签功能?感谢您的帮助。

1 个答案:

答案 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.

这些约束是立即执行,因为这些约束将值分配给ABC:这些约束被添加并且从那时起变量的域被修改,约束将旨在减少所涉及的其他变量的域。

例如,如果约束为A #\= BA in 1..3B in 1..3labeling/2将分配A = 1,则约束将触发,并将B的域名缩减为B in 2..3。因为它不再具有值1。

safe(L)之后,我们将所有约束添加到约束存储中,然后labeling/2可以开始搜索解决方案。