Wenn Sie unter den Verrückten leben, müssen Sie lernen, selbst verrückt zu seinHaben Sie jemals versucht, "lernen, verrückt zu sein"? Nicht triviale Aufgabe. Sie werden nicht einmal eine normale Technik finden, weil jeder auf seine Weise verrückt wird. Mein erster Versuch: Verschwörungstheorie. Die Theorie beinhaltet keine Praxis, was bedeutet, dass Sie nicht hart arbeiten müssen. Auch in jeder Situation wird niemand leiden.
Wie erstelle ich Verschwörungstheorien?Die Erstellung einer Verschwörungstheorie ist relativ einfach. Wir brauchen eine Idee, die einfach genug ist, um von 90% der Bevölkerung akzeptiert zu werden. Es sollte kontrovers sein, damit 5% der Bevölkerung 90% erklären können, was für Idioten sie sind. Schließlich brauchen wir einige Untersuchungen, die diese 95% der Menschen nicht verstehen, die aber von 90% als Argument verwendet werden: "Die Menschen haben sich als schlauer erwiesen als wir ...".
Quantum Computing ist ein großartiger Bereich für eine solche Studie. Sie können ein einfaches Schema zusammenstellen, aber das Wort "Quantum" erhöht das Gewicht der Ergebnisse.
Das Objekt des Studiums ist ein Spiel, denn das Objekt ist auf die einfache und vertraute Jugend zurückzuführen. Wer ist an Quantencomputern und Spielen beteiligt? Google
Also, ketzerische Theorie: Nach 5 Jahren werden Page und Green entscheiden, wer die Hauptsache in Google sein wird, und dies mit Hilfe des Spiels tun. Jeder von ihnen hat eine Gruppe von Forschern. Das AlphaGo-Team mit seinen
kämpfenden neuronalen Netzen zog Rivalen in Go an. Die Gegner waren gezwungen, nach neuen Methoden zu suchen, und fanden dennoch ein Instrument der
völligen Überlegenheit: das Quantencomputing.
Kann ich Quantum Computing für Spiele verwenden? Einfach. Lassen Sie uns zum Beispiel zeigen, dass das Spiel "Fuchsjäger" in 6 Zügen "gelöst" werden kann. Aus Gründen der Glaubwürdigkeit beschränken wir uns auf 15 Qubits (die Online-Editor-Eigenart emuliert nicht länger als fünfzehn). Der Einfachheit halber werden wir die Einschränkungen der Prozessorarchitektur und der Fehlerkorrektur ignorieren.
Die Regeln
Sehr einfach.
Es gibt fünf Löcher in einer Reihe (wir nummerieren sie als 0-1-2-3-4). In einem von ihnen ist ein Fuchs. Jede Nacht bewegt sich der Fuchs zum nächsten Nerz links oder rechts. Jeden Morgen kann der Jäger ein Loch zur Auswahl prüfen. Die Aufgabe des Jägers ist es, den Fuchs zu fangen. Die Aufgabe des Fuchses ist es zu überleben. Theoretisch kann ein Fuchs für immer vor einem Jäger fliehen. In der Praxis gibt es eine Gewinnstrategie: Überprüfen Sie die Löcher 1-2-3-1-2-3. Nur diese Strategie werde ich testen.
Ein Schema aufbauen
Beginnen wir mit der Initiierung der Qubits 0-1-2-3-4 (5 Löcher).
Hier können Sie bearbeiten
Tatsächlich haben wir nach der Initiierung ein System, in dem nach der Messung streng ein Qubit einzeln ist. Die Wahrscheinlichkeiten der "Einheit" unterscheiden sich für jedes Qubit, aber in unserem Fall ist dies nicht kritisch. Wir müssen Raum für Diskussionen über das Schema (und gleichzeitig unsere Theorie) lassen.
Auf Q # erhalten wir Code wie folgt:
operation TestStrategy () : (Result) { let res = Zero; using(qubits=Qubit[16]) {
TestStrategy testet unsere Strategie 1-2-3-1-2-3. InitFoxHoles () ist nur für die Initiierung von Fuchslöchern verantwortlich. Lassen Sie uns die Initiation überprüfen. Kopieren Sie TestStrategy, starten Sie die Initiierung, messen Sie die ersten 5 Qubits und geben Sie ihre Werte zurück.
operation TestInit(): (Result, Result, Result, Result, Result) { body { mutable res0 = Zero; mutable res1 = Zero; mutable res2 = Zero; mutable res3 = Zero; mutable res4 = Zero; using(qubits=Qubit[16]) {
Wir werden den Test tausendmal durchführen (mehrere Läufe sind typisch für Quantenalgorithmen, an einigen Stellen sogar notwendig). Rufcode - unter dem Spoiler, Ergebnisse: auf dem Bildschirm unten.
Testen Sie die Initiierung schnell static void TestInitiation() { using (var sim = new QuantumSimulator()) { var initedQubitsValues = Enumerable.Range(0, 5) .ToDictionary(qubitIndex => qubitIndex, oneMesaured => 0); for (int i = 0; i < 1000; i++) { (Result, Result, Result, Result, Result) result = TestInit.Run(sim).Result; if (result.Item1 == Result.One) { initedQubitsValues[0]++; } if (result.Item2 == Result.One) { initedQubitsValues[1]++; } if (result.Item3 == Result.One) { initedQubitsValues[2]++; } if (result.Item4 == Result.One) { initedQubitsValues[3]++; } if (result.Item5 == Result.One) { initedQubitsValues[4]++; } } Console.WriteLine($"Qubit-0 initiations: {initedQubitsValues[0]}"); Console.WriteLine($"Qubit-1 initiations: {initedQubitsValues[1]}"); Console.WriteLine($"Qubit-2 initiations: {initedQubitsValues[2]}"); Console.WriteLine($"Qubit-3 initiations: {initedQubitsValues[3]}"); Console.WriteLine($"Qubit-4 initiations: {initedQubitsValues[4]}"); } }

Etwas ist schief gelaufen. Eine nahezu gleichmäßige Verteilung wurde erwartet. Der Grund ist einfach: In Schritt 3 habe ich das dritte Qubit anstelle des ersten invertiert: (Controlled (X)) ([Register [0], Register [2]], Register [3]);
nicht gute alte Copy-Paste.
Wir korrigieren den Code und führen den Test durch:

Schon besser. Der Code ist in der Rübe, Version
Commit 1, zu sehen .
Wo soll der Fuchs laufen?
Wählen Sie das fünfte Qubit (die Nummerierung beginnt von oben) unter der aktuellen Richtung des Fuchses. Wir sind uns einig, dass Null eine Abwärtsbewegung bedeutet, eine Einheit eine Aufwärtsbewegung. Wenn sich der Fuchs bereits im Nullloch befindet, sollte er sich natürlich nach unten bewegen. Befindet sich der Fuchs im vierten Loch, bewegt er sich nach oben. In anderen Fällen kann sich der Fuchs auf und ab bewegen. Nach diesen einfachen Regeln können wir das „Qubit der aktuellen Richtung“ auf 0, 1 oder eine Überlagerung von Null und Eins setzen. Wir sehen uns den Code im Repository
Commit 2 an .
Schema im Editor.Code und Test
static void TestMovementDirectionSetup() { using (var sim = new QuantumSimulator()) { List<string> results = new List<string>(); string initedCubit = null; string moveDirection = null; for (int i = 0; i < 1000; i++) { (Result, Result, Result, Result, Result, Result) result = Quantum.FoxHunter.TestMovementDirectionSetup.Run(sim).Result; if (result.Item1 == Result.One) { initedCubit = "0"; } if (result.Item2 == Result.One) { initedCubit = "1"; } if (result.Item3 == Result.One) { initedCubit = "2"; } if (result.Item4 == Result.One) { initedCubit = "3"; } if (result.Item5 == Result.One) { initedCubit = "4"; } if (result.Item6 == Result.One) { moveDirection = "1"; } else { moveDirection = "0"; } results.Add($"{initedCubit}{moveDirection}"); } foreach(var group in results .GroupBy(result => result) .OrderBy(group => group.Key)) { Console.WriteLine($"{group.Key} was measured {group.Count()} times"); } Console.WriteLine($"\r\nTotal measures: {results.Count()}"); } }

Bewegung
Implementiert von kontrolliertem SWAP. Wenn das steuernde Qubit einfach ist, tauschen Sie es aus. Wenn das steuernde Qubit Null ist, tauschen wir auf.
Schema im Editor .
Q #: Anweisung für Tests operation TestFirstMovement(): (Result, Result, Result, Result, Result, Result) { body { mutable res0 = Zero; mutable res1 = Zero; mutable res2 = Zero; mutable res3 = Zero; mutable res4 = Zero; mutable res5 = Zero; using(qubits=Qubit[16]) { InitFoxHoles(qubits); SetupMovementDirection(qubits); MakeMovement(qubits); set res0 = M(qubits[0]); set res1 = M(qubits[1]); set res2 = M(qubits[2]); set res3 = M(qubits[3]); set res4 = M(qubits[4]); set res5 = M(qubits[5]); ResetAll(qubits);
C # -Code static void TestFirstMove() { using (var sim = new QuantumSimulator()) { List<string> results = new List<string>(); string initedCubit = null; string moveDirection = null; for (int i = 0; i < 1000; i++) { (Result, Result, Result, Result, Result, Result) result = Quantum.FoxHunter.TestFirstMovement.Run(sim).Result; if (result.Item1 == Result.One) { initedCubit = "0"; } if (result.Item2 == Result.One) { initedCubit = "1"; } if (result.Item3 == Result.One) { initedCubit = "2"; } if (result.Item4 == Result.One) { initedCubit = "3"; } if (result.Item5 == Result.One) { initedCubit = "4"; } if (result.Item6 == Result.One) { moveDirection = "1"; } else { moveDirection = "0"; } results.Add($"{initedCubit}{moveDirection}"); }
Der Code kann in
Commit 3 angezeigt werden.
Wir machen 6 Züge
Schließlich wählen wir das sechste Qubit für den Status des Spiels (der Fuchs ist frei / der Fuchs ist nicht frei). Die Einheit entspricht einem freien Fuchs. Wir werden weitere Schritte nur mit einem einzigen Status-Qubit machen.
Die Qubits 7,8,9,10,11 werden eine Bewegungsgeschichte führen. Nach jedem Zug tauschen wir einen von ihnen gegen ein Qubit der aktuellen Richtung aus (dies ermöglicht es uns, den Verlauf der Züge zu speichern und das Qubit der aktuellen Richtung vor jedem Zug zurückzusetzen).
Schema beigefügt .
Q #: Anweisung für Tests operation TestSixMovements(): (Result) { body { mutable res = Zero; using(qubits=Qubit[16]) { ResetAll(qubits); InitFoxHoles(qubits); X(qubits[6]);
C #: Testen static void TestMovements() { using (var sim = new QuantumSimulator()) { int zerosCount = 0; for (int i = 0; i < 1000; i++) { Result result = Quantum.FoxHunter.TestSixMovements.Run(sim).Result; if(result == Result.Zero) { zerosCount++; } } Console.WriteLine($"\r\nTotal zeroes: {zerosCount}"); } }
Wir sehen
Commit 4 .
Feinschliff
Wir haben einen Fehler in der Schaltung. Da wir die Strategie 1-2-3-1-2-3 testen, überprüfen wir jedes Loch zweimal. Nachdem wir den Fuchs im ersten Zug gefangen haben, werden wir das Status-Qubit zweimal durchlaufen (im ersten und vierten Zug).
Um diese Situation zu vermeiden, verwenden wir 12 Qubits, um den Status nach den Zügen 4-5-6 zu korrigieren. Zusätzlich fügen wir die Definition des Sieges hinzu: Wenn mindestens eines der Status-Qubits auf Null geht, haben wir gewonnen.
Das endgültige Schema .
Q #: Korrigieren Sie den 6-Zug-Operator operation MakeSixMovements(qubits: Qubit[]) : Unit { body {
F #: Festlegen der Operator-Teststrategie 1-2-3-1-2-3 operation TestStrategy () : (Result) {
C #: Endprüfung durchführen static void RunFoxHunt() { Stopwatch sw = new Stopwatch(); sw.Start(); using (var sim = new QuantumSimulator()) { var foxSurvives = 0; var hunterWins = 0; for (int i = 0; i < 1000; i++) { var result = (Result)(TestStrategy.Run(sim).Result); if (result == Result.Zero) { foxSurvives++; } else { hunterWins++; } } Console.WriteLine($"Fox survives: \t{foxSurvives}"); Console.WriteLine($"Hunter wins: \t{hunterWins}"); } sw.Stop(); Console.WriteLine($"Experiment finished. " + $"Time spent: {sw.ElapsedMilliseconds / 1000} seconds"); }
Festschreiben 5 .
Was folgt daraus
Grundsätzlich kann das Schema sowohl in der Anzahl der Qubits als auch in der Anzahl der Operationen optimiert werden. Die triviale Optimierung für die Anzahl der Qubits besteht darin, Qubit-13 zu entfernen und nur 6 und 12 zurückzugeben. Optimierung für Operationen - um den ersten Schuss unmittelbar nach der Initiierung zu machen. Überlassen wir diese Arbeit jedoch den Google-Ingenieuren.
Wie Sie sehen, kann jeder, der oberflächlich mit Quantencomputern vertraut ist, sicher den "Fuchsjäger" spielen. Wenn wir etwas mehr Qubits hätten, könnten wir die optimale Lösung finden und nicht die vorhandene überprüfen. Es ist durchaus möglich, dass Tic-Tac-Toe (und ihre Quantenversion), Dame, Schach, Go als nächstes fallen.
Gleichzeitig bleibt das Thema "Lösbarkeit" von Spielen wie DotA, Starcraft und Doom offen. Für das Quantencomputing ist die Speicherung der gesamten Klickhistorie charakteristisch. Wir nehmen einen APM (Actions Per Minute) von 500, multiplizieren mit der Anzahl der Spieler, multiplizieren mit der Anzahl der Minuten, addieren die Zufälligkeit des Spiels selbst - die Anzahl der Qubits, die zum Speichern aller Informationen erforderlich sind, wächst zu schnell.
Die Auswahl eines Spiels in einem kleinen Wettbewerb zwischen Brin und Page kann also eine entscheidende Rolle spielen. Die Entwicklung eines „ebenso schwierigen“ Spiels für klassische Computer und Quantencomputer verdient jedoch eine eigene Theorie.