我目前正在开发一种算法,试图找到问题的所有解决方案,"有多少种方法可以将8位骑士放在一个8x8的电路板上,这样他们就不会互相攻击?"
现在我已经能够应用8 Queens 8x8主板解决方案来解决8个主教和8个Rooks的类似问题,这些问题来自我在网上找到的8 Queens算法。 (由于Bishops和Rooks在对角线上移动,或横向/纵向移动,它与Queens算法非常相似)
这是我到目前为止所拥有的。
solution([]).
solution([X/Y|Others]) :-
solution(Others),
member(Y, [1, 2, 3, 4, 5, 6, 7, 8]),
noattack(X/Y, Others).
noattack(_,[]).
noattack(X/Y, [X1/Y1|Others]):-
Y1 - Y =\= 2, X1 - X =\= 1
; Y - Y1 =\= 2, X1 - X =\= 1
; Y1 - Y =\= 2, X - X1 =\= 1
; Y - Y1 =\= 2, X - X1 =\= 1
; Y1 - Y =\= 1, X1 - X =\= 2
; Y - Y1 =\= 1, X1 - X =\= 2
; Y1 - Y =\= 1, X - X1 =\= 2
; Y - Y1 =\= 1, X - X1 =\= 2
; noattack(X/Y, Others).
template([1/Y1, 2/Y2, 3/Y3, 4/Y4, 5/Y5, 6/Y6, 7/Y7, 8/Y8]).
main :-
open('knights.out',write,ID),
( ( template(X), solution(X), write(ID,X), nl(ID), fail )
; close(ID)
).
基本上,我或多或少地使用标准的8-Queens Prolog算法对此算法进行建模,而不是将Y和Y1与潜在的"水平"进行比较。潜在的攻击和Y1-Y = \ = X1 - X和Y1-Y = \ = X - X1用于对角线潜在的攻击,就像我对女王所做的那样,这次我将下一个可能的点的每个确切位置与当前的任何地方进行比较骑士可以攻击,并将其统一到与攻击相结合的东西上。 (对不起,作为一个以Python为中心的CS学生,我真的很难解释这一点。如果你在这一点上不起床,请查看http://www.javaist.com/blog/2008/11/06/eight-queens-problem-in-prolog/)他很好地解释了8皇后算法是什么是
现在运行它的标准方法是。
?- template(A), solution(A).
然后在第一次统一时,按" a"为了打印出gprolog或swiprolog交互式控制台中的所有解决方案。对于8个皇后,只有32个解决方案,因此,一个可以在回溯序列中逐行进行并计数32以验证算法。但是对于8个骑士问题,将会有379978716个有效解决方案(根据http://oeis.org/search?q=nonattacking%20knights&sort=&language=&go=Search)。这就是"主要"最后的功能就在眼前。这基本上将每个统一打印到一个名为" knights.out,"的文件中。所以我可以在代码编辑器中打开它,看看是否有379978716行。
运行,进行一些计算,我计算出输出文件应该在14 gigs左右,但我的算法目前生成的文件大于70G(可能是无限循环,但我的Linux Partitian只能存储70G& #39; s所以我不知道)。但无论哪种方式,这个算法重复计算几次,我不知道如何解决这个问题。
任何帮助将不胜感激。 (对于Brevity,我没有上传八位主教和八位乐队的代码,但如果你有兴趣,我会把它们留在这里:https://github.com/gilgameshskytrooper/eightqueens)
答案 0 :(得分:1)
评论中指出的解决方案不正确。我会建议一些改进: 而不是:
noattack(X/Y, [X1/Y1|Others]):-
Y1 - Y =\= 2, X1 - X =\= 1;
Y - Y1 =\= 2, X1 - X =\= 1;
Y1 - Y =\= 2, X - X1 =\= 1;
Y - Y1 =\= 2, X - X1 =\= 1;
Y1 - Y =\= 1, X1 - X =\= 2;
Y - Y1 =\= 1, X1 - X =\= 2;
Y1 - Y =\= 1, X - X1 =\= 2;
Y - Y1 =\= 1, X - X1 =\= 2;
noattack(X/Y, Others).
你可以简单地使用abs并写:
noattack(X/Y, [X1/Y1|Others]):-
Y =\= Y1,
abs(Y1-Y) =\= abs(X1-X),
noattack(X/Y,Others).
在上面的谓词中,我们不需要写:X = \ = X1,因为由于模板,我们假设X是不同的。
这并没有回答这个问题,但这是一个更好的方式来编写它,它不适合评论...