Ich habe eine Reihe von Paaren. Jedes Paar hat die Form (x, y), sodass x, y zu ganzen Zahlen aus dem Bereich gehören [0,n)
.
Wenn also n 4 ist, dann habe ich die folgenden Paare:
(0,1) (0,2) (0,3)
(1,2) (1,3)
(2,3)
Ich habe schon die Paare. Jetzt muss ich eine Kombination mit n/2
Paaren erstellen, sodass sich keine der ganzen Zahlen wiederholt (mit anderen Worten, jede ganze Zahl kommt in der endgültigen Kombination mindestens einmal vor). Es folgen Beispiele für eine richtige und eine falsche Kombination zum besseren Verständnis
1. (0,1)(1,2) [Invalid as 3 does not occur anywhere]
2. (0,2)(1,3) [Correct]
3. (1,3)(0,2) [Same as 2]
Kann mir jemand einen Weg vorschlagen, alle möglichen Kombinationen zu generieren, sobald ich die Paare habe.
algorithms
graphics
data-structures
computational-geometry
operating-systems
process-scheduling
algorithms
sorting
database-theory
relational-algebra
finite-model-theory
logic
automata
linear-temporal-logic
buchi-automata
complexity-theory
np-complete
decision-problem
machine-learning
algorithms
pattern-recognition
logic
formal-languages
formal-grammars
context-free
Ankit
quelle
quelle
Antworten:
Ein direkter Weg ist eine rekursive Prozedur, die bei jedem Aufruf Folgendes ausführt. Die Eingabe für die Prozedur ist eine Liste von Paaren, die bereits ausgewählt wurden, und eine Liste aller Paare.
Die Visualisierung dieses Algorithmus erfolgt mit einem Baum, dessen Pfade Sequenzen nicht überlappender Paare sind. Die erste Ebene des Baums enthält alle Paare, die 0 enthalten. Im obigen Beispiel ist der Baum
In diesem Beispiel geben alle Pfade durch den Baum tatsächlich korrekte Sammlungen an. Wenn wir jedoch beispielsweise das Paar (1,2) weglassen, hat der Pfad ganz rechts nur einen Knoten und entspricht der Suche in Schritt 3, die fehlschlägt.
Suchalgorithmen dieses Typs können für viele ähnliche Probleme der Aufzählung aller Objekte eines bestimmten Typs entwickelt werden.
Möglicherweise bedeutete das OP, dass sich alle Paare in der Eingabe befanden und nicht nur eine Gruppe von ihnen, wie in der Frage angegeben. In diesem Fall ist der Algorithmus viel einfacher, da nicht mehr überprüft werden muss, welche Paare zulässig sind. Es ist nicht einmal erforderlich, die Menge aller Paare zu generieren. Der folgende Pseudocode erfüllt die Anforderungen des OP. Hier ist die Eingabenummer, "Liste" beginnt als leere Liste, und "verdeckt" ist ein Array mit der Länge auf 0 initialisiert ist. Es könnte etwas effizienter gestaltet werden, aber das ist nicht mein unmittelbares Ziel.nn n
quelle
Sie können es iterativ lösen. Angenommen, Sie haben alle Lösungen für den Bereich . Dann können Sie einfach die Lösungen aus konstruieren . Die Größe wächst mit sehr schnell. Es kann daher sinnvoll sein, einen Generator zu schreiben, anstatt alle Sets im Speicher zu halten (siehe Python-Beispiel unten). [ 0 , n ) S n + 2 S n nSn [0,n) Sn+2 Sn n
Sie können alle Paare auflisten, indem Sie anrufen
quelle
Update : Meine frühere Antwort befasste sich mit zweigeteilten Graphen, nach denen das OP NICHT fragte. Ich lasse es im Moment als verwandte Informationen. Die sachdienlicheren Informationen beziehen sich jedoch auf perfekte Übereinstimmungen in nicht zweigeteilten Diagrammen.
In dieser Hinsicht gibt es eine schöne Umfrage von Propp , in der die Fortschritte (bis 1999) skizziert werden. Einige der Ideen in diesem Artikel und die zugehörigen Links könnten sich als nützlich erweisen. die TL; DR ist - es ist knifflig :)
--- Beginn der alten Antwort
Beachten Sie, dass Sie alle möglichen perfekten Übereinstimmungen in einem zweigeteilten Diagramm auflisten müssen. Hierzu gibt es viele verschiedene Algorithmen, insbesondere einen neueren aus dem ISAAC 2001 .
Die Grundidee besteht darin, mithilfe von Netzwerkflüssen eine perfekte Übereinstimmung zu finden und diese dann wiederholt mithilfe alternierender Zyklen zu ändern (weitere Informationen finden Sie im Lehrbuch zu Algorithmen im Kapitel zu Netzwerkflüssen).
quelle
Jedes Paar, das Sie auswählen, eliminiert zwei Reihen, aus denen Sie nicht mehr auswählen können. Diese Idee kann verwendet werden, um einen rekursiven Algorithmus (in Scala) einzurichten:
Dies kann sicherlich effizienter zum Ausdruck gebracht werden. Insbesondere wird die Idee, nicht ganze Zeilen für Kombinationen berücksichtigen zu müssen, vom Aufruf an nicht verwendet
filter
.quelle
Es gibt zwar bereits viele nette Antworten auf die Frage, aber ich denke, es wäre schön, auf den grundlegenden, allgemeinen Trick hinzuweisen, der dahintersteckt.
Es ist viel einfacher, eindeutige Kombinationen zu generieren, wenn Sie eine Gesamtreihenfolge der zu kombinierenden Elemente haben . Auf diese Weise ist die Eindeutigkeit garantiert, wenn wir nur sortierte Kombinationen zulassen. Es ist auch nicht schwer, die sortierten Kombinationen zu generieren - führen Sie einfach die übliche Brute-Force-Aufzählungssuche durch, sondern wählen Sie bei jedem Schritt nur Elemente aus, die größer sind als die, die bereits bei jedem Schritt ausgewählt wurden.
Die zusätzliche Komplikation bei diesem speziellen Problem ist der Wunsch, nur die Kombinationen der Länge n / 2 (der maximalen Länge) zu erhalten. Dies ist nicht schwer zu tun, wenn wir uns für eine gute Sortierstrategie entscheiden. Wenn wir zum Beispiel, wie in Carl Mummets Antwort ausgeführt, eine lexikografische Sortierung betrachten (von oben nach unten, von links nach rechts im Diagramm der Frage), leiten wir die Strategie ab, immer das nächste Element so zu nehmen, dass dessen erste Ziffer die ist kleinste noch unbenutzte Nummer.
Wir können diese Strategie auch erweitern, wenn wir Sequenzen anderer Länge erzeugen wollen. Denken Sie daran, dass bei der Auswahl eines nächsten Elements, dessen erste Nummer nicht die kleinste verfügbare ist, die Anzeige einer oder mehrerer Elementreihen in der sortierten Teilsequenz ausgeschlossen wird, sodass sich die maximale Länge der Prermutation entsprechend verringert.
quelle
Ich bin nicht sicher, ob dies das ist, wonach Sie fragen, aber wie ich verstehe, haben Sie alle ungeordnete Paare von und möchten die Liste aller Paare zählen, die decken Sie die Menge wobei eine gerade Zahl ist. Wir können uns dies als Kantenbedeckung von , dem vollständigen Graphen auf Ecken.(n2) [n]={1,⋯,n} [n] n Kn n
Außerdem scheint die Frage anzunehmen, dass jede Zahl in nur einmal in der Liste vorkommt. In diesem Fall betrachten wir nur die Abdeckungen, die perfekt zusammenpassen . Die Anzahl der Übereinstimmungen in einem Diagramm entspricht der Permanenz seiner Adjazenzmatrix . Wir müssen also berechnen .[n] Perm(Kn)
Es ist bekannt, dass permanent , aber dies ist im Allgemeinen der Fall. Für gibt es solche Listen.#P-complete Kn n!2n2
Der einfachste Weg, um all dies zu generieren, besteht darin, eine perfekte Übereinstimmung festzulegen und dann eine Permutation von anzuwenden. Dadurch werden jedoch viele Duplikate generiert.[n] quelle