2010-12-12 9 views
1

Ich schrieb ein Prolog-Programm, das alle möglichen Positionen von Elementen in einer zweidimensionalen Tabelle generiert. Die Anzahl der Elemente und die Tabellengröße sind angegeben.Prolog, entfernen sich wiederholende Ergebnisse in der Generation

My-Code ist:

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 es die Größe der Tabelle ist, N die Anzahl der Elemente ist, und die letzte ist das Ergebnis) Predicate geni Nummer X in [A;B] Intervall erzeugt.

Beispiel (2 Elemente in 2x2-Tabelle):

?- 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. 

My Tabelle Schachbrett ist und Elemente sind Ritter. In diesem Fall sind alle Elemente gleich, aber mein Programm "denkt", dass sie verschieden sind. Wie vermeidet man gleiche Ergebnisse? Wie folgt aus:

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

Antwort

4

Derzeit verwenden Sie not(member(...)) das Ergebnis enthält kein Duplikat zu gewährleisten. Um alle Permutationen eines Ergebnisses zu vermeiden, müssen Sie nur sicherstellen, dass die Elemente im Ergebnis geordnet sind.

Schritt 1 ist um einen Auftrag zu definieren, das heißt wie folgt aus:

% 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). 

Jetzt müssen Sie sicherstellen, dass das Element, das Sie der Liste hinzufügen möchten, ist „größer“ als alle anderen Elemente.

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). 

Ich bin mit dem build-in-Prädikat maplist alle Elemente der Liste zu testen. Aus dem Beispiel sollte klar sein, wie es funktioniert.

Wenn Sie die Reihenfolge umkehren möchten, implementieren Sie stattdessen einen "niedrigeren".

?- 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. 
Verwandte Themen