Übung, Teil 2: Erstellen eines Quanten-Zufallszahlengenerators
In dieser Einheit implementieren Sie die zweite Phase des Quanten-Zufallszahlen-Generators: die Kombination mehrerer Zufallsbits, um eine größere Zufallszahl zu bilden. Diese Phase baut auf dem Zufallsbit-Generator auf, den Sie in der vorherigen Lektion bereits erstellt haben.
Kombinieren mehrerer zufälliger Bits, um eine größere Zahl zu bilden
In der vorherigen Lerneinheit haben Sie einen Zufallsbitgenerator erstellt, der ein zufälliges Bit generiert, indem ein Qubit in die Superposition gesetzt und gemessen wird.
Wenn Sie das Qubit messen, erhalten Sie mit einer Wahrscheinlichkeit von 50 % ein zufälliges Bit, entweder 0 oder 1. Der Wert dieses Bits ist wirklich zufällig. Sie können nicht wissen, welches Ergebnis Sie mit der Messung erhalten. 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.
Definieren der Logik für den Zufallszahlen-Generator
Sehen wir uns an, wie die Logik eines Zufallszahlengenerators aussehen sollte, vorausgesetzt, der zufällige Bitgenerator, der in der vorherigen Einheit erstellt wurde, ist vorhanden:
- Definieren Sie
max
als höchste Zahl, die Sie generieren möchten. - Definieren Sie die Anzahl zufälliger Bits, die Sie generieren müssen, indem Sie berechnen, wie viele Bits,
nBits
, Sie benötigen, um ganze Zahlen bismax
auszudrücken. - Generieren Sie eine zufällige Bitzeichenfolge, die
nBits
lang ist. - Wenn die Bitzeichenfolge eine Zahl größer als
max
darstellt, 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 aus dem Zufallszahlengenerator abrufen möchten.
Sie benötigen ${\lfloor ln(12) / ln(2) + 1 \rfloor}$ gleich 4 Bits, um eine Zahl zwischen 0 und 12 darzustellen. (Aus Platzgründen überspringen wir die Ableitung dieser Gleichung.)
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 die Zahl 6 zurück.
Erstellen eines vollständigen Zufallszahlengenerators
Hier erweitern Sie die Main.qs
-Datei, um größere Zufallszahlen zu erstellen.
Importieren der erforderlichen Bibliotheken
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. Für den vollständigen Quanten-Zufallszahlengenerator benötigen Sie jedoch einige zusätzliche Funktionen und Vorgänge aus zwei Q#-Namespaces: Microsoft.Quantum.Math
und Microsoft.Quantum.Convert
.
Kopieren Sie die folgenden import
-Anweisungen, und fügen Sie sie am Anfang Ihrer Main.qs
-Datei hinzu:
import Microsoft.Quantum.Convert.*;
import Microsoft.Quantum.Math.*;
Umbenennen des Main
-Vorgangs in GenerateRandomBit
Für den vollständigen Zufallszahlengenerator werden Sie den in der vorherigen Lektion definierten Vorgang wiederverwenden. Der Vorgangsname Main
ist jedoch der Einstiegspunkt des Programms und sollte eindeutig sein. Um Verwirrung zu vermeiden, müssen Sie den Main
-Vorgang in GenerateRandomBit
umbenennen.
Der GenerateRandomBit
-Vorgang sollte wie folgt aussehen:
operation GenerateRandomBit() : Result {
// Allocate a qubit.
use q = Qubit();
// Set the qubit into superposition of 0 and 1 using the Hadamard
H(q);
// Measure the qubit and store the result.
let result = M(q);
// Reset qubit to the |0〉 state.
Reset(q);
// Return the result of the measurement.
return result;
}
Definieren des zufälligen Quantenzahlenvorgangs
Hier definieren Sie den GenerateRandomNumberInRange
-Vorgang. Mit diesem Vorgang wird der GenerateRandomBit
-Vorgang wiederholt aufgerufen, um eine Bitzeichenfolge zu erstellen.
Kopieren Sie den folgenden Code, und fügen Sie diesen vor dem GenerateRandomBit
-Vorgang in Ihre Main.qs
-Datei ein.
/// 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 {
set 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
max
ausdrücken. DieBitSizeI
-Funktion aus derMicrosoft.Quantum.Math
-Bibliothek konvertiert eine ganze Zahl in die Anzahl der Bits, die erforderlich sind, um sie darzustellen. - Der
GenerateRandomNumberInRange
-Vorgang verwendet einefor
-Schleife zum Generieren von Zufallszahlen, bis eine Zahl generiert wird, die kleiner oder gleichmax
ist. Diefor
-Schleife funktioniert genauso wie einefor
-Schleife in anderen Programmiersprachen. - Die Variable
bits
ist 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
ResultArrayAsInt
-Funktion stammt aus derMicrosoft.Quantum.Convert
-Bibliothek. Mit dieser Funktion wird die Bitzeichenfolge in eine positive ganze Zahl konvertiert.
Hinzufügen eines Einstiegspunkts
Schließlich fügen Sie dem Programm einen Einstiegspunkt hinzu. Standardmäßig sucht der Q#-Compiler nach einem Main
-Vorgang und startet die Verarbeitung dort, unabhängig davon, wo er sich befindet. Der Main
-Vorgang ruft den GenerateRandomNumberInRange
-Vorgang auf, um eine zufällige Zahl zwischen 0 und einer max
Zahl zu generieren. In diesem Beispiel definieren Sie den Maximalwert als 100.
Kopieren Sie den folgenden Code, und fügen Sie ihn in Ihre Main.qs
Datei ein:
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);
}
Endgültiges Programm
Ihre Datei Main.qs
sollte wie folgt aussehen:
import Microsoft.Quantum.Convert.*;
import Microsoft.Quantum.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 {
set 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 the Hadamard operation
H(q);
// 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.
Reset(q);
// Return the result of the measurement.
return result;
}
Ausführen des Programms
Testen Sie den neuen Zufallszahlen-Generator.
- Bevor Sie das Programm ausführen, müssen Sie das Zielprofil auf Uneingeschränkt festlegen. Wählen Sie Ansicht>Befehlspalette aus, suchen Sie nach QIR, wählen Sie Q# aus: Legen Sie das Azure Quantum QIR-Zielprofil fest und wählen Sie dann Q#: uneingeschränkt aus.
- Um Ihr Programm auszuführen, wählen Sie in der Liste der Befehle über dem Vorgang
Main
Ausführen aus, oder drücken Sie STRG+F5. Die Ausgabe wird in der Debugkonsole angezeigt. - Führen Sie das Programm erneut aus, um ein anderes Ergebnis anzuzeigen.
Hinweis
Wenn das Zielprofil nicht auf Uneingeschränkt festgelegt ist, wird beim Ausführen des Programms eine Fehlermeldung angezeigt.
Herzlichen Glückwunsch! Nun wissen Sie, wie klassische Logik mit Q# kombiniert werden kann, um einen Quanten-Zufallszahlen-Generator zu erstellen.
Zusatzübung
Ändern Sie das Programm so, dass die generierte Zufallszahl auch größer als die Mindestzahl min
statt null ist.