Wie generieren Sie die power-set aus einer vorgegebenen Liste?
Ich versuche zu generieren, die eine Sammlung aller 2^N - 1 mögliche Kombinationen eines gegebenen Liste der Länge N. Die Sammlung anzeigen der Anzahl von Elementen in einer Kombination, um eine geordnete Liste von Kombinationen mit Kombinationen der bestimmten Länge. Zum Beispiel, für die Liste:
[A, B, C, D]
Möchte ich zum generieren der Karte:
{
1 -> [{A}, {B}, {C}, {D}]
2 -> [{A, B}, {A, C}, {A, D}, {B, C}, {B, D}, {C, D}]
3 -> [{A, B, C}, {A, B, D}, {A, C, D}, {B, C, D}]
4 -> [{A, B, C, D}]
}
Den generierten Datenbank sollte erhalten die original-Reihenfolge (wo []
stellt eine geordnete Reihe (List
), und {}
stellt eine un-geordnete Gruppe (Set
)), und führen Sie so schnell wie möglich.
Ich kämpfte mit einigen rekursiven code den ganzen Tag (ich weiß, die Umsetzung sollte rekursiv sein), aber konnte nicht auf den Grund gehen.
Gibt es eine Referenz, die ich verwenden kann/eine fertige Implementierung eines solchen Algorithmus?
- Ich bin mir nicht sicher, Rekursion ist besonders hilfreich für dieses problem. Versuchen Sie, darüber nachzudenken iterativ statt für ein bisschen.
- Wenn Sie es tun, iterativ, beachten Sie, dass Sie erzeugen kann die Größe
i
und GrößeN-i
Listen gleichzeitig. Denken in Bezug auf die Partitionierung der Liste in zwei Teilmengen, und das hinzufügen jede Teilmenge einer Ihrer Listen. - Das ist ein interessanter Ansatz, werde ich prüfen.
- Bin ich die Abstimmung schließen diese Frage, da es angefordert wird, von der off-site-resource.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Was du suchst, ist im wesentlichen die power set (minus vielleicht die leere Menge). Guave hat tatsächlich eine Methode dafür:
Setzt.powerSet()
. Sie können die Quelle desLegt fest
Klasse, um zu sehen, wie die Methode implementiert wird, wenn Sie schreiben wollen, es sich selbst; Sie könnte, muss es geändert werden, um wieder eineList
statt einerSet
da Sie bewahren wollen bestellen, obwohl diese änderung sollte nicht zu drastisch. Wenn Sie die macht gesetzt, es sollte trivial zu Durchlaufen und konstruieren Sie die Karte, die Sie wollen.Was du fragst ist Generierung aller möglichen Teilmengen einer Menge. Sie können denken, es als Iteration über alle möglichen binären arrays der Größe N (Größe der Liste):
Warum ist das so? Die Antwort ist einfach: 1 zeigt an, dass ein element existiert in einer Untergruppe, während 0 bedeutet, dass es nicht vorhanden ist.
So, der grundlegende Algorithmus ist offensichtlich:
Wo
calculate_subset_based_on_bin_array
iteriert aufb
unds
und wählt Elemente auss[current]
wob[current] = 1
.Oben gedruckt wird, alle vorhandenen Untergruppen. Sie können die Anpassung dieses Algorithmus, um die Karte, die Sie gefragt haben, für Ihre Frage.
AUSGABE
Hier ist ein code, den ich getestet habe, erzeugen alle möglichen Kombinationen aus dem gegebenen array:
[a, b]
und[b, a]
werden nicht beide in der Ausgabe angezeigt werden (weila
ist vorb
im Eingang, und die[b, a]
nicht halten die ursprüngliche Reihenfolge).Gibt es mehrere Möglichkeiten, um dieses problem zu lösen, aber die einfachste Möglichkeit IMHO ist die Verwendung von Rekursion. Unten habe ich die iterative und rekursive Ansätze zur Lösung des Problems der Erzeugung aller Kombinationen von einem Satz. Die Allgemeine Idee, die für beide Ansätze zu generieren, die Menge der Indizes, die gehören zu den Elementen, die Sie auswählen möchten.
Für den rekursiven Ansatz, den Sie verfolgen wollen drei Stücke von Informationen: Ein boolean-array, der angibt, ob ein Element ausgewählt wurde oder nicht, die position, die Sie sind in der Liste der Elemente und eine variable r-tracking die Anzahl der Elemente noch zu wählen. Dann solange r != 0 (Bedeutung, die Sie noch auswählen müssen, um r Elemente Oberfläche dieser Kombination) Sie backtrack ein element selektiert haben Sie noch nicht ausgewählt ist und bewegen uns in das array.
Den code unten gezeigte war aus meiner github repo.
Ich den code testen, vorgeschlagen von Elist und ich fand Fehler.
Hier ist ein Vorschlag für die Korrektur : (in den letzten sonst von der Funktion getPermutation(), habe ich zwei änderungen vorgenommen)
}
Dieses Power-set ist eine der übung, die im Buch SICP "Structure und Interpretation of Computer Programming".Jeder Programmierer Lesen sollte man.
OP die Lösung bewegt von der Frage zur Antwort: