Ćwiczenie— część 2 — tworzenie kwantowego generatora liczb losowych
W tej lekcji zaimplementujesz drugą część kwantowego generatora liczb losowych. Połączysz wiele losowych bitów, aby utworzyć większą liczbę losową. Ta część opiera się na generatorze bitów losowych, który został już utworzony w poprzedniej lekcji.
Łączenie wielu losowych bitów w celu utworzenia większej liczby
W poprzedniej lekcji utworzono generator bitów losowych, który umieszcza kubit w stanie superpozycji, a następnie mierzy kubit w celu wygenerowania losowej wartości bitowej 0 lub 1, z których każdy ma 50% prawdopodobieństwa. Wartość tego bitu jest naprawdę losowa, nie ma możliwości z wyprzedzeniem wiedzieć, jaki będzie wynik pomiaru. Ale jak można użyć tego zachowania, aby wygenerować większe liczby losowe?
Jeśli powtarzasz proces cztery razy, możesz wygenerować tę sekwencję cyfr binarnych:
$${0, 1, 1, 0}$$
Jeśli połączysz te bity w ciąg bitowy, możesz utworzyć większą liczbę. W tym przykładzie sekwencja bitowa ${0110}$ w zapisie binarnym jest równoważna liczbie 6 w systemie dziesiętnym.
$${0110_{\ binary} \equiv 6_{\ decimal}}$$
Aby wygenerować dowolnie dużą liczbę losową, po prostu powtórz ten proces wiele razy. Następnie połącz wszystkie bity w liczbę binarną i przekonwertuj liczbę binarną na liczbę dziesiętną.
Definiowanie logiki generatora liczb losowych
Przed napisaniem kodu w języku Q# przedstawimy logikę generowania liczby losowej:
- Zdefiniuj
maxjako maksymalną liczbę dziesiętną, którą chcesz wygenerować. - Określ liczbę losowych bitów,
nBits, które są wymagane do wygenerowaniamax. - Wygeneruj losowy ciąg bitowy o długości
nBits. - Jeśli ciąg bitowy reprezentuje liczbę większą niż
max, wróć do poprzedniego kroku. - W przeciwnym razie proces zostanie zakończony. Zwraca wygenerowaną liczbę jako liczbę dziesiętną.
Na przykład zdefiniujmy max wartość 12. Oznacza to, że 12 jest największą liczbą, którą powinien wygenerować generator liczb losowych.
Użyj następującego równania, aby określić liczbę bitów wymaganą do reprezentowania liczby 12 w pliku binarnym:
$${\lfloor ln(12) / ln(2) + 1 \rfloor}$$
Zgodnie z tym równaniem potrzebne są 4 bity do reprezentowania liczby z zakresu od 0 do 12.
Załóżmy na przykład, że generujesz losowy bit cztery razy i pobierasz ciąg bitowy ${1101_{\ binary}}$. Ta wartość w systemie binarnym jest równa 13 w systemie dziesiętnym. Ponieważ 13 jest większe niż 12, należy powtórzyć proces.
Następnie wygenerujesz ciąg bitowy ${0110_{\ binary}}$, który jest równy ${6_{\ decimal}}$. Ponieważ 6 jest mniejsze niż 12, proces jest zakończony.
Kwantowy generator liczb losowych zwraca liczbę 6.
Tworzenie pełnego generatora liczb losowych w języku Q#
W tym miejscu rozszerzysz Main.qs plik z poprzedniej lekcji, aby skompilować generator liczb losowych.
Importowanie wymaganych bibliotek
Najpierw zaimportuj przestrzenie nazw z standardowej biblioteki języka Q#, która zawiera funkcje i operacje potrzebne do zapisania programu. Kompilator języka Q# ładuje wiele typowych funkcji i operacji automatycznie. Jednak w przypadku kwantowego generatora liczb losowych potrzebne są pewne dodatkowe funkcje i operacje z dwóch przestrzeni nazw języka Q#: Microsoft.Quantum.Math i Microsoft.Quantum.Convert.
Skopiuj i wklej następujące import dyrektywy na początku Main.qs pliku:
import Std.Convert.*;
import Std.Math.*;
Uwaga
Można używać Std zamiast Microsoft.Quantum do importowania funkcji i operacji z biblioteki standardowej.
Zmień nazwę operacji na MainGenerateRandomBit
Program generatora liczb losowych używa Main operacji, którą napisałeś w poprzedniej jednostce, aby wygenerować losowy bit.
Main Zmień nazwę operacji na GenerateRandomBit tak, aby ta operacja ma bardziej opisową nazwę i nie jest punktem wejścia do programu.
Skopiuj i wklej następujący kod do Main.qspliku :
import Std.Convert.*;
import Std.Math.*;
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;
}
Definiowanie operacji generatora liczb losowych
Utwórz nową operację o nazwie GenerateRandomNumberInRange. Ta operacja wielokrotnie wywołuje operację GenerateRandomBit, aby utworzyć ciąg bitów.
Skopiuj następujący kod i umieść go bezpośrednio przed operacją GenerateRandomBit w Main.qs pliku:
/// 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's within the requested range.
// Generate it again if it's outside the range.
return sample > max ? GenerateRandomNumberInRange(max) | sample;
}
Oto omówienie kodu w pliku GenerateRandomNumberInRange:
- Wywołaj funkcję
BitSizeIz bibliotekiStd.Math, aby obliczyć liczbę bitów potrzebnych do reprezentowania liczby całkowitej przechowywanej wmax. -
forUżyj pętli, aby wygenerować liczbę losowych bitów równychnBits. Wywołaj operacjęGenerateRandomBit, aby wygenerować losowe bity. - Wewnątrz pętli, użyj instrukcji
set, aby zaktualizować zmiennąbitskażdym nowym losowym bitem. Zmiennabitsjest zmienną modyfikowalnym, co oznacza, że wartośćbitsmoże ulec zmianie podczas obliczeń. - Wywołaj funkcję
ResultArrayAsIntz bibliotekiStd.Convert, aby przekonwertować tablicę bitów wbitsna dodatnią liczbę całkowitą przechowywaną wsample. - W instrukcji
returnsprawdź, czy wartośćsamplejest większa niżmax. Jeślisamplewartość jest większa niżmax, wywołajGenerateRandomNumberInRangeponownie i rozpocznij od nowa. W przeciwnym razie zwróć losową liczbę przechowywaną wsample.
Dodawanie punktu wejścia
Na koniec dodaj operację punktu wejścia do kodu, aby kompilator mógł uruchomić program. Domyślnie kompilator języka Q# szuka Main operacji i używa Main jej jako punktu wejścia, niezależnie od tego, gdzie Main znajduje się w pliku. W tym miejscu operacja ustawia wartość parametru max i wywołuje operację GenerateRandomNumberInRange w celu wygenerowania losowej liczby z zakresu od 0 do max.
Na przykład aby wygenerować losową liczbę z zakresu od 0 do 100, skopiuj następujący kod do Main.qs pliku:
operation Main() : Int {
let max = 100;
Message($"Generating a random number between 0 and {max}: ");
// Generate random number in the 0..max range.
return GenerateRandomNumberInRange(max);
}
Końcowy program
Oto kompletny kod języka Q# dla programu w pliku Main.qs:
import Std.Convert.*;
import Std.Math.*;
operation Main() : Int {
let max = 100;
Message($"Generating 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's within the requested range.
// Generate it again if it's 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;
}
Uruchamianie programu
Wypróbuj nowy kwantowy generator liczb losowych!
Aby uruchomić program, wybierz opcję Uruchom z listy poleceń powyżej operacji Main. Lub naciśnij Ctrl + F5. Twój wynik jest wyświetlany w konsoli debugowania. Uruchom program wiele razy i zwróć uwagę, jak zmienia się wynik.
Gratulacje! Utworzono prawdziwie losowy generator liczb kwantowych w języku Q#.
Ćwiczenie dodatkowe
Spróbuj zmodyfikować program, aby wymagać również wygenerowanej liczby losowej większej niż minimalna liczba dodatnia, minzamiast zera.