2010-12-12 8 views
1

2次元の表の要素の可能な位置をすべて生成するプロローグプログラムを作成しました。要素数とテーブルサイズが与えられます。Prolog、生成時に繰り返し結果を削除する

私のコードは次のとおり

geni(Min, Min, Max) :- Min =< Max. 
geni(Min, X, Max) :- Max >= Min, MinInc is Min+1, geni(MinInc, X, Max). 
generate(_, 0, []) :- !. 
generate(TSize, N, [X|Tail]) :- NDec is N-1, generate(TSize,NDec, Tail), 
           X=k(X1,Y1), geni(1,X1,TSize), geni(1,Y1,TSize), 
           not(member(X, Tail)). 

述語geni間隔[A;B]で数Xを生成する(TSizeN、要素の数であり、そして最後の結果であり、表のサイズがあります)。

例(2×2の表2要素):

?- generate(2, 2, R). 
R = [k(1, 1), k(1, 2)] ; 
R = [k(1, 1), k(2, 1)] ; 
R = [k(1, 1), k(2, 2)] ; 
R = [k(1, 2), k(1, 1)] ; 
R = [k(1, 2), k(2, 1)] ; 
R = [k(1, 2), k(2, 2)] ; 
R = [k(2, 1), k(1, 1)] ; 
R = [k(2, 1), k(1, 2)] ; 
R = [k(2, 1), k(2, 2)] ; 
R = [k(2, 2), k(1, 1)] ; 
R = [k(2, 2), k(1, 2)] ; 
R = [k(2, 2), k(2, 1)] ; 
false. 

マイテーブルがチェスボードであり、要素が騎士です。この場合、すべての要素は同じですが、私のプログラムはそれらが異なると「考える」。 等しい結果を避けるにはどうすればよいですか?このように:

R = [k(1, 1), k(1, 2)] ; 
R = [k(1, 2), k(1, 1)] ; 

答えて

4

現在、not(member(...))を使用して、結果に重複が含まれていないことを確認しています。結果のすべての順列を取得しないようにするには、結果内の要素が順序付けされていることを確認するだけです。

ステップ1は、すなわちこのように、順序を定義することです:

% A knight 1 is "bigger" than knight 2 
% if the X-value is bigger or X is equal and Y is bigger 
is_bigger(k(X1, Y1), k(X2, Y2)) :- 
    X1 > X2; (X1 = X2, Y1 > Y2). 

今、あなたはあなたがリストに追加する要素は、他のすべての要素よりも「大きな」であることを確認する必要があります。

geni(Min, X, Max) :- between(Min, Max, X). 
generate(_, 0, []) :- !. 
generate(TSize, N, [X|Tail]) :- X=k(X1,Y1), NDec is N-1, 
          generate(TSize,NDec, Tail), 
          geni(1,X1,TSize), 
          geni(1,Y1,TSize), 
          maplist(is_bigger(X), Tail). 

私は、リストのすべての要素をテストするために、ビルドイン述語maplistを使用しています。例から、それがどのように機能するのかが明確になるはずです。

注文を元に戻したい場合は、代わりに「lower」を実装します。

?- generate(2, 2, T). 
T = [k(1, 2), k(1, 1)] ; 
T = [k(2, 1), k(1, 1)] ; 
T = [k(2, 2), k(1, 1)] ; 
T = [k(2, 1), k(1, 2)] ; 
T = [k(2, 2), k(1, 2)] ; 
T = [k(2, 2), k(2, 1)] ; 
false. 
関連する問題