Zelfstudie: Een kwantumgenerator voor willekeurige getallen implementeren in Q#
In deze zelfstudie leert u hoe u een basis kwantumprogramma schrijft waarin Q# gebruik wordt gemaakt van de aard van de kwantummechanica om een willekeurig getal te produceren.
In deze zelfstudie leert u het volgende:
- Maak een Q# programma.
- Bekijk de belangrijkste onderdelen van een Q# programma.
- Definieer de logica van een probleem.
- Combineer klassieke en kwantumbewerkingen om een probleem op te lossen.
- Werken met qubits en superpositie om een kwantumgenerator van willekeurige getallen te maken.
Tip
Als u uw kwantumcomputingtraject wilt versnellen, bekijkt u Code met Azure Quantum, een unieke functie van de Azure Quantum-website. Hier kunt u ingebouwde Q# voorbeelden of uw eigen Q# programma's uitvoeren, nieuwe Q# code genereren vanuit uw prompts, uw code openen en uitvoeren in VS Code voor het web met één klik en Copilot vragen stellen over kwantumcomputing.
Vereisten
Het codevoorbeeld uitvoeren in Copilot in Azure Quantum:
- Een Microsoft-e-mailaccount (MSA).
Het codevoorbeeld ontwikkelen en uitvoeren in Visual Studio Code:
De nieuwste versie van Visual Studio Code of open VS Code op het web.
De nieuwste versie van de Azure-extensieQuantum Development Kit. Zie De QDK-extensie instellenvoor installatiedetails.
Als u Jupyter Notebooks wilt gebruiken, moet u ook Python
qsharp
. Hiervoor opent u een terminal en voert u de volgende opdracht uit:$ pip install --upgrade qsharp
Het probleem definiëren
Klassieke computers produceren geen willekeurige getallen, maar eerder pseudorandom getallen. Een pseudorandom-getalgenerator genereert een deterministische reeks getallen op basis van een bepaalde initiële waarde, een seed genoemd. Voor een betere benadering van willekeurige waarden is deze seed vaak de huidige tijd van de CPU-klok.
Kwantumcomputers kunnen daarentegen echt willekeurige getallen genereren. Dit komt doordat de meting van een qubit in superpositie een probabilistisch proces is. Het resultaat van de meting is willekeurig en er is geen manier om het resultaat te voorspellen. Dit is het basisprincipe van kwantumgeneratoren voor willekeurige getallen.
Een qubit is een eenheid van kwantumgegevens die zich in superpositie kunnen bevindt. Wanneer gemeten, kan een qubit alleen de status 0 of de 1-status hebben. Voordat de meting wordt uitgevoerd, vertegenwoordigt de toestand van de qubit echter de waarschijnlijkheid van het lezen van een 0 of een 1 met een meting.
U begint met het nemen van een qubit in een basisstatus, bijvoorbeeld nul. De eerste stap van de generator voor willekeurige getallen is het gebruik van een Hadamard-bewerking om de qubit in een gelijke superpositie te plaatsen. De meting van deze toestand resulteert in een nul of een met 50% waarschijnlijkheid van elk resultaat, een echt willekeurige bit.
Er is geen manier om te weten wat u krijgt na de meting van de qubit in superpositie en het resultaat is een andere waarde telkens wanneer de code wordt aangeroepen. Maar hoe kunt u dit gedrag gebruiken om grotere willekeurige getallen te genereren?
Stel dat u het proces vier keer herhaalt, waarna deze reeks binaire cijfers wordt gegenereerd:
$${0, 1, 1, 0}$$
Als u deze bits samenvoegt of combineert in een bit-tekenreeks, kunt u een groter getal vormen. In dit voorbeeld is de bitreeks ${0110}$ gelijk aan zes in decimalen.
$${0110_{\ binary} \equiv 6_{\ decimal}}$$
Als u dit proces meerdere keren herhaalt, kunt u meerdere bits combineren om een groot getal te vormen. Met deze methode kunt u een getal maken dat moet worden gebruikt als een veilig wachtwoord, omdat u er zeker van kunt zijn dat geen hacker de resultaten van de reeks metingen kan bepalen.
De logica definiëren voor de generator voor willekeurige getallen
Laten we eens een overzicht geven van de logica van een generator voor willekeurige getallen:
- Definieer
max
het maximumaantal dat u wilt genereren. - Definieer het aantal willekeurige bits dat u moet genereren. Dit wordt gedaan door te berekenen hoeveel bits,
nBits
u moet gehele getallen uitdrukken totmax
. - Genereer een tekenreeks voor willekeurige bits die
nBits
in lengte is. - Als de bit-tekenreeks een getal vormt dat groter is dan
max
, gaat u terug naar stap 3. - Is dat niet het geval, dan is het proces voltooid. Retourneer het gegenereerde getal als een geheel getal.
Laten we bijvoorbeeld max
instellen op 12. Dat wil gezegd: 12 is het grootste getal dat u als wachtwoord wilt gebruiken.
U hebt ${\lfloor ln(12) / ln(2) + 1 \rfloor}$ of 4 bits nodig om een getal tussen 0 en 12 weer te geven. We kunnen de ingebouwde functie BitSizeI
gebruiken, die elk geheel getal accepteert en het aantal bits retourneert dat nodig is om deze weer te geven.
Stel dat u de bit-tekenreeks ${1101_{\ binary}}$ wilt genereren, wat gelijk is aan ${13_{\ decimal}}$. Omdat 13 groter is dan 12, herhaalt u het proces.
Vervolgens genereert u de bit-tekenreeks ${0110_{\ binary}}$, die gelijk is aan ${6_{\ decimal}}$. Omdat 6 kleiner is dan 12, is het proces voltooid.
De kwantumgenerator voor willekeurige getallen retourneert nummer 6 als uw wachtwoord. Stel in de praktijk een groter getal in als het maximum, omdat lagere getallen eenvoudig te kraken zijn door alleen alle mogelijke wachtwoorden te proberen. Om de moeite van het raden of kraken van uw wachtwoord te vergroten, kunt u ASCII-code gebruiken om binair naar tekst te converteren en een wachtwoord te genereren met behulp van cijfers, symbolen en gemengde letters.
Een willekeurige bitgenerator schrijven
De eerste stap is het schrijven van een Q# bewerking waarmee een willekeurige bit wordt gegenereerd. Deze bewerking is een van de bouwstenen van de generator voor willekeurige getallen.
operation GenerateRandomBit() : Result {
// Allocate a qubit.
use q = Qubit();
// Set the qubit into superposition of 0 and 1 using the Hadamard
H(q);
// At this point the qubit `q` has 50% chance of being measured in the
// |0〉 state and 50% chance of being measured in the |1〉 state.
// 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.
// Qubits must be in the |0〉 state by the time they are released.
Reset(q);
// Return the result of the measurement.
return result;
}
Bekijk nu nieuwe code.
- U definieert de
GenerateRandomBit
bewerking, die geen invoer gebruikt en een waarde van het typeResult
produceert. HetResult
type vertegenwoordigt het resultaat van een meting en kan twee mogelijke waarden hebben:Zero
ofOne
. - U wijst één qubit toe met het
use
trefwoord. Wanneer deze wordt toegewezen, heeft een qubit altijd de status |0〉. - U gebruikt de
H
bewerking om de qubit in een gelijke superpositie te plaatsen. - U gebruikt de bewerking om de
M
qubit te meten, de gemeten waarde (Zero
ofOne
) te retourneren. - U gebruikt de
Reset
bewerking om de qubit opnieuw in te stellen op de status |0〉.
Door de qubit in superpositie te plaatsen met de H
bewerking en deze te meten met de M
bewerking, is het resultaat telkens wanneer de code wordt aangeroepen een andere waarde.
Visualiseer de Q# code met de Bloch sphere
In de Blochbol vertegenwoordigt de noordpool de klassieke waarde 0 en de zuidpool de klassieke waarde 1. Elke superpositie kan worden weergegeven met een punt op de bol (aangeduid met een pijl). Hoe dichter het einde van de pijl bij een pool is, hoe groter de kans is dat de qubit bij meting uiteenvalt in de klassieke waarde die aan die pool is toegewezen. De qubitstatus die wordt vertegenwoordigd door de pijl in de volgende afbeelding, heeft bijvoorbeeld een hogere kans om de waarde 0 op te geven als u deze meet.

