Oefening deel 2: een kwantumgenerator voor willekeurige getallen maken
In deze eenheid implementeert u het tweede deel van uw kwantumgenerator voor willekeurige getallen. U combineert meerdere willekeurige bits om een groter willekeurig getal te vormen. Dit onderdeel bouwt voort op de random-bitgenerator die u al in de vorige les hebt gemaakt.
Meerdere willekeurige bits combineren om een groter getal te vormen
In de vorige eenheid hebt u een willekeurige bitgenerator gemaakt die een qubit in een superpositiestatus plaatst en vervolgens meet die qubit om willekeurige bitwaarde van 0 of 1 te genereren, elk met 50% waarschijnlijkheid. De waarde van deze bit is echt willekeurig, er is geen manier om vooraf te weten wat het meetresultaat is. Maar hoe kunt u dit gedrag gebruiken om grotere willekeurige getallen te genereren?
Als u het proces vier keer herhaalt, kunt u deze reeks binaire cijfers genereren:
$${0, 1, 1, 0}$$
Als u deze bits in een bittekenreeks combineert, kunt u een groter getal vormen. In dit voorbeeld is de bitreeks ${0110}$ in binair equivalent aan het getal 6 in decimaal.
$${0110_{\ binary} \equiv 6_{\ decimal}}$$
Als u een willekeurig groot willekeurig getal wilt genereren, herhaalt u dit proces vaak. Combineer vervolgens alle bits in een binair getal en converteer dat binaire getal naar een decimaal getal.
De logica definiëren voor de generator voor willekeurige getallen
Voordat u uw Q#-code schrijft, gaan we een overzicht maken van de logica voor het genereren van een willekeurig getal:
- Definieer
maxhet maximumdecimaal getal dat u wilt genereren. - Bepaal het aantal willekeurige bits,
nBitsdat vereist is om te genererenmax. - Genereer een tekenreeks voor willekeurige bits die
nBitsin lengte is. - Als de bittekenreeks een getal groter dan
maxvertegenwoordigt, ga terug naar de vorige stap. - Is dat niet het geval, dan is het proces voltooid. Retourneert het gegenereerde getal als een decimaal geheel getal.
Laten we bijvoorbeeld definiëren dat max gelijk is aan 12. Dat wil gezegd, 12 is het grootste getal dat uw generator voor willekeurige getallen moet uitvoeren.
Gebruik de volgende vergelijking om het aantal bits te bepalen dat is vereist om het getal 12 in binair getal weer te geven:
$${\lfloor ln(12) / ln(2) + 1 \rfloor}$$
Volgens deze vergelijking hebt u vier bits nodig om een getal tussen 0 en 12 weer te geven.
Stel dat u een willekeurige bit vier keer genereert en de bittekenreeks ${1101_{\ binary}}$ opgeeft. Deze waarde in binair is gelijk aan 13 in decimaal. Omdat 13 groter is dan 12, herhaalt u het proces.
Vervolgens genereert u de bittekenreeks ${0110_{\ binary}}$, die gelijk is aan ${6_{\ decimal}}$. Omdat 6 kleiner is dan 12, is het proces voltooid.
De kwantumgenerator voor willekeurige getallen retourneert het getal 6.
Een volledige generator voor willekeurige getallen maken in Q#
Hier vouwt u het Main.qs bestand uit de vorige les uit om uw generator voor willekeurige getallen te bouwen.
De vereiste bibliotheken importeren
Importeer eerst de naamruimten uit de Q#-standaardbibliotheek die de functies en bewerkingen bevat die u nodig hebt om uw programma te schrijven. De Q#-compiler laadt automatisch veel algemene functies en bewerkingen. Maar voor de kwantumgenerator voor willekeurige getallen hebt u enkele extra functies en bewerkingen van twee Q#-naamruimten nodig: Microsoft.Quantum.Math en Microsoft.Quantum.Convert.
Kopieer en plak de volgende import instructies aan het begin van het Main.qs bestand:
import Std.Convert.*;
import Std.Math.*;
Notitie
U kunt Std in plaats van Microsoft.Quantum functies en bewerkingen importeren uit de standaardbibliotheek.
Wijzig de naam van de Main bewerking in GenerateRandomBit
Het generatorprogramma voor willekeurige getallen gebruikt de Main bewerking die u in de vorige les hebt geschreven om een willekeurige bit te genereren. Wijzig de naam van de Main bewerking zodat GenerateRandomBit deze bewerking een meer beschrijvende naam heeft en niet het toegangspunt is voor het programma.
Kopieer en plak de volgende code in 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;
}
De generatorbewerking voor willekeurige getallen definiëren
Maak een nieuwe bewerking met de naam GenerateRandomNumberInRange. Met deze bewerking wordt herhaaldelijk de bewerking GenerateRandomBit aangeroepen om een bit-tekenreeks te maken.
Kopieer de volgende code en plaats deze direct vóór de GenerateRandomBit bewerking in uw Main.qs bestand:
/// 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;
}
Hier volgt een overzicht van de code in GenerateRandomNumberInRange:
- Roep de
BitSizeIfunctie aan uit deStd.Mathbibliotheek om het aantal bits te berekenen dat nodig is om het gehele getal weer te geven waarin is opgeslagenmax. - Gebruik een
forlus om een aantal willekeurige bits te genereren die gelijk zijn aannBits. Roep uwGenerateRandomBitbewerking aan om de willekeurige bits te genereren. - Gebruik de
forsetinstructie om debitsvariabele bij te werken met elke nieuwe willekeurige bit. De variabelebitsis een veranderlijke variabele, wat betekent dat de waarde vanbitsde berekening kan worden gewijzigd. - Roep de
ResultArrayAsIntfunctie van deStd.Convertbibliotheek aan om de matrix met bitsbitste converteren naar een positief geheel getal dat is opgeslagen insample. - Controleer in de
return-verklaring ofsamplegroter is danmax. Alssamplegroter is danmax, voerGenerateRandomNumberInRangeopnieuw uit en begin opnieuw. Anders retourneert u het willekeurige getal dat is opgeslagen insample.
Een toegangspunt toevoegen
Voeg ten slotte een invoerpuntbewerking toe aan uw code, zodat de compiler uw programma kan uitvoeren. De Q#-compiler zoekt standaard naar een Main bewerking en gebruikt Main als toegangspunt, ongeacht waar Main zich zich in uw bestand bevindt. Hier stelt de Main-bewerking een waarde in voor max en voert vervolgens de GenerateRandomNumberInRange-bewerking uit om een willekeurig getal tussen 0 en max te genereren.
Als u bijvoorbeeld een willekeurig getal tussen 0 en 100 wilt genereren, kopieert u de volgende code naar uw Main.qs bestand:
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);
}
Definitief programma
Hier volgt de volledige Q#-code voor uw programma in 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;
}
Het programma uitvoeren
Probeer uw nieuwe kwantumgenerator voor willekeurige getallen!
Als u uw programma wilt uitvoeren, kiest u de code lens Run uit de lijst met opdrachten boven de Main operatie. Of druk op Ctrl+F5. De uitvoer wordt weergegeven in de debugconsole. Voer het programma meerdere keren uit en u ziet hoe het resultaat verandert.
Gefeliciteerd U hebt een echt willekeurige kwantumnummergenerator gemaakt in Q#.
Bonusoefening
Probeer het programma zo te wijzigen dat ook het gegenereerde willekeurige getal groter is dan een minimaal positief getal, minin plaats van nul.