Övning del 2 – Skapa en kvantgenerator för slumptal
I den här lektionen implementerar du den andra fasen i kvant slumptalsgeneratorn: kombinera flera slumpmässiga bitar för att bilda ett större slumpmässigt tal. Den här fasen bygger på den slumpmässiga bitgenerator som du redan skapade i föregående lektion.
Kombinera flera slumpmässiga bitar för att bilda ett större tal
I föregående lektion skapade du en slumpmässig bitgenerator som genererar en slumpmässig bit genom att placera en qubit i superposition och mäta den.
När du mäter kvantbiten får du en slumpmässig bit, antingen 0 eller 1, med lika med 50 % sannolikhet. Värdet för den här biten är verkligen slumpmässigt, det finns inget sätt att veta vad du får efter mätningen. Men hur kan du använda det här beteendet för att generera större slumpmässiga tal?
Anta att du upprepar processen fyra gånger och genererar den här sekvensen med binära siffror:
$${0, 1, 1, 0}$$
Om du sammanfogar, eller kombinerar, dessa bitar till en bitsträng kan du skapa ett större tal. I det här exemplet motsvarar bitsekvensen ${0110}$ talet sex i decimalsystemet.
$${0110_{\ binary} \equiv 6_{\ decimal}}$$
Om du upprepar den här processen många gånger kan du kombinera flera bitar för att bilda ett stort tal.
Definiera logiken för slumptalsgeneratorn
Nu ska vi beskriva logiken för en slumptalsgenerator, förutsatt att den slumpmässiga bitgeneratorn som skapades i föregående enhet:
- Definiera
max
som det högsta antal som du vill generera. - Definiera antalet slumpmässiga bitar som du behöver generera genom att beräkna hur många bitar,
nBits
, du måste uttrycka heltal upp tillmax
. - Generera en slumpmässig bitsträng som har längden
nBits
. - Om bitsträngen representerar ett tal som är större än
max
går du tillbaka till steg tre. - I annat fall är processen slutförd. Returnera det genererade talet som ett heltal.
Som exempel anger vi max
till 12. Det vill: 12 är det största talet som du vill få från slumptalsgeneratorn.
Du behöver ${\lfloor ln(12) / ln(2) + 1 \rfloor}$, eller 4 bitar för att representera ett tal mellan 0 och 12. (För korthet hoppar vi över hur den här ekvationen ska härledas.)
Anta att du genererar bitsträngen ${1101_{\ binary}}$, som motsvarar ${13_{\ decimal}}$. Eftersom 13 är större än 12 upprepar du processen.
Sedan generar du bitsträngen ${0110_{\ binary}}$, som motsvarar ${6_{\ decimal}}$. Eftersom 6 är mindre än 12 är processen slutförd.
Slumptalsgeneratorn för kvant returnerar talet 6.
Skapa en fullständig slumptalsgenerator
Här expanderar Main.qs
du filen för att skapa större slumptal.
Importera nödvändiga bibliotek
Först måste du importera de nödvändiga namnrymderna från Q#Standard-biblioteket till programmet. Q#-kompilatorn läser in många vanliga funktioner och åtgärder automatiskt, men för den fullständiga kvantgeneratorn för slumptal behöver du ytterligare funktioner och åtgärder från två Q#-namnområden: Microsoft.Quantum.Math
och Microsoft.Quantum.Convert
.
Kopiera och klistra in följande import
direktiv överst Main.qs
i filen:
import Microsoft.Quantum.Convert.*;
import Microsoft.Quantum.Math.*;
Byt namn på Main
åtgärden till GenerateRandomBit
För den fullständiga slumptalsgeneratorn ska du återanvända åtgärden som definierades i föregående enhet. Åtgärdsnamnet Main
är dock startpunkten för programmet och bör vara unikt. För att undvika förvirring måste du byta namn på Main
åtgärden till GenerateRandomBit
.
Åtgärden GenerateRandomBit
bör se ut så här:
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;
}
Definiera åtgärden för kvant slumptal
Här definierar du åtgärden GenerateRandomNumberInRange
. Den här åtgärden anropar åtgärden GenerateRandomBit
upprepade gånger för att bygga en sträng med bitar.
Kopiera följande kod och klistra in den före åtgärden 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 is within the requested range.
// Generate it again if it is outside the range.
return sample > max ? GenerateRandomNumberInRange(max) | sample;
}
Vi tar och går igenom den nya koden.
- Du måste beräkna antalet bitar som behövs för att uttrycka heltal upp till
max
. FunktionenBitSizeI
frånMicrosoft.Quantum.Math
biblioteket konverterar ett heltal till det antal bitar som behövs för att representera det. - Åtgärden
GenerateRandomNumberInRange
använder enfor
-loop för att generera slumpmässiga tal tills den genererar ett som är lika med eller mindre änmax
. Loopenfor
fungerar exakt på samma sätt som enfor
loop i andra programmeringsspråk. - Variabeln
bits
är en föränderlig variabel. Föränderliga variabler kan ändras under beräkningen. Du kan använda direktivetset
för att ändra värdet för en föränderlig variabel. - Funktionen
ResultArrayAsInt
kommer frånMicrosoft.Quantum.Convert
biblioteket. Den här funktionen konverterar bitsträngen till ett positivt heltal.
Lägg till en startpunkt
Slutligen lägger du till en startpunkt i programmet. Som standard söker Q#-kompilatorn efter en Main
åtgärd och börjar bearbeta där, oavsett var den finns. Åtgärden Main
anropar GenerateRandomNumberInRange
åtgärden för att generera ett slumpmässigt tal mellan 0 och ett max
tal. I det här exemplet definierar du det maximala värdet som 100.
Kopiera och klistra in följande kod i Main.qs
filen:
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);
}
Slutligt program
Filen Main.qs
bör se ut så här:
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;
}
Köra programmet
Nu ska vi prova vår nya slumptalsgenerator!
- Innan du kör programmet måste du ange målprofilen till Obegränsad. Välj Visa>kommandopalett, sök efter QIR, välj Q#: Ange Azure Quantum QIR-målprofilen och välj sedan Q#: obegränsad.
- Om du vill köra programmet väljer du Kör i listan med kommandon ovanför
Main
åtgärden eller trycker på Ctrl+F5. Dina utdata visas i felsökningskonsolen. - Kör programmet igen för att se ett annat resultat.
Kommentar
Om målprofilen inte är inställd på Obegränsad får du ett fel när du kör programmet.
Grattis! Nu vet du hur du kombinerar klassisk logik med Q# för att skapa en slumpgenerator för kvanttal.
Bonusövning
Försök att ändra programmet för att även kräva att det genererade slumpmässiga talet är större än ett minsta tal, min
, i stället för noll.