Cvičení – část 2 – vytvoření kvantového generátoru náhodných čísel
V této lekci implementujete druhou část kvantového generátoru náhodných čísel. Zkombinujete několik náhodných bitů, abyste vytvořili větší náhodné číslo. Tato část vychází z generátoru náhodných bitů, který jste už vytvořili v předchozí lekci.
Kombinování více náhodných bitů a vytvoření většího čísla
V předchozí lekci jste vytvořili generátor náhodných bitů, který umístí qubit do stavu superpozice, a pak tento qubit měří tak, aby vygeneroval náhodnou bitovou hodnotu 0 nebo 1, přičemž každý s 50% pravděpodobností. Hodnota tohoto bitu je skutečně náhodná, neexistuje způsob, jak předem zjistit, jaký bude výsledek měření. Jak ale můžete toto chování použít k vygenerování větších náhodných čísel?
Pokud tento proces opakujete čtyřikrát, můžete tuto sekvenci binárních číslic vygenerovat:
$${0, 1, 1, 0}$$
Pokud tyto bity zkombinujete do bitového řetězce, můžete vytvořit větší číslo. V tomto příkladu je bitová sekvence ${0110}$ v binární soustavě ekvivalentní číslu 6 v desítkové soustavě.
$${0110_{\ binary} \equiv 6_{\ decimal}}$$
Pokud chcete vygenerovat libovolné velké náhodné číslo, opakujte tento proces mnohokrát. Potom zkombinujte všechny bity do binárního čísla a převeďte toto binární číslo na desítkové číslo.
Definování logiky generátoru náhodných čísel
Než napíšete kód Q#, nastíníme logiku pro vygenerování náhodného čísla:
- Definujte
maxjako maximální desetinné číslo, které chcete vygenerovat. - Určete počet náhodných bitů,
nBitskteré jsou nutné k vygenerovánímax. - Vygenerujte náhodný bitový řetězec, který má délku
nBits. - Pokud bitový řetězec představuje číslo větší než
max, vraťte se k předchozímu kroku. - Tím je proces hotový. Vrátí vygenerované číslo jako desetinné číslo.
Pojďme například definovat max 12. To znamená, že 12 je největší číslo, které by měl výstup generátor náhodných čísel.
Pomocí následující rovnice určete počet bitů potřebných k reprezentaci čísla 12 v binární soustavě:
$${\lfloor ln(12) / ln(2) + 1 \rfloor}$$
Podle této rovnice potřebujete 4 bity, které představují číslo od 0 do 12.
Předpokládejme například, že vygenerujete náhodný bit čtyřikrát a získáte bitový řetězec ${1101_{\ binary}}$. Tato hodnota v binární soustavě se rovná 13 v desítkové soustavě. Protože 13 je větší než 12, proces se zopakuje.
Dále vygenerujete bitový řetězec ${0110_{\ binary}}$, který se rovná ${6_{\ decimal}}$. Protože 6 je menší než 12, proces se dokončí.
Generátor kvantových náhodných čísel vrátí číslo 6.
Vytvoření kompletního generátoru náhodných čísel v Q#
V této části rozbalíte Main.qs soubor z předchozí lekce a sestavíte generátor náhodných čísel.
Import potřebných knihoven
Nejprve naimportujte obory názvů ze standardní knihovny Q#, která obsahuje funkce a operace, které potřebujete k napsání programu. Kompilátor Q# načítá mnoho běžných funkcí a operací automaticky. Ale pro kvantový generátor náhodných čísel potřebujete některé další funkce a operace ze dvou oborů názvů Q#: Std.Math a Std.Convert.
Zkopírujte a vložte následující import direktivy na začátek vašeho souboru Main.qs.
import Std.Convert.*;
import Std.Math.*;
Přejmenování operace na MainGenerateRandomBit
Program generátoru náhodných čísel používá Main operaci, kterou jste napsali v předchozí lekci, k vygenerování náhodného bitu.
Main Přejmenujte operaci takGenerateRandomBit, aby tato operace byla popisnější a nebyla vstupním bodem programu.
Zkopírujte a vložte následující kód do 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;
}
Definování operace generátoru náhodných čísel
Vytvořte novou operaci s názvem GenerateRandomNumberInRange. Tato operace opakovaně volá operaci GenerateRandomBit pro sestavení řetězce bitů.
Zkopírujte následující kód a umístěte ho přímo před GenerateRandomBit operaci do souboru Main.qs.
/// 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;
}
Tady je přehled kódu v GenerateRandomNumberInRange:
- Zavolejte funkci
BitSizeIz knihovnyStd.Mathpro výpočet počtu bitů potřebných k reprezentaci celého čísla uloženého vmax. -
forPomocí smyčky vygenerujte počet náhodných bitů, které se rovnajínBits. Voláním operaceGenerateRandomBitvygenerujte náhodné bity. - Uvnitř
forsmyčky použijtesetpříkaz k aktualizacibitsproměnné pomocí každého nového náhodného bitu. Proměnnábitsje proměnlivá proměnná, což znamená, že se hodnotabitsmůže během výpočtu změnit. - Zavolejte funkci
ResultArrayAsIntz knihovnyStd.Convertpro převod pole bitů vbitsna kladné celé číslo uložené vsample. -
returnV příkazu zkontrolujte, zdasampleje větší nežmax. Pokud jesamplevětší nežmax, zavolejte znovuGenerateRandomNumberInRangea začněte od začátku. V opačném případě vrátí náhodné číslo uložené vsample.
Přidání vstupního bodu
Nakonec do kódu přidejte operaci vstupního bodu, aby kompilátor mohl program spustit. Kompilátor Q# ve výchozím nastavení hledá Main operaci a používá Main ji jako vstupní bod bez ohledu na to, kde Main se nachází v souboru. V této části operace nastaví hodnotu pro Main a zavolá operaci max k vygenerování náhodného čísla mezi 0 a GenerateRandomNumberInRange.
Pokud chcete například vygenerovat náhodné číslo od 0 do 100, zkopírujte Main.qs do souboru následující kód:
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);
}
Konečný program
Tady je kompletní kód jazyka Q# pro váš program v 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;
}
Spuštění programu
Vyzkoušejte nový generátor kvantových náhodných čísel!
Chcete-li spustit program, vyberte z příkazů nad operací CodeLens Main. Nebo stiskněte Ctrl+F5. Výstup se zobrazí v konzole ladění. Spusťte program několikrát a všimněte si, jak se výsledek změní.
Gratulujeme! V jazyce Q# jste vytvořili skutečně náhodný generátor kvantových čísel.
Bonusové cvičení
Pokuste se program upravit tak, aby také vyžadoval vygenerované náhodné číslo větší než některé minimální kladné číslo , minmísto nuly.