U kunt deze weergave gebruiken om te visualiseren wat de code doet:
Begin eerst met een qubit die is geïnitialiseerd in de toestand |0〉 en pas een bewerking toe om een
H
gelijke superpositie te maken waarin de waarschijnlijkheden voor 0 en 1 hetzelfde zijn.Meet vervolgens de qubit en sla de uitvoer op:
Omdat het resultaat van de meting willekeurig is en de waarschijnlijkheid van het meten van 0 en 1 hetzelfde is, hebt u een volledig willekeurige bit verkregen. U kunt deze bewerking meerdere keren aanroepen om gehele getallen te maken. Als u de bewerking bijvoorbeeld drie keer aanroept om drie willekeurige bits te verkrijgen, kunt u willekeurige 3-bits getallen maken (dat wil gezegd een willekeurig getal tussen 0 en 7).
Een volledige generator voor willekeurige getallen schrijven
Eerst moet u de vereiste naamruimten uit de Q# standaardbibliotheek importeren in het programma. De Q# compiler laadt veel algemene functies en bewerkingen automatisch, maar voor de volledige generator voor willekeurige getallen hebt u enkele extra functies en bewerkingen uit twee Q# naamruimten nodig:
Microsoft.Quantum.Math
enMicrosoft.Quantum.Convert
.import Microsoft.Quantum.Convert.*; import Microsoft.Quantum.Math.*;
Vervolgens definieert u de
GenerateRandomNumberInRange
bewerking. Met deze bewerking wordt herhaaldelijk de bewerkingGenerateRandomBit
aangeroepen om een bit-tekenreeks te maken./// 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 { 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; }
Laten we nog even de nieuwe code controleren.
- U moet het aantal bits berekenen dat nodig is om gehele getallen tot en met
max
. DeBitSizeI
functie van deMicrosoft.Quantum.Math
naamruimte converteert een geheel getal naar het aantal bits dat nodig is om deze weer te geven. - De bewerking
SampleRandomNumberInRange
maakt gebruik van eenfor
-lus om willekeurige getallen te genereren totdat er één wordt gegenereerd die gelijk is aan of kleiner is danmax
. Defor
lus werkt precies hetzelfde als eenfor
lus in andere programmeertalen. - De variabele is een veranderlijke variabele
bits
. Een veranderlijke variabele kan tijdens de berekening worden gewijzigd. U kunt met deset
-instructie de waarde van een veranderlijke variabele wijzigen. - De
ResultArrayAsInt
functie converteert de bittekenreeks vanuit de standaardnaamruimteMicrosoft.Quantum.Convert
naar een positief geheel getal.
- U moet het aantal bits berekenen dat nodig is om gehele getallen tot en met
Ten slotte voegt u een toegangspunt toe aan het programma. De compiler zoekt standaard Q# naar een
Main
bewerking en begint daar met verwerken. Hiermee wordt deGenerateRandomNumberInRange
bewerking aanroepen om een willekeurig getal te genereren tussen 0 en 100.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); }
De
let
-instructie declareert variabelen die niet worden gewijzigd tijdens de berekening. Hier definieert u de maximumwaarde als 100.De volledige code voor de generator voor willekeurige getallen is als volgt:
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 {
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 a Hadamard operation
H(q);
// At this point the qubit `q` has 50% chance of being measured in the
// |0〉 state and 50% chance of being measured in the |1〉 state.
// 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.
// Qubits must be in the |0〉 state by the time they are released.
Reset(q);
// Return the result of the measurement.
return result;
}
Het generatorprogramma voor willekeurige getallen uitvoeren
U kunt het programma uitvoeren in Copilot in Azure Quantum en in Visual Studio Code als zelfstandige Q# toepassing of met behulp van een Python-hostprogramma.
U kunt uw Q# code gratis testen met Copilot in Azure Quantum. U hebt alleen een Microsoft-e-mailaccount (MSA) nodig. Zie Azure Quantum verkennen voor meer informatie over Copilot in Azure Quantum.
Open Copilot in Azure Quantum in uw browser.
Kopieer en plak de volgende code in de code-editor.
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); } /// # Summary /// 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 { 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; } /// # Summary /// Generates a random bit. operation GenerateRandomBit() : Result { // Allocate a qubit. use q = Qubit(); // Set the qubit into superposition of 0 and 1 using the Hadamard // operation `H`. H(q); // At this point the qubit `q` has 50% chance of being measured in the // |0〉 state and 50% chance of being measured in the |1〉 state. // 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. // Qubits must be in the |0〉 state by the time they are released. Reset(q); // Return the result of the measurement. return result; // Note that Qubit `q` is automatically released at the end of the block. }
Selecteer het aantal schermafbeeldingen dat moet worden uitgevoerd en selecteer Uitvoeren.
De resultaten worden weergegeven in het histogram en in de resultatenvelden .
Selecteer Code uitleggen om Copilot te vragen om de code aan u uit te leggen.
Tip
Vanuit Copilot in Azure Quantum kunt u uw programma openen in VS Code for the Web door in de rechterhoek van de code-editor de knop VS Code-logo te selecteren.
Notitie
Dit codefragment wordt momenteel niet uitgevoerd op beschikbare Azure Quantum-hardware targets, omdat het aanroepbare ResultArrayAsInt
een QPU met een volledig rekenprofiel vereist.
Gerelateerde inhoud
Bekijk andere Q# zelfstudies:
- Kwantumverstrengeling laat zien hoe u een Q# programma schrijft dat qubits bewerkt en meet en de effecten van superpositie en verstrengeling demonstreert.
- Het zoekalgoritmen van Grover laten zien hoe u een Q# programma schrijft dat gebruikmaakt van het zoekalgoritmen van Grover.
- Met Quantum Fourier-transformaties wordt uitgelegd hoe u een Q# programma schrijft waarmee specifieke qubits rechtstreeks worden aangepakt.
- De Quantum Katas zijn zelfstudies in eigen tempo en programmeeroefeningen die zijn gericht op het leren van de elementen van kwantumcomputing en Q# programmeren op hetzelfde moment.