私は大学の試験のために Prolog を勉強していますが、次の演習で問題があります。
私は 8-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]) :-
Y =\= Y1, % Q e Q1 sono su righe diverse
% Q e Q1 sono su diagonali diverse:
Y1-Y =\= X1-X,
Y1-Y =\= X-X1,
% Q non attacca regine nella sottolista Others:
noattack( X/Y, Others).
% TEMPLATE DELLE SOLUZIONI: c'è una regina su ogni colonna:
template([1/Y1,2/Y2,3/Y3,4/Y4,5/Y5,6/Y6,7/Y7,8/Y8]).
わかりました、このプログラムは非常に単純に見えます: 互いに攻撃してはならない女王のリストがあります。
クイーンのリストが空の場合、クイーンがリスト内の別のクイーンを攻撃する可能性はないため、空のリストは問題の解決策です (解決策の基本ケースです)。
*クイーンのリストが空でない場合、[X/Y|その他] に分割できます。ここで、X/Y は、リスト内の最初のクイーンのボード上のラッププレゼンス位置です * (位置はカップルによるラッププレゼンスエンドです (X,Y ) ここで、X は列、Y は行です)
したがって、次の関係が真である場合、リスト [X/Y|Others] が問題の解決策であることは TRUE です。
サブリスト Others はそれ自体が解決策です (Others には、リスト内の他の女王を攻撃する女王は含まれません)
Y は 1 から 8 までの整数値に属します(8 行あるため)
リストの最初のクィーンは、サブリストの他のクィーンを攻撃しません その他
次に、クイーンが別のクイーンを攻撃しないことが真であるといつ言えるかを指定するnoattack関係が定義されます (これは非常に単純です: それらは同じ行、同じ列、同じ場所にとどまることはできません)。対角線)
最後に、X 値を 1 から 8 の値で制限することで、私の生活を簡素化するソリューション テンプレートがあります (2 つのクイーンが同じ列にとどまることはできないことがわかっているため、ソリューション内のすべてのクイーンは別の列にとどまります)。他のすべての女王)
したがって、最大の問題は、列数を指定する行にあると思います。
member(Y,[1,2,3,4,5,6,7,8])
そして、ソリューション テンプレートを定義する行で:
template([1/Y1,2/Y2,3/Y3,4/Y4,5/Y5,6/Y6,7/Y7,8/Y8]).
可変数のクイーンを処理するために以前のソリューションを拡張する方法についてはわかりません。