Frage

stieß ich auf dieses Problem, wenn einige enthusiastische Programmierung zu tun. Das Problem kann wie folgt ausgedrückt werden:

  

Für eine multiset A, sei P (A) bezeichnen die   alle möglichen Permutationen von A eingestellt   P (A) ist natürlich unterteilt in   disjunkte Teilmengen, die Gleichwertigkeit sind   Klassen, mit der Äquivalenzrelation   Sein „kann durch kreisförmige Verschiebung in Beziehung gesetzt werden.“ aufzählen all   diese Äquivalenzklassen durch Erzeugen   genau ein Mitglied aus jedem von ihnen.

Betrachten wir zum Beispiel die multiset {0, 1, 1, 2}. Die Permutationen „0112“ und „1201“ sind eindeutige Permutationen, aber die letztere kann kehrt durch Kreisverschiebung des ersteren und umge gefunden werden. Der gewünschte Algorithmus sollte beide nicht erzeugen.

Natürlich ein Brute-Force-Ansatz möglich: nur Permutationen erzeugen - unabhängig von Kreis Vervielfältigung - eine der multiset Permutation Algorithmen und Verwerfungs Vervielfältigungen gefunden im Vergleich mit früheren Ergebnissen. Jedoch neigt dies ineffizient in der Praxis zu sein. Der gewünschte Algorithmus sollte minimal erforderlich, wenn nicht Null Buchhaltung.

Jede Einblicke in dieses Problem ist tief geschätzt.

War es hilfreich?

Andere Tipps

Es ist etwas einfacher für diesen von unten nach oben zu gehen:

, wenn A nur 1 Element enthält, P (A) enthält auch eine Permutation. es ist einfach, die gleichen Arbeiten zu sehen, wenn A nur zwei Elemente enthält.

Nun lassen Sie uns annehmen, dass Sie bereits alle P haben (A) für A mit n Elementen, und fügen Sie ein Element. es kann in einem der Permutationen in P (A).

in einem n-Spots gehen

ich glaube, diese Idee ist ziemlich direkt an einen rekursiven Algorithmus in der Sprache Ihrer Wahl übersetzt, und hoffe, meine Erklärung war deutlich genug.

EDIT: Ich weiß, ich Art ignoriert die Tatsache, dass eine doppelte Elemente enthalten kann, aber immer noch Gedanken über diesen Teil:)

nur als obwohl - wenn Sie A vor dem Start der Permutation Algorithmus sortiert, ich denke, diese Duplikate beseitigen könnten. (Immer noch darüber nachgedacht zu)

Für ein intuitives Verständnis des Problems denke ich, dass wir diese Metapher verwenden können. Visualisieren eine Uhr an der Wand, sondern 12 Positionen aufweisen, auf dem Gesicht hat n, wobei n die Anzahl der Elemente im Set.

Dann wird die jede Äquivalenzklasse nur eine Zuordnung eines Elements A zu einer Position auf dem Ziffernblatt.

Sobald eine andere Permutation von der gleichen Äquivalenzklasse zugeordnet ist, kann durch einfaches Drehen der Uhr an der Wand erzeugt werden.

Um eine weitere unabhängige Permutation von A zu erzeugen Sie benötigen ein Element haben, zumindest ein weiteres Element überspringen.

Jetzt ist der Algorithmus, wie ich es sehe zum Beispiel mit einer Zuordnung wäre zu beginnen sagen wir vier Elemente in A hatten = {a, b, c, d} und wir vergeben sie an die 12, 3, 6 und 9 Positionen jeweils für visuelle Klarheit. Dann ist unsere erste Operation Swap a und b sein würde. dann a und c, dann a und d, dann würden wir es mit dem Element in der 3-Position b und Swap gehen, die jetzt c ist.

Dadurch, bis wir erreichen d einen Vertreter aus allen Äquivalenzklassen erzeugen würde.

Dies dauert nicht um Duplikate, aber es sollte viel effizienter sein als alle Permutationen von A zu erzeugen.

