Dies ist eine Herausforderung mit den wenigsten Operationen , bei der das Ziel darin besteht, einen Vektor mit den wenigsten Umkehrungen in aufsteigender Reihenfolge zu sortieren. Ihr Algorithmus kann den Vektor nur mit "Subvektorumkehrungen" 1 sortieren , aber er kann andere Operationen für arithmetische Operationen, Schleifen, zum Überprüfen, ob er sortiert ist usw. verwenden. Die Anzahl der Subvektorumkehrungen, die Ihr Algorithmus durchführt, ist seine Punktzahl.
1 Eine "Subvektorumkehr":
- Wählen Sie einen Zahlenbereich im Vektor aus und kehren Sie die Elemente in diesem Bereich um.
Um ein einfaches Beispiel zu geben: Wenn Sie mit dem Vektor beginnen {4,3,2,1}
, können Sie ihn auf viele verschiedene Arten sortieren:
- Kehrt den gesamten Vektor um. Dies ist offensichtlich der kürzeste Ansatz, da nur eine Umkehrung erforderlich ist:
{4,3,2,1} -> {1,2,3,4}
- Sie können eine Version der Blasensortierung ausführen, für die 6 Umkehrungen erforderlich sind:
{4,3,2,1} -> {3,4,2,1} -> {3,2,4,1} -> {2,3,4,1} -> {2,3,1,4} -> {2,1,3,4} -> {1,2,3,4}
- Sie können mit den ersten drei Elementen beginnen, dann mit den drei letzten und schließlich mit den beiden ersten und den beiden letzten, was 4 Tauschvorgänge erfordert:
{4,3,2,1} -> {2,3,4,1} -> {2,1,4,3} -> {1,2,4,3} -> {1,2,3,4}
- ... und so weiter. Es stehen unendlich viele Optionen zur Verfügung (Sie können jeden Vorgang wiederholen, wenn Sie möchten).
Regeln und Anforderungen:
Bei einer Liste mit 100 Nummern muss Ihr Code in weniger als einer Minute fertig sein. Sie können dies selbst zeitlich festlegen, aber spielen Sie bitte fair 2 .
Sie müssen die Start- und Endindizes aller von Ihnen durchgeführten Swaps speichern, damit die Lösung überprüft werden kann. (Was dies bedeutet, erkläre ich weiter unten).
Der Code muss deterministisch sein.
Sie können die Eingabe in jedem gewünschten Format vornehmen: Numerischer Vektor, verknüpfte Liste, Array mit Länge ... nach Belieben.
Sie können eine Kopie des Vektors nach Belieben bearbeiten. Dazu gehört es, verschiedene Stornierungen vorzunehmen und zu prüfen, welche am effizientesten ist. Brute-Forcing ist völlig in Ordnung, aber halten Sie sich an das Zeitlimit.
Die Punktzahl ist die Gesamtzahl der Flips für die 5 Testvektoren. Tie-Breaker wird der Datumsstempel.
Beispiel:
4 1 23 21 49 2 7 9 2 | Anfangsvektor / Liste 4 1 2 9 7 2 49 21 23 | (2, 8) (Elemente zwischen den Indizes 2 und 8 umgedreht) 4 1 2 2 7 9 49 21 23 | (3, 5) 4 1 2 2 7 9 23 21 49 | (6, 8) 4 1 2 2 7 9 21 23 49 | (6, 7) 2 2 1 4 7 9 21 23 49 | (0, 3) 1 2 2 4 7 9 21 23 49 | (0, 2)
Die Punktzahl wäre 6, da Sie 6 Umkehrungen durchgeführt haben. Sie müssen die auf der rechten Seite aufgelisteten Indizes in einem geeigneten Format speichern (nicht drucken), das zu Überprüfungszwecken leicht gedruckt / ausgegeben werden kann.
Testvektoren:
133, 319, 80, 70, 194, 333, 65, 21, 345, 142, 82, 491, 92, 167, 281, 386, 48, 101, 394, 130, 111, 139, 214, 337, 180, 24, 443, 35, 376, 13, 166, 59, 452, 429, 406, 256, 133, 435, 446, 304, 350, 364, 447, 471, 236, 177, 317, 342, 294, 146, 280, 32, 135, 399, 78, 251, 467, 305, 366, 309, 162, 473, 27, 67, 305, 497, 112, 399, 103, 178, 386, 343, 33, 134, 480, 147, 466, 244, 370, 140, 227, 292, 28, 357, 156, 367, 157, 60, 214, 280, 153, 445, 301, 108, 77, 404, 496, 3, 226, 37
468, 494, 294, 42, 19, 23, 201, 47, 165, 118, 414, 371, 163, 430, 295, 333, 147, 336, 403, 490, 370, 128, 261, 91, 173, 339, 40, 54, 331, 236, 255, 33, 237, 272, 193, 91, 232, 452, 79, 435, 160, 328, 47, 179, 162, 239, 315, 73, 160, 266, 83, 451, 317, 255, 491, 70, 18, 275, 339, 298, 117, 145, 17, 178, 232, 59, 109, 271, 301, 437, 63, 103, 130, 15, 265, 281, 365, 444, 180, 257, 99, 248, 378, 158, 210, 466, 404, 263, 29, 117, 417, 357, 44, 495, 303, 428, 146, 215, 164, 99
132, 167, 361, 145, 36, 56, 343, 330, 14, 412, 345, 263, 306, 462, 101, 453, 364, 389, 432, 32, 200, 76, 268, 291, 35, 13, 448, 188, 11, 235, 184, 439, 175, 159, 360, 46, 193, 440, 334, 128, 346, 192, 263, 466, 175, 407, 340, 393, 231, 472, 122, 254, 451, 485, 257, 67, 200, 135, 132, 421, 205, 398, 251, 286, 292, 488, 480, 56, 284, 484, 157, 264, 459, 6, 289, 311, 116, 138, 92, 21, 307, 172, 352, 199, 55, 38, 427, 214, 233, 404, 330, 105, 223, 495, 334, 169, 168, 444, 268, 248
367, 334, 296, 59, 18, 193, 118, 10, 276, 180, 242, 115, 233, 40, 225, 244, 147, 439, 297, 115, 354, 248, 89, 423, 47, 458, 64, 33, 463, 142, 5, 13, 89, 282, 186, 12, 70, 289, 385, 289, 274, 136, 39, 424, 174, 186, 489, 73, 296, 39, 445, 308, 451, 384, 451, 446, 282, 419, 479, 220, 35, 419, 161, 14, 42, 321, 202, 30, 32, 162, 444, 215, 218, 102, 140, 473, 500, 480, 402, 1, 1, 79, 50, 54, 111, 189, 147, 352, 61, 460, 196, 77, 315, 304, 385, 275, 65, 145, 434, 39
311, 202, 126, 494, 321, 330, 290, 28, 400, 84, 6, 160, 432, 308, 469, 459, 80, 48, 292, 229, 191, 240, 491, 231, 286, 413, 170, 486, 59, 54, 36, 334, 135, 39, 393, 201, 127, 95, 456, 497, 429, 139, 81, 293, 359, 477, 404, 129, 129, 297, 298, 495, 424, 446, 57, 296, 10, 269, 350, 337, 39, 386, 142, 327, 22, 352, 421, 32, 171, 452, 2, 484, 337, 359, 444, 246, 174, 23, 115, 102, 427, 439, 71, 478, 89, 225, 7, 118, 453, 350, 109, 277, 338, 474, 405, 380, 256, 228, 277, 3
Ich bin mir ziemlich sicher, dass es nicht einfach ist, eine optimale Lösung zu finden (da das regelmäßige Sortieren von Pfannkuchen der Fall ist).
2 Ja, Menschen mit sehr schnellen Computern können aufgrund des Zeitlimits von einer Minute Vorteile haben. Nach vielen Diskussionen habe ich herausgefunden, dass es am besten ist, wenn jeder sein eigenes Benchmarking durchführt. Es ist keine schnellste Code-Herausforderung.
quelle
n-1
Flips gibt? Ich kann nur eine Untergrenze von ca. 50 nachweisen.Antworten:
Java, genetischer Algorithmus, 80 + 81 + 79 + 78 + 80 = 398 (vorher
418)Nachdem ich eine Reihe verschiedener Ideen ausprobiert hatte und die meisten fehlgeschlagen waren, entschied ich mich für diesen Algorithmus: Beginnen Sie mit dem Eingabearray, versuchen Sie alle möglichen Umkehrungen und behalten Sie eine bestimmte Anzahl von Ergebnissen mit der geringsten Anzahl von Durchläufen bei Wir erhalten ein sortiertes Array.
Mit "Durchläufen" meine ich maximale Unterfelder, die im sortierten Feld genau oder umgekehrt vorkommen. Grundsätzlich handelt es sich um maximal sortierte Subarrays. Bei wiederholten Elementen sollte die Anzahl der Elemente in der Mitte übereinstimmen. ZB wenn die sortierten Array wird
2, 2, 3, 3, 4, 4
dann4, 3, 3, 2
ein Run , aber2, 2, 3, 4
nicht (und keiner ist2, 3, 2
).In dieser Version habe ich den Algorithmus so optimiert, dass er nur an Laufgrenzen umkehrt und nur dann, wenn ein umgekehrter Lauf mit einem neu angrenzenden Lauf verbunden werden kann. Außerdem werden die Läufe bei jedem Schritt angepasst und verbunden, um zu vermeiden, dass sie aus dem geänderten Array neu berechnet werden. Dies ermöglichte es mir, die "Populationsgröße" von 30 auf etwa 3000 zu erhöhen und mehrere Simulationen mit verschiedenen Größen durchzuführen.
Die Eingabe ist eine Liste von Zahlen, die durch Komma und / oder Leerzeichen (von stdin) getrennt sind. Wenn die Eingabe leer ist, führt das Programm die 5 Tests durch. Jeder dauert hier ungefähr 40 Sekunden.
quelle
Ein Zug Brute-Force, dann Auswahlsortierung (auch naive Lösung), 90 + 89 + 88 + 87 + 89 = 443 Züge
Versuchen Sie es für jeden möglichen ersten Schritt und führen Sie dann eine Auswahlsortierung durch.
Ja, das ist eine andere naive Lösung.
Ich bin mir nicht sicher, ob dies eine Bearbeitung oder ein anderer Beitrag sein soll, aber es scheint, dass die Lösung zu einfach ist, sodass die Bearbeitung ausgewählt wird.
Auswahl sortieren (Naive Lösung), 92 + 93 + 95 + 93 + 96 = 469 Züge
Eine naive Lösung verwenden Auswahlsortierung.
Es MUSS einige bessere Lösungen geben, aber poste dies, da ich keine bessere gefunden habe (ohne Brute-Force-Suche).
(Der obige Code ist JavaScript Shell )
quelle