Øvelse Del 2 – Opprett en kvante tilfeldig tallgenerator
I denne enheten implementerer du den andre delen av kvantetilfeldig tallgenerator. Du kombinerer flere tilfeldige biter for å danne et større tilfeldig tall. Denne delen bygger på den tilfeldige bitgeneratoren som du allerede opprettet i forrige enhet.
Kombinere flere tilfeldige biter for å danne et større tall
I den forrige enheten opprettet du en tilfeldig bitgenerator som setter en kvantebit i en superposisjonstilstand og deretter måler den kvantebiten for å generere tilfeldig bitverdi på enten 0 eller 1, hver med 50% sannsynlighet. Verdien av denne biten er virkelig tilfeldig, det er ingen måte å vite på forhånd hva måleresultatet vil bli. Men hvordan kan du bruke denne virkemåten til å generere større tilfeldige tall?
Hvis du gjentar prosessen fire ganger, kan du generere denne sekvensen av binære sifre:
$${0, 1, 1, 0}$$
Hvis du kombinerer disse bitene til en bitstreng, kan du danne et større tall. I dette eksemplet tilsvarer bitsekvensen ${0110}$ i binær tallet 6 i desimal.
$${0110_{\ binær} \ekvivalent 6_{\ desimal}}$$
For å generere et vilkårlig stort tilfeldig tall, gjenta bare denne prosessen mange ganger. Deretter kombinerer du alle bitene til et binært tall og konverterer det binære tallet til et desimaltall.
Definer den tilfeldige tallgeneratorlogikken
Før du skriver Q#-koden din, la oss skissere logikken for å generere et tilfeldig tall:
- Definer
maxsom maksimalt desimaltall du vil generere. - Bestem antall tilfeldige biter,
nBits, som kreves for å genereremax. - Generer en tilfeldig bitstreng som er
nBitsi lengden. - Hvis bitstrengen representerer et tall som er større enn
max, går du tilbake til forrige trinn. - Ellers er prosessen fullført. Returner det genererte tallet som et desimalheltall.
La oss for eksempel definere max å være 12. Det vil si at 12 er det største tallet som tilfeldig tallgeneratoren din skal sende ut.
Bruk følgende formel til å bestemme antall biter som kreves for å representere tallet 12 i binær:
$${\lgulv ln(12) / ln(2) + 1 \retasje}$$
I følge denne ligningen trenger du 4 biter for å representere et tall mellom 0 og 12.
La oss for eksempel si at du genererer en tilfeldig bit fire ganger og får bitstrengen ${1101_{\ binær}}$. Denne verdien i binær er lik 13 i desimal. Fordi 13 er større enn 12, gjentar du prosessen.
Deretter genererer du bitstrengen ${0110_{\ binær}}$, som er lik ${6_{\ desimal}}$. Fordi 6 er mindre enn 12, er prosessen fullført.
Quantum random number generator returnerer tallet 6.
Lag en komplett tilfeldig tallgenerator i Q#
Her utvider Main.qs du filen fra forrige leksjon for å bygge tilfeldig tallgenerator.
Importer de nødvendige bibliotekene
Først importerer du navneområdene fra Q#-standardbiblioteket som inneholder funksjonene og operasjonene du trenger for å skrive programmet. Q#-kompilatoren laster inn mange vanlige funksjoner og operasjoner automatisk. Men for kvantetilfeldig tallgeneratoren trenger du noen tilleggsfunksjoner og operasjoner fra to Q#-navnerom: Std.Math og Std.Convert.
Kopier og lim inn følgende import direktiver i begynnelsen av Main.qs filen:
import Std.Convert.*;
import Std.Math.*;
Gi Main nytt navn til GenerateRandomBit
Tilfeldig tallgenerator-programmet bruker operasjonen Main du skrev i forrige enhet for å generere en tilfeldig bit. Gi operasjonen Main nytt navn slik GenerateRandomBit at denne operasjonen har et mer beskrivende navn og ikke er inngangspunktet til programmet.
Kopier og lim inn følgende kode i Main.qs:
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;
}
Definer operasjonen for tilfeldig tallgenerator
Opprett en ny operasjon kalt GenerateRandomNumberInRange. Denne operasjonen kaller gjentatte ganger GenerateRandomBit-operasjonen for å bygge en streng med biter.
Kopier følgende kode og plasser den rett før operasjonen GenerateRandomBit i Main.qs filen:
/// 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;
}
Her er en oversikt over koden i GenerateRandomNumberInRange:
- Kall funksjonen
BitSizeIfraStd.Mathbiblioteket for å beregne antall biter som trengs for å representere heltallet som er lagret imax. - Bruk en
forløkke til å generere et antall tilfeldige biter liknBits. Ring operasjonen dinGenerateRandomBitfor å generere de tilfeldige bitene. - Inne i løkken
forbruker du setningensettil å oppdatere variabelenbitsmed hver nye tilfeldige bit. Variabelenbitser en foranderlig variabel, noe som betyr at verdien avbitskan endres under beregningen. - Kall funksjonen
ResultArrayAsIntfraStd.Convertbiblioteket for å konvertere matrisen med biter tilbitset positivt heltall som er lagret isample. - I utsagnet
returnkontrollerer du omsampleer større ennmax. Hvissampleer større ennmax, ringGenerateRandomNumberInRangeigjen og start på nytt. Ellers returnerer du det tilfeldige tallet som er lagret isample.
Legge til et inngangspunkt
Til slutt legger du til en inngangspunktoperasjon i koden slik at kompilatoren kan kjøre programmet. Som standard ser Q#-kompilatoren etter en Main operasjon og bruker Main den som inngangspunkt, uansett hvor Main den befinner seg i filen. Her Main setter operasjonen en verdi for max og kaller GenerateRandomNumberInRange operasjonen for å generere et tilfeldig tall mellom 0 og max.
Hvis du for eksempel vil generere et tilfeldig tall mellom 0 og 100, kopierer du følgende kode til Main.qs filen:
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);
}
Endelig program
Her er den fullstendige Q#-koden for programmet ditt i 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;
}
Kjør programmet
Prøv din nye kvantetilfeldige tallgenerator!
For å kjøre programmet, velg Kjør kodelinse fra listen over kommandoer over operasjonen Main . Eller trykk CTRL + F5. Utdataene vises i feilsøkingskonsollen. Kjør programmet flere ganger og legg merke til hvordan resultatet endres.
Gratulerer! Du opprettet en virkelig tilfeldig kvantetallsgenerator i Q#.
Bonusøvelse
Prøv å endre programmet slik at det også krever at det genererte tilfeldige tallet er større enn et minimum positivt tall, min, i stedet for null.