Der Gedanke, dass Federn meiner Meinung nach ist, dass für jede Menge, die mindestens ein Element, das nur einmal erscheint, dann können Sie für alle Antworten dieses Element in der ersten Position der Liste gesetzt und erzeugen dann alle Permutationen der restlichen die Zahlen. Dies ist eine ziemlich triviale Lösung, da dadurch Ihr erstes Element ist einzigartig, sicherstellt, dass es keine Äquivalente von Zyklus der Elemente zu verschieben. Offensichtlich werden alle Lösungen, die Sie generieren müssen eindeutig sein.

Das offensichtliche Problem ist, dass, wenn Sie keine Elemente aufweisen, die Singles sind dann nach unten vollständig diese bricht. Der Hauptgrund dafür, dass ich diese in gesetzt ist becasue es mehrere andere Lösungen sind den Umgang mit keine Duplikate und ich denke, das ist ein effektiver ist, als sie (löst mehr Fälle), so ist erwähnenswert. Es ist auch ziemlich einfach in Bezug auf das Verständnis, wie es funktioniert und deren Umsetzung. Ich hoffe nur, meine Argumentation Klang. ; -)

Bearbeiten für weitere Gedanken:

Es fällt mir, dass dieses Prinzip auf die Situation erweitert werden kann, wo Sie Duplikate zu einem gewissen Grad haben.

Wenn Sie ein Element nehmen (wir nehmen nun an wiederholt werden), die Sie bei nur seine Permutationen aussehen können und welche für Zyklusverschiebung Wiederholung erlauben würde, nach wie vor assumign, dass man „Schloss“ ein an Ort und Stelle ohne Beschränkung der Allgemeinheit. zB wenn Sie insgesamt 6 Elemente haben und A erscheint zweimal in diesem Set können Sie haben:

AAXXXX, AXAXXX, AXXAXX, AXXXAX, AXXXXA

Die letzte davon ist die gleiche wie die erste (innerhalb der zyklischen Verschiebung) so ignoriert werden kann, ditto die zweite und vierte. Die dritte (AXXAXX) kann durch drei gefahren werden, um sich zurück zu bekommen, so das Potenzial für Zyklen hat. Die ersten beiden kann nie ganz gleich Anlass zu Zyklen geben, wie oft Sie Zyklus sie so aber Sie verteilen die übrigen Elemente, die Sie nur sicherstellen müssen, dass sie einzigartig sind Verteilungen und Sie werden garantiert durch Zyklus Ergebnisse einzigartig zu erhalten.

Für das dritte Muster das kann Zyklus (AXXAXX) Sie würde Element B aussehen müssen, und wiederholen Sie den Vorgang für alle. Dieses Mal Unfortuantely würden Sie nicht in der Lage sein, den Trick zu verwenden, der den ersten Wertes Sperrzeit zu speichern.

Ich bin nicht 100% sicher, wie Sie darum, diese in ein voll funktionsfähiges Programm gehen würde, aber es ist einige thougths, wie man rohe Gewalt zu vermeiden ist.

Ich schlage vor, hier eine Lösung in Python implementiert

import itertools as it

L = ['a','b','c','d']
B = it.combinations(L,2)
swaplist = [e for e in B]
print 'List of elements to permute:' 
print swaplist
print
unique_necklaces = []
unique_necklaces.append(L)
for pair in swaplist:
    necklace = list(L)
    e1 = pair[0]
    e2 = pair[1]
    indexe1 = L.index(e1)
    indexe2 = L.index(e2)
    #swap
    necklace[indexe1],necklace[indexe2] = necklace[indexe2], necklace[indexe1]
    unique_necklaces.append(necklace)

for n in unique_necklaces:
    # Commented code display the rotation of the elements in each necklace
    print 'Necklaces'
    print n#, [n[-r:]+n[:-r]for r in (1,2,3)]   

Die Idee ist, verschiedene Ketten von Permutationen von zwei Elementen zu bauen. Für eine Liste der vier Elemente a, b, c, d die Algo ergibt:

['a', 'b', 'c', 'd']
['b', 'a', 'c', 'd']
['c', 'b', 'a', 'd']
['d', 'b', 'c', 'a']
['a', 'c', 'b', 'd']
['a', 'd', 'c', 'b']
['a', 'b', 'd', 'c']
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top