Ćwiczenie— część 2 — tworzenie kwantowego generatora liczb losowych
W tej lekcji zaimplementujesz drugą fazę kwantowego generatora liczb losowych: łącząc wiele losowych bitów w celu utworzenia większej liczby losowej. Ta faza 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 generuje losowy bit, umieszczając kubit w superpozycję i mierząc go.
Po zmierzeniu kubitu otrzymasz losowy bit (0 lub 1) z równym 50% prawdopodobieństwem. Wartość tego bitu jest naprawdę losowa, nie ma możliwości poznania tego, co otrzymujesz po pomiarze. Ale jak można użyć tego zachowania, aby wygenerować większe liczby losowe?
Załóżmy, że powtarzasz ten proces cztery razy, generując następującą sekwencję cyfr binarnych:
$${0, 1, 1, 0}$$
Jeśli połączysz te bity w ciąg bitów, możesz utworzyć większą liczbę. W tym przykładzie sekwencja bitowa ${0110}$ jest równa liczbie sześć w postaci dziesiętnej.
$${0110_{\ binary} \equiv 6_{\ decimal}}$$
W przypadku wielokrotnego powtarzania tego procesu można połączyć wiele bitów, aby utworzyć dowolną dużą liczbę.
Definiowanie logiki generatora liczb losowych
Określmy, jaka powinna być logika generatora liczb losowych, pod warunkiem, że generator bitów losowych został utworzony w poprzedniej lekcji:
- Zdefiniuj
max
jako maksymalną liczbę, którą chcesz wygenerować. - Zdefiniuj liczbę bitów losowych, które należy wygenerować, obliczając liczbę bitów ,
nBits
należy wyrazić liczby całkowite domax
. - Wygeneruj losowy ciąg bitowy o długości
nBits
. - Jeśli ciąg bitowy reprezentuje liczbę większą niż
max
, wróć do kroku trzeciego. - W przeciwnym razie proces zostanie zakończony. Zwróć wygenerowaną liczbę jako liczbę całkowitą.
Załóżmy na przykład, że wartość max
wynosi 12. Oznacza to, że 12 jest największą liczbą, którą chcesz uzyskać z generatora liczb losowych.
Potrzebujesz ${\lfloor ln(12) / ln(2) + 1 \rfloor}$, lub 4 bity do reprezentowania liczby z zakresu od 0 do 12. (W celu zwięzłości pomijamy sposób tworzenia tego równania).
Załóżmy, że wygenerujesz ciąg bitowy ${1101_{\ binary}}$, który jest odpowiednikiem ciągu ${13_{\ decimal}}$. Ponieważ 13 jest większe niż 12, należy powtórzyć proces.
Następnie wygenerujesz ciąg bitowy ${0110_{\ binary}}$, który jest odpowiednikiem ciągu ${6_{\ decimal}}$. Ponieważ 6 jest mniejsze niż 12, proces jest zakończony.
Kwantowy generator liczb losowych zwraca liczbę 6.
Tworzenie kompletnego generatora liczb losowych
W tym miejscu rozszerzysz Main.qs
plik, aby utworzyć większe liczby losowe.
Importowanie wymaganych bibliotek
Najpierw należy zaimportować wymagane przestrzenie nazw z biblioteki Q# Standard do programu. Kompilator języka Q# ładuje wiele typowych funkcji i operacji automatycznie, jednak w przypadku kompletnego 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 Microsoft.Quantum.Convert.*;
import Microsoft.Quantum.Math.*;
Zmień nazwę operacji na Main
GenerateRandomBit
W przypadku pełnego generatora liczb losowych użyjesz ponownie operacji zdefiniowanej w poprzedniej lekcji. Jednak nazwa Main
operacji jest punktem wejścia programu i powinna być unikatowa. Aby uniknąć nieporozumień, musisz zmienić nazwę Main
operacji na GenerateRandomBit
.
Operacja GenerateRandomBit
powinna wyglądać następująco:
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 kwantowej operacji liczb losowych
Teraz zdefiniujesz operację GenerateRandomNumberInRange
. Ta operacja wielokrotnie wywołuje operację GenerateRandomBit
, aby utworzyć ciąg bitów.
Skopiuj następujący kod i wklej go przed operacją GenerateRandomBit
do 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 is within the requested range.
// Generate it again if it is outside the range.
return sample > max ? GenerateRandomNumberInRange(max) | sample;
}
Poświęćmy chwilę na przejrzenie nowego kodu.
- Musisz obliczyć liczbę bitów potrzebnych do wyrażenia liczb całkowitych do
max
. FunkcjaBitSizeI
zMicrosoft.Quantum.Math
biblioteki konwertuje liczbę całkowitą na liczbę bitów potrzebnych do jej reprezentowania. - Operacja
GenerateRandomNumberInRange
używa pętlifor
do generowania liczb losowych do momentu wygenerowania takiej liczby, która jest równa lub mniejsza niżmax
. Pętlafor
działa dokładnie tak samo jak pętlafor
w innych językach programowania. - Zmienna
bits
jest zmienną modyfikowalnym. Zmienna modyfikowalna to taka, która może się zmienić podczas obliczania. Aby zmienić wartość zmiennej modyfikowalnej, należy użyć dyrektywyset
. - Funkcja
ResultArrayAsInt
pochodzi zMicrosoft.Quantum.Convert
biblioteki. Ta funkcja konwertuje ciąg bitowy na dodatnią liczbę całkowitą.
Dodawanie punktu wejścia
Na koniec dodasz punkt wejścia do programu. Domyślnie kompilator języka Q# szuka Main
operacji i rozpoczyna przetwarzanie, niezależnie od tego, gdzie się znajduje. Operacja Main
wywołuje operację GenerateRandomNumberInRange
, aby wygenerować losową liczbę z zakresu od 0 do max
liczby. W tym przykładzie zdefiniujesz maksymalną wartość jako 100.
Skopiuj i wklej następujący kod do pliku Main.qs
:
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);
}
Końcowy program
Plik Main.qs
powinien wyglądać następująco:
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;
}
Uruchamianie programu
Wypróbujmy nasz nowy generator liczb losowych.
- Przed uruchomieniem programu należy ustawić profil docelowy na Wartość Bez ograniczeń. Wybierz pozycję Wyświetl>paletę poleceń, wyszukaj pozycję QIR, wybierz pozycję Q#: Ustaw profil docelowy usługi Azure Quantum QIR, a następnie wybierz pozycję Q#: nieograniczone.
- Aby uruchomić program, wybierz pozycję Uruchom z listy poleceń powyżej
Main
operacji lub naciśnij Ctrl+F5. Dane wyjściowe zostaną wyświetlone w konsoli debugowania. - Uruchom ponownie program, aby zobaczyć inny wynik.
Uwaga
Jeśli profil docelowy nie jest ustawiony na Unrestricted, podczas uruchamiania programu zostanie wyświetlony błąd.
Gratulacje! Teraz już wiesz, jak połączyć klasyczną logikę z językiem Q#, aby utworzyć kwantowy generator liczb losowych.
Ćwiczenie dodatkowe
Spróbuj zmodyfikować program, aby wymagać również wygenerowanej liczby losowej większej niż minimalna liczba, min
zamiast zera.