Guter Algorithmus zum Kombinieren von Elementen aus N Listen zu einem mit ausgewogener Verteilung?

7

Nehmen wir an, ich habe die folgenden drei Listen

A1
A2
A3

B1
B2

C1
C2
C3
C4
C5

Ich möchte sie in einer einzigen Liste zusammenfassen, wobei die Elemente aus jeder Liste so gleichmäßig wie möglich verteilt sind:

C1
A1
C2
B1
C3
A2
C4
B2
A3
C5

Ich benutze .NET 3.5 / C #, aber ich suche mehr danach, wie man dann spezifischen Code anwendet.

EDIT: Ich muss die Reihenfolge der Elemente aus den ursprünglichen Listen beibehalten.

    
John Sheehan 05.12.2008, 19:26
quelle

7 Antworten

17
  1. Nehmen Sie eine Kopie der Liste mit den meisten Mitgliedern. Dies wird die Zielliste sein.

  2. Dann nimm die Liste mit der nächstgrößeren Nummer.

  3. Teilen Sie die Ziellistenlänge durch die kleinere Länge, um einen Bruchwert von größer als eins zu erhalten.

  4. Pflegen Sie für jedes Element in der zweiten Liste einen Float-Zähler. Fügen Sie den im vorherigen Schritt berechneten Wert hinzu und runden Sie ihn mathematisch auf die nächste ganze Zahl ab (lassen Sie den ursprünglichen Float-Zähler unverändert). Fügen Sie ihn an dieser Position in die Zielliste ein und erhöhen Sie den Zähler um 1, um ihn zu berücksichtigen. Wiederholen Sie dies für alle Listenmitglieder in der zweiten Liste.

  5. Wiederholen Sie die Schritte 2-5 für alle Listen.

EDIT: Das hat den Vorteil, auch O (n) zu sein, was immer nett ist:)

    
Andrew Rollings 05.12.2008, 19:43
quelle
2

Erstens ist diese Antwort eher ein Gedankengang als eine konzeptuelle Lösung.

OK, Sie haben also eine Liste von 3 Elementen (A1, A2, A3), wobei A1 irgendwo im ersten Drittel der Zielliste, A2 im zweiten Drittel der Zielliste stehen soll und A3 im dritten Drittel. Ebenso möchtest du, dass B1 in der ersten 1/2 ist, usw. ...

Sie ordnen also Ihre Liste von 10 als ein Array zu, dann beginnen Sie mit der Liste mit den meisten Elementen, in diesem Fall C. Berechnen Sie die Stelle, an der C1 fallen sollte (1.5) C1 am nächsten Punkt fallen lassen (in diesem Fall) , entweder 1 oder 2), dann berechnen, wo C2 fallen sollte (3.5) und den Prozess fortsetzen, bis es keine Cs mehr gibt.

Dann gehen Sie mit der Liste mit der zweithöchsten Anzahl von Elementen. In diesem Fall A. Berechnen Sie, wo A1 geht (1.66), also versuchen Sie es zuerst mit 2. Wenn Sie C1 bereits dort eingeben, versuchen Sie 1. Tun Sie dasselbe für A2 (4.66) und A3 (7.66). Zum Schluss listen wir B auf. B1 sollte auf 2,5 gehen, also versuchen Sie es mit 2 oder 3. Wenn beide genommen werden, versuchen Sie 1 und 4 und bewegen Sie sich weiter radial nach außen, bis Sie eine leere Stelle finden. Tun Sie dasselbe für B2.

Wenn Sie die niedrigere Zahl wählen, erhalten Sie so etwas wie folgt:

C1 A1 C2 A2 C3 B1 C4 A3 C5 B2

oder wenn Sie die obere Zahl auswählen:

A1 C1 B1 C2 A2 C3 A3 C4 B2 C5

Das scheint für Ihre Beispiellisten ziemlich gut zu funktionieren, aber ich weiß nicht, wie gut es auf viele Listen mit vielen Elementen skalieren wird. Probieren Sie es aus und lassen Sie mich wissen, wie es geht.

    
Kyle Cronin 05.12.2008 19:52
quelle
2

Implementierung von Andrew Rollings 'Antwort:

%Vor%     
I_AM_PANDA 26.06.2015 03:04
quelle
1
  • Erstellen Sie eine Hash-Tabelle mit Listen.
  • Speichern Sie für jede Liste das n-te Element in der Liste unter dem Schlüssel (/ n (+ (length list) 1))
  • Optional können Sie die Listen unter jedem Schlüssel in der Hash-Tabelle mischen oder sie auf irgendeine Weise sortieren
  • Verknüpfen Sie die Listen im Hash mit dem sortierten Schlüssel
Svante 05.12.2008 22:20
quelle
1

Ich denke an einen "teile und herrsche" -Ansatz. Jede Iteration, in die Sie alle Listen mit Elementen & gt; 1 in der Hälfte und recurse. Wenn Sie zu einem Punkt kommen, an dem alle Listen außer einem Element zu einem Element gehören, können Sie diese zufällig kombinieren, eine Ebene aufklappen und die Listen, die aus dem Rahmen mit der Länge 1 entfernt wurden, beliebig kombinieren ... und so weiter.

Etwas wie das Folgende ist, was ich denke:

%Vor%     
nlucaroni 05.12.2008 19:40
quelle
-1

Sie könnten einfach die drei Listen zu einer einzigen Liste kombinieren und dann diese Liste UNSORTIEREN. Eine unsortierte Liste sollte Ihre Anforderung von "gleichmäßig verteilt" ohne zu viel Aufwand erreichen.

Hier ist eine Implementierung von unsort: Ссылка .

    
Will Bickford 05.12.2008 19:30
quelle
-1

Ein kurzer Vorschlag, im Python-Pseudocode:

%Vor%

Dies sollte Elemente aus kürzeren Listen gleichmäßiger als die anderen Vorschläge hier verteilen.

    
gnud 05.12.2008 19:42
quelle

Tags und Links