Wie kann ich alle möglichen Kombinationen der Elemente einer Liste erzeugen?
Zum Beispiel die Liste gegeben [1,2,3], ich will comb([1,2,3], L).
ein Prädikat entwerfen mit der Form, die die folgende Antwort für L zurückgeben sollte:
[1]
[2]
[3]
[1,2]
[2,1]
[1,3]
[3,1]
[2,3]
[3,2]
[1,2,3]
[1,3,2]
[2,1,3]
[2,3,1]
[3,1,2]
[3,2,1]
Permutierte Kombinationen der Elemente einer Liste - Prolog
Antwort
Worum Sie bitten, beinhaltet sowohl Kombinationen (Auswählen einer Teilmenge) als auch Permutationen (Umordnen der Reihenfolge) einer Liste.
Ihre Beispielausgabe impliziert, dass die leere Liste nicht als gültige Lösung betrachtet wird, daher werden wir sie in der folgenden Implementierung ausschließen. Überdenken Sie, ob dies ein Versehen war. Auch diese Implementierung erzeugt die Lösungen in einer anderen Reihenfolge als Ihre Beispielausgabe.
comb(InList,Out) :-
splitSet(InList,_,SubList),
SubList = [_|_], /* disallow empty list */
permute(SubList,Out).
splitSet([ ],[ ],[ ]).
splitSet([H|T],[H|L],R) :-
splitSet(T,L,R).
splitSet([H|T],L,[H|R]) :-
splitSet(T,L,R).
permute([ ],[ ]) :- !.
permute(L,[X|R]) :-
omit(X,L,M),
permute(M,R).
omit(H,[H|T],T).
omit(X,[H|L],[H|R]) :-
omit(X,L,R).
Getestet mit Amzi! Prolog:
?- comb([1,2,3],L).
L = [3] ;
L = [2] ;
L = [2, 3] ;
L = [3, 2] ;
L = [1] ;
L = [1, 3] ;
L = [3, 1] ;
L = [1, 2] ;
L = [2, 1] ;
L = [1, 2, 3] ;
L = [1, 3, 2] ;
L = [2, 1, 3] ;
L = [2, 3, 1] ;
L = [3, 1, 2] ;
L = [3, 2, 1] ;
no
Hinweis: Dies ist einfach zu tun, wenn Sie ein Prädikat inselt(X,Y,Z)
geschrieben haben, die, wenn eine Einfügung hält von Y
in X
gibt Z
:
inselt([E|X], Y, [E|Z]) :- inselt(X,Y,Z).
inselt(X, Y, [Y|X]).
Dann comb/3
rekursiv inselt/3
mit kodiert werden kann.
gibt es einen vordefinierten Prädikat Permutation genannt ...
1 ?- permutation([1,2,3],L).
L = [1, 2, 3] ;
L = [2, 1, 3] ;
L = [2, 3, 1] ;
L = [1, 3, 2] ;
L = [3, 1, 2] ;
L = [3, 2, 1] .
2 ?- listing(permutation).
lists:permutation([], [], []).
lists:permutation([C|A], D, [_|B]) :-
permutation(A, E, B),
select(C, D, E).
lists:permutation(A, B) :-
permutation(A, B, B).
true.
hoffe, das hilft ..
Es ist definitiv hilfreich zu sehen, wie man Permutationen beschreiben kann (+1!). Ein lehrreiches Merkmal dieses Codes ist, dass "Permutation/3" * nicht * tail rekursiv ist, und dass das Austauschen der zwei Ziele typischerweise die Laufzeit um einen großen Spielraum erhöht. Es ist auch elegant und schön anzusehen, nur mit reinem Code. Beachten Sie jedoch, dass OP etwas anderes verlangt: Die Frage betrifft Permutationen von Subsequenzen, die nicht notwendigerweise die gesamte Liste umfassen. Schauen Sie sich @ repeats kurze, elegante und pure Lösung an! – mat
rein bleiben von comb/2
definieren, basierend auf same_length/2
, prefix/2
, foldl/4
und select/3
:
comb(As,Bs) :- same_length(As,Full), Bs = [_|_], prefix(Bs,Full), foldl(select,Bs,As,_).
Hier ist die Beispielabfrage durch die OP gegeben:
?- comb([1,2,3],Xs).
Xs = [1]
; Xs = [2]
; Xs = [3]
; Xs = [1,2]
; Xs = [1,3]
; Xs = [2,1]
; Xs = [2,3]
; Xs = [3,1]
; Xs = [3,2]
; Xs = [1,2,3]
; Xs = [1,3,2]
; Xs = [2,1,3]
; Xs = [2,3,1]
; Xs = [3,1,2]
; Xs = [3,2,1]
; false.
Ok! Was aber, wenn die als erstes Argument angegebene Liste Duplikate enthält?
?- comb([1,1,2],Xs).
Xs = [1]
; Xs = [1] % (redundant)
; Xs = [2]
; Xs = [1,1]
; Xs = [1,2]
; Xs = [1,1] % (redundant)
; Xs = [1,2] % (redundant)
; Xs = [2,1]
; Xs = [2,1] % (redundant)
; Xs = [1,1,2]
; Xs = [1,2,1]
; Xs = [1,1,2] % (redundant)
; Xs = [1,2,1] % (redundant)
; Xs = [2,1,1]
; Xs = [2,1,1] % (redundant)
; false.
Nicht ganz! Können wir obige redundante Antworten loswerden? Ja, verwenden Sie einfach selectd/3
!
comb(As,Bs) :- same_length(As,Full), Bs = [_|_], prefix(Bs,Full), foldl(selectd,Bs,As,_).
also lasst uns wieder mit der verbesserten Umsetzung der comb/2
obige Abfrage erneut ausführen!
?- comb([1,1,2],Xs).
Xs = [1]
; Xs = [2]
; Xs = [1,1]
; Xs = [1,2]
; Xs = [2,1]
; Xs = [1,1,2]
; Xs = [1,2,1]
; Xs = [2,1,1]
; false.
Große Lösung, +1! Ich hoffe, wir werden bald eine Bibliothek sehen, die all diese reinen Elementarprädikate enthält! 'library (purple)': * Reine Prolog-Bibliothek (elementar) *? – mat
- 1. Elemente einer Liste in Prolog
- 2. Prolog Vergleichen Elemente der Liste
- 3. Prolog: Wie alle Kombinationen bekommen
- 4. Einzigartige Elemente in der Liste (Prolog)
- 5. Einige Kombinationen der gegebenen Liste in Prolog erhalten
- 6. Prolog: Filtern einer Liste?
- 7. Einzigartige Kombinationen der Liste
- 8. Verdoppelung aller Elemente in einer Liste in Prolog
- 9. Prolog - Fügen Sie einige Elemente einer Liste auf eine andere
- 10. Prolog: Liste der Objekte
- 11. Alle möglichen Kombinationen von Elementen einer Liste
- 12. Filterelemente einer Liste in Prolog
- 13. Prolog Listen in einer Liste vereinigen
- 14. Prolog-Liste, überprüfen Sie die Einträge in der Liste
- 15. Prolog findall Liste der Prädikate
- 16. Rückgabeelemente aus der Liste der Listen - Prolog
- 17. Inkrementelle Elemente in SWI-Prolog
- 18. Summe Produkt von Kombinationen in einer Liste
- 19. eine Liste mit Listen in einer anderen Liste in Prolog
- 20. Kombinationen aufeinanderfolgender Elemente eines Arrays
- 21. generieren alle Kombinationen von einer Liste in Python
- 22. Prolog - das Produkt einer Liste finden
- 23. Zwei Sterne in einer Prolog-Liste
- 24. Anzahl der möglichen Kombinationen in einer Partitionierung
- 25. 3 konsekutive Elemente in Prolog mit concat
- 26. Prolog Sortierung einer Liste der Struktur, arithmetischer Fehler
- 27. Prolog Liste der Prädikate zur Liste der Listen
- 28. Prolog: Integer aus der Liste entfernen
- 29. Prolog: Get Liste der Wörter, die insgesamt X Silben
- 30. Prolog Liste aufeinanderfolgende Paare
[1] wird normalerweise nicht eine Kombination von [1,2,3] genannt: Ich vermute, das ist nicht das, was Sie meinen. –