Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Lernprogramm lernen Sie, ein grundlegendes Quantenprogramm zu schreiben, in Q# dem die Natur der Quantenmechanik genutzt wird, um eine Zufallszahl zu erzeugen.
In diesem Lernprogramm lernen Sie Folgendes:
- Erstellen Sie ein Q# Programm.
- Überprüfen Sie die Hauptkomponenten eines Q# Programms.
- Definieren Sie die Logik eines Problems.
- Kombinieren Sie klassische und Quantenoperationen, um ein Problem zu lösen.
- Arbeiten mit Qubits und Superposition, um einen Quanten-Zufallszahlen-Generator zu erstellen
Tipp
Wenn Sie Ihre Quantum Computing-Reise beschleunigen möchten, schauen Sie sich Code mit Azure Quantum an, einem einzigartigen Feature der Microsoft Quantum-Website. Hier können Sie integrierte Q# Beispiele oder Eigene Q# Programme ausführen, neuen Q# Code aus Ihren Eingabeaufforderungen generieren, Ihren Code in VS Code für das Web mit nur einem Klick öffnen und ausführen und Copilot Fragen zum Quanten computing stellen.
Voraussetzungen
So führen Sie das Codebeispiel im Copilot in Azure Quantum aus:
- Ein Microsoft-E-Mail-Konto (MSA).
So entwickeln und führen Sie das Codebeispiel in Visual Studio Code aus:
Die neueste Version von Visual Studio Code oder öffnen Sie VS Code im Web.
Die neueste Version der Quantum Development Kit. Details zur Installation finden Sie unter Einrichten der QDK-Erweiterung.
Wenn Sie das Jupyter Notebook verwenden möchten, müssen Sie auch Python- und Jupyter-Erweiterungen sowie die neueste
qdkPython-Bibliothek mit denjupyterExtras installieren. Öffnen Sie dazu ein Terminal, und führen Sie den folgenden Befehl aus:pip install --upgrade qdk[jupyter]
Definieren des Problems
Klassische Computer erzeugen keine Zufallszahlen, sondern pseudozufällige Zahlen. Ein Pseudorandomzahlengenerator generiert eine deterministische Sequenz von Zahlen basierend auf einem bestimmten Anfangswert, der als Seed bezeichnet wird. Um sich Zufallswerten besser anzunähern, ist dieser Ausgangswert oft die aktuelle Zeit der CPU-Uhr.
Quantencomputer hingegen können echte Zufallszahlen generieren. Dies liegt daran, dass die Messung eines Qubits in der Superposition ein probabilistischer Prozess ist. Das Ergebnis der Messung ist zufällig und es gibt keine Möglichkeit, das Ergebnis vorherzusagen. Dies ist das Grundprinzip von Quanten-Zufallszahlengeneratoren.
Ein Qubit ist eine Einheit von Quanteninformationen, die sich in der Superposition befindet. Wenn gemessen, kann ein Qubit nur im Zustand 0 oder im 1-Zustand sein. Vor der Messung stellt der Zustand des Qubits jedoch die Wahrscheinlichkeit dar, entweder ein 0 oder ein 1 mit einer Messung zu lesen.
Sie beginnen mit einem Qubit in einem Basiszustand, z. B. 0. Der erste Schritt des Zufallszahlengenerators besteht darin, einen Hadamard-Vorgang zu verwenden, um das Qubit in eine gleiche Superposition zu setzen. Die Messung dieses Zustands führt zu einer Null oder einer mit einer Wahrscheinlichkeit von 50 % jedes Ergebnisses, einem wirklich zufälligen Bit.
Es gibt keine Möglichkeit zu wissen, was Sie nach der Messung des Qubits in Superposition erhalten werden, und das Ergebnis ist bei jedem Aufruf des Codes ein anderer Wert. Aber wie können Sie dieses Verhalten verwenden, um größere Zufallszahlen zu generieren?
Angenommen, Sie wiederholen den Prozess viermal und erzeugen dabei diese Folge von Binärzahlen:
${0, 1, 1, 0}$$
Wenn Sie diese Bits verketten oder in eine Bitzeichenfolge kombinieren, können Sie eine größere Zahl bilden. In diesem Beispiel entspricht die Bitfolge ${0110}$ der Dezimalzahl 6.
$${0110_{\ binary} \equiv 6_{\ decimal}}$$
Wenn Sie diesen Prozess mehrmals wiederholen, können Sie mehrere Bits zu einer beliebigen großen Zahl kombinieren. Mit dieser Methode können Sie eine Zahl erstellen, die als sicheres Kennwort verwendet werden soll, da Sie sicher sein können, dass kein Hacker die Ergebnisse der Abfolge der Messungen ermitteln konnte.
Definieren der Logik für den Zufallszahlen-Generator
Sehen wir uns an, was die Logik eines Zufallszahlengenerators sein sollte:
- Definieren Sie
maxals höchste Zahl, die Sie generieren möchten. - Definieren Sie die Anzahl der Zufallsbits, die Sie generieren müssen. Dazu wird berechnet, wie viele Bits ,
nBitsSie ganze Zahlen bis zumaxausdrücken müssen. - Generieren Sie eine zufällige Bitzeichenfolge, die
nBitslang ist. - Wenn die Bitzeichenfolge eine Zahl größer als
maxdarstellt, kehren Sie zu Schritt 3 zurück. - Andernfalls ist der Vorgang abgeschlossen. Geben Sie die generierte Zahl als ganze Zahl zurück.
Legen Sie zum Beispiel max auf 12 fest. Das heißt, 12 ist die größte Zahl, die Sie als Kennwort verwenden möchten.
Sie benötigen ${\lfloor ln(12) / ln(2) + 1 \rfloor}$ gleich 4 Bits, um eine Zahl zwischen 0 und 12 darzustellen. Wir können die integrierte Funktion BitSizeIverwenden, die eine ganze Zahl akzeptiert und die Anzahl der Bits zurückgibt, die erforderlich sind, um sie darzustellen.
Angenommen, Sie generieren die Bitzeichenfolge ${1101_{\ binary}}$, dann entspricht dies ${13_{\ decimal}}$. Da 13 größer als 12 ist, wiederholen Sie den Vorgang.
Als Nächstes generieren Sie die Bitzeichenfolge ${0110_{\ binary}}$, dies entspricht ${6_{\ decimal}}$. Da 6 kleiner als 12 ist, ist der Prozess abgeschlossen.
Der Zufallszahlengenerator gibt zahl 6 als Kennwort zurück. Legen Sie in der Praxis eine größere Zahl als den Höchstwert fest, da niedrigere Zahlen einfach zu knacken sind, indem einfach alle möglichen Kennwörter ausprobiert werden. Um das Erraten oder Knacken des Kennworts weiter zu erschweren, könnten Sie den ASCII-Code verwenden, um Binärdaten in Text zu konvertieren und ein Kennwort mithilfe von Zahlen, Symbolen und einer Mischung aus Groß- und Kleinbuchstaben zu generieren.
Schreiben eines zufälligen Bitgenerators
Der erste Schritt besteht darin, einen Q# Vorgang zu schreiben, der ein zufälliges Bit generiert. Dieser Vorgang ist einer der Bausteine des Zufallszahlengenerators.
operation GenerateRandomBit() : Result {
// Allocate a qubit.
use q = Qubit();
// Set the qubit into superposition of 0 and 1 using the Hadamard
H(q);
// At this point the qubit `q` has 50% chance of being measured in the
// |0〉 state and 50% chance of being measured in the |1〉 state.
// Measure the qubit value using the `M` operation, and store the
// measurement value in the `result` variable.
let result = M(q);
// Reset qubit to the |0〉 state.
// Qubits must be in the |0〉 state by the time they are released.
Reset(q);
// Return the result of the measurement.
return result;
}
Sehen Sie sich den neuen Code an.
- Sie definieren den
GenerateRandomBit-Vorgang. Dieser benötigt keine Eingabe und erzeugt einen Wert vom TypResult. Der TypResultstellt das Ergebnis einer Messung dar und kann einen von zwei möglichen Werten haben:ZerooderOne. - Sie weisen ein einzelnes Qubit mit dem
useSchlüsselwort zu. Wenn sie zugewiesen wird, befindet sich ein Qubit immer im Zustand "|0". - Sie verwenden den
HVorgang, um das Qubit in einer gleichen Superposition zu platzieren. - Sie verwenden den
MVorgang zum Messen des Qubits, zurückgeben den gemessenen Wert (ZerooderOne). - Sie verwenden den
ResetVorgang, um den Qubit auf den Zustand '|0' zurückzusetzen.
Wenn das Qubit mithilfe der H-Operation in Superposition versetzt und mithilfe der M-Operation gemessen wird, führt jeder Codeaufruf zu einem anderen Ergebniswert.
Visualisieren des Q# Codes mit der Bloch-Kugel
In der Bloch-Kugel stellt der Nordpol den klassischen Wert 0 dar, und der Südpol stellt den klassischen Wert 1 dar. Jede Überlagerung kann durch einen Punkt auf der Kugel dargestellt werden (per Pfeil). Je näher sich das Ende des Pfeils an einem der Pole befindet, desto höher ist die Wahrscheinlichkeit, dass das Qubit bei einer Messung auf den klassischen Wert zurückfällt, der dem Pol zugeordnet ist. Beispielsweise hat der qubit-Zustand, der durch den Pfeil in der folgenden Abbildung dargestellt wird, eine höhere Wahrscheinlichkeit, den Wert 0 zu geben, wenn Sie ihn messen.
Diese Darstellung kann zur Visualisierung der Aktivitäten des Codes verwendet werden:
Beginnen Sie zunächst mit einem qubit initialisiert im |0-Zustand und wenden Sie einen
HVorgang an, um eine gleiche Superposition zu erstellen, in der die Wahrscheinlichkeiten für 0 und 1 identisch sind.
Messen Sie anschließend das Qubit, und speichern Sie die Ausgabe:
Da das Ergebnis der Messung zufällig ist und die Wahrscheinlichkeit der Messung von 0 und 1 identisch ist, haben Sie ein völlig zufälliges Bit erhalten. Sie können diesen Vorgang mehrmals aufrufen, um ganze Zahlen zu erstellen. Wenn Sie den Vorgang beispielsweise dreimal aufrufen, um drei zufällige Bits zu erhalten, können Sie zufällige 3-Bit-Zahlen erstellen (also eine Zufallszahl zwischen 0 und 7).
Schreiben eines vollständigen Zufallszahlengenerators
Zunächst müssen Sie die erforderlichen Namespaces aus der Q# Standardbibliothek in das Programm importieren. Der Q# Compiler lädt viele allgemeine Funktionen und Vorgänge automatisch, aber für den vollständigen Zufallszahlengenerator benötigen Sie einige zusätzliche Funktionen und Vorgänge aus zwei Q# Namespaces:
Std.MathundStd.Convert.import Std.Convert.*; import Std.Math.*;Als Nächstes definieren Sie den
GenerateRandomNumberInRangeVorgang. Mit diesem Vorgang wird derGenerateRandomBit-Vorgang wiederholt aufgerufen, um eine Bitzeichenfolge zu erstellen./// Generates a random number between 0 and `max`. operation GenerateRandomNumberInRange(max : Int) : Int { // Determine the number of bits needed to represent `max` and store it // in the `nBits` variable. Then generate `nBits` random bits which will // represent the generated random number. mutable bits = []; let nBits = BitSizeI(max); for idxBit in 1..nBits { bits += [GenerateRandomBit()]; } let sample = ResultArrayAsInt(bits); // Return random number if it is within the requested range. // Generate it again if it is outside the range. return sample > max ? GenerateRandomNumberInRange(max) | sample; }Sehen Sie sich den neuen Code noch einmal an.
- Sie müssen die Anzahl der Bits berechnen, die erforderlich sind, um ganze Zahlen bis zu
maxausdrücken. DieBitSizeIFunktion aus demStd.MathNamespace konvertiert eine ganze Zahl in die Anzahl der Bits, die erforderlich sind, um sie darzustellen. - Der
SampleRandomNumberInRange-Vorgang verwendet einefor-Schleife zum Generieren von Zufallszahlen, bis eine Zahl generiert wird, die kleiner oder gleichmaxist. Diefor-Schleife funktioniert genauso wie einefor-Schleife in anderen Programmiersprachen. - Die Variable
bitsist eine veränderbare Variable. Eine änderbare Variable ist eine Variable, die während der Berechnung geändert werden kann. Verwenden Sie dieset-Direktive, um den Wert einer änderbaren Variablen zu ändern. - Die
ResultArrayAsIntFunktion konvertiert aus dem StandardnamespaceStd.Convertdie Bitzeichenfolge in eine positive ganze Zahl.
- Sie müssen die Anzahl der Bits berechnen, die erforderlich sind, um ganze Zahlen bis zu
Schließlich fügen Sie dem Programm einen Einstiegspunkt hinzu. Standardmäßig sucht der Q# Compiler nach einem
MainVorgang und startet die Verarbeitung dort. Er ruft denGenerateRandomNumberInRangeVorgang auf, um eine Zufallszahl zwischen 0 und 100 zu generieren.operation Main() : Int { let max = 100; Message($"Sampling a random number between 0 and {max}: "); // Generate random number in the 0..max range. return GenerateRandomNumberInRange(max); }Mit der
let-Direktive werden Variablen deklariert, die während der Berechnung nicht geändert werden. Hier definieren Sie den Maximalwert als 100.Weitere Informationen zum
MainVorgang finden Sie unter "Einstiegspunkte".Der vollständige Code für den Zufallszahlengenerator lautet wie folgt:
import Std.Convert.*;
import Std.Math.*;
operation Main() : Int {
let max = 100;
Message($"Sampling a random number between 0 and {max}: ");
// Generate random number in the 0..max range.
return GenerateRandomNumberInRange(max);
}
/// Generates a random number between 0 and `max`.
operation GenerateRandomNumberInRange(max : Int) : Int {
// Determine the number of bits needed to represent `max` and store it
// in the `nBits` variable. Then generate `nBits` random bits which will
// represent the generated random number.
mutable bits = [];
let nBits = BitSizeI(max);
for idxBit in 1..nBits {
bits += [GenerateRandomBit()];
}
let sample = ResultArrayAsInt(bits);
// Return random number if it is within the requested range.
// Generate it again if it is outside the range.
return sample > max ? GenerateRandomNumberInRange(max) | sample;
}
operation GenerateRandomBit() : Result {
// Allocate a qubit.
use q = Qubit();
// Set the qubit into superposition of 0 and 1 using a Hadamard operation
H(q);
// At this point the qubit `q` has 50% chance of being measured in the
// |0〉 state and 50% chance of being measured in the |1〉 state.
// Measure the qubit value using the `M` operation, and store the
// measurement value in the `result` variable.
let result = M(q);
// Reset qubit to the |0〉 state.
// Qubits must be in the |0〉 state by the time they are released.
Reset(q);
// Return the result of the measurement.
return result;
}
Ausführen des Programms für den Zufallszahlengenerator
Sie können das Programm im Copilot in Azure Quantum und in Visual Studio Code als eigenständige Q# Anwendung oder mit einem Python-Hostprogramm ausführen.
Sie können Ihren Q# Code mit dem Copilot in Azure Quantum kostenlos testen – alles, was Sie benötigen, ist ein Microsoft-E-Mail-Konto (MSA). Weitere Informationen zum Copilot in Azure Quantum finden Sie unter Explore Azure Quantum.
Öffnen Sie den Copilot in Azure Quantum in Ihrem Browser.
Kopieren Sie den folgenden Code, und fügen Sie ihn in den Code-Editor ein.
import Std.Convert.*; import Std.Math.*; operation Main() : Int { let max = 100; Message($"Sampling a random number between 0 and {max}: "); // Generate random number in the 0..max range. return GenerateRandomNumberInRange(max); } /// # Summary /// Generates a random number between 0 and `max`. operation GenerateRandomNumberInRange(max : Int) : Int { // Determine the number of bits needed to represent `max` and store it // in the `nBits` variable. Then generate `nBits` random bits which will // represent the generated random number. mutable bits = []; let nBits = BitSizeI(max); for idxBit in 1..nBits { bits += [GenerateRandomBit()]; } let sample = ResultArrayAsInt(bits); // Return random number if it is within the requested range. // Generate it again if it is outside the range. return sample > max ? GenerateRandomNumberInRange(max) | sample; } /// # Summary /// Generates a random bit. operation GenerateRandomBit() : Result { // Allocate a qubit. use q = Qubit(); // Set the qubit into superposition of 0 and 1 using the Hadamard // operation `H`. H(q); // At this point the qubit `q` has 50% chance of being measured in the // |0〉 state and 50% chance of being measured in the |1〉 state. // Measure the qubit value using the `M` operation, and store the // measurement value in the `result` variable. let result = M(q); // Reset qubit to the |0〉 state. // Qubits must be in the |0〉 state by the time they are released. Reset(q); // Return the result of the measurement. return result; // Note that Qubit `q` is automatically released at the end of the block. }Wählen Sie die Anzahl der auszuführenden Aufnahmen und dann "Ausführen" aus.
Die Ergebnisse werden im Histogramm und in den Feldern "Ergebnisse " angezeigt.
Wählen Sie "Erklären"-Code aus, um Copilot aufzufordern, den Code Ihnen zu erläutern.
Tipp
Über Copilot in Azure Quantum können Sie Ihr Programm in VS Code für das Web öffnen, indem Sie in der rechten Ecke des Code-Editors die Schaltfläche "VS Code-Logo" auswählen.
Hinweis
Dieser Codeausschnitt wird derzeit nicht auf verfügbarer Azure Quantum-Hardware targetsausgeführt, da für die aufrufbare ResultArrayAsInt Datei eine QPU mit einem vollständigen Berechnungsprofil erforderlich ist.
Zugehöriger Inhalt
Sehen Sie sich weitere Q#-Tutorials an:
- Quantenanglement zeigt, wie ein Q# Programm geschrieben wird, das Qubits bearbeitet und misst und die Auswirkungen von Superposition und Veranglement veranschaulicht.
- von Grover verwendet.
- Quantum Fourier Transforms untersucht, wie ein Q# Programm geschrieben wird, das direkt bestimmte Qubits adressiert.
- Die Quantum Katas sind selbstgesteuerte Lernprogramme und Programmierübungen, die darauf abzielen, die Elemente von Quantencomputing und Q# Programmierung gleichzeitig zu unterrichten.