2010-12-12 3 views
1

Я написал программу пролога, которая генерирует все возможные положения элементов в двумерной таблице. Дано количество элементов и размер таблицы.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)). 

(там TSize является размер таблицы, N является количество элементов, а последний результат) предиката geni генерирует номер X в интервале [A;B].

Пример (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 проверить все элементы списка. Из примера следует ясно, как это работает.

Если вы хотите отменить заказ, используйте вместо него «нижний».

?- 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. 
Смежные вопросы