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
Voraussetzungen
Um das Codebeispiel in Visual Studio Code (VS Code) und Jupyter-Notizbuch zu entwickeln und auszuführen, installieren Sie Folgendes:
Die neueste Version von VS Code oder öffnen Sie VS Code für das Web.
Die neueste Version der Microsoft Quantum Development Kit Erweiterung (QDK). Details zur Installation finden Sie unter Einrichten der QDK-Erweiterung.
Die Python - und Jupyter-Erweiterungen für VS Code.
Die neueste
qdkPython-Bibliothek mit demjupyterZusatz. Um diese zu installieren, öffnen Sie 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 ergibt mit jeweils 50 % Wahrscheinlichkeit eine Null oder eine Eins, also ein wirklich zufälliges 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
nBitsbenötigt werden, um ganze Zahlen bis zumaxdarzustellen. - 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 Quanten-Zufallszahlengenerator wird die Zahl 6 als Ihr Passwort zurückgeben. 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 Sie einen Zufallsbitgenerator.
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
Wählen Sie Ihre bevorzugte Entwicklungsumgebung aus, entweder die QDK-Erweiterung in VS Code oder die QDK-Python-Bibliothek in Jupyter Notebook.
Öffnen Sie im VS Code das Menü "Datei ", und wählen Sie "Neue Textdatei " aus, um eine neue Datei zu erstellen.
Speichern Sie die Datei unter dem Namen
RandomNumberGenerator.qs. Diese Datei enthält den Q# Code für Ihr Programm.Kopieren Sie den folgenden Code in der
RandomNumberGenerator.qsDatei.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. }Wenn Sie Ihr Programm ausführen möchten, wählen Sie die Option "Ausführen" aus der Liste der vorherigen
Main()Befehle aus, oder drücken Sie STRG+F5. Das Programm führt denMain()Vorgang im Standardsimulator aus.
Die Ausgabe wird in der Debugkonsole angezeigt.
Führen Sie das Programm erneut aus, um ein anderes Ergebnis anzuzeigen.
Hinweis
Wenn das QIR-Profil target nicht auf "Uneingeschränkt" festgelegt ist, wird beim Ausführen des Programms eine Fehlermeldung angezeigt. Für dieses Programm legt der Compiler das target Profil automatisch auf "Uneingeschränkt" fest, es sei denn, Sie legen das Profil selbst fest.
Zeichnen des Häufigkeits histogramms
Lassen Sie uns die Verteilung der Ergebnisse visualisieren, die aus der Ausführung des Quantenprogramms mehrmals erzielt werden. Das Häufigkeits histogramm hilft dabei, die Wahrscheinlichkeitsverteilung dieser Ergebnisse zu visualisieren.
Select View -> Command Palette und geben Sie histogram ein, was den QDK: Run file and show histogram Befehl aufruft. Sie können auch Histogramm aus der Liste der Befehle vor
Main()auswählen. Wählen Sie diese Option aus, um das Q# Histogrammfenster zu öffnen.
Geben Sie eine Reihe von Aufnahmen ein, um das Programm auszuführen, z. B. 100 Aufnahmen, und drücken Sie die EINGABETASTE. Das Histogramm wird im Q# Histogrammfenster angezeigt.
Jeder Balken im Histogramm entspricht einem möglichen Ergebnis, und seine Höhe gibt an, wie oft dieses Ergebnis beobachtet wird. Die Anzahl der verschiedenen Ergebnisse kann bei jeder Ausführung des Histogramms unterschiedlich sein.
Tipp
Sie können das Histogramm mithilfe des Mausrads oder einer Trackpadgeste zoomen. Beim Vergrößern können Sie das Diagramm verschieben, indem Sie beim Scrollen die ALT-TASTE drücken.
Wählen Sie einen Balken aus, um den Prozentsatz dieses Ergebnisses anzuzeigen.
Wählen Sie das Symbol „Einstellungen“ oben links aus, um Optionen anzuzeigen. Sie können top 10 Ergebnisse, top 25 Ergebnisse oder alle Ergebnisse anzeigen. Sie können die Ergebnisse auch von hoch bis niedrig oder niedrig bis hoch sortieren.
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:
- Quantenverschränkung zeigt, wie man ein Q#-Programm schreibt, das Qubits manipuliert und misst und die Auswirkungen von Superposition und Verschränkung veranschaulicht.
- Grovers Suchalgorithmus zeigt, wie man ein Q# Programm schreibt, das Grovers Suchalgorithmus 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.