Cvičení – část 2 – vytvoření kvantového generátoru náhodných čísel

Dokončeno

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:

  1. Definujte max jako maximální desetinné číslo, které chcete vygenerovat.
  2. Určete počet náhodných bitů, nBitskteré jsou nutné k vygenerování max.
  3. Vygenerujte náhodný bitový řetězec, který má délku nBits.
  4. Pokud bitový řetězec představuje číslo větší než max, vraťte se k předchozímu kroku.
  5. 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 BitSizeI z knihovny Std.Math pro výpočet počtu bitů potřebných k reprezentaci celého čísla uloženého v max.
  • for Pomocí smyčky vygenerujte počet náhodných bitů, které se rovnají nBits. Voláním operace GenerateRandomBit vygenerujte náhodné bity.
  • Uvnitř for smyčky použijte set příkaz k aktualizaci bits proměnné pomocí každého nového náhodného bitu. Proměnná bits je proměnlivá proměnná, což znamená, že se hodnota bits může během výpočtu změnit.
  • Zavolejte funkci ResultArrayAsInt z knihovny Std.Convert pro převod pole bitů v bits na kladné celé číslo uložené v sample.
  • return V příkazu zkontrolujte, zda sample je větší než max. Pokud je sample větší než max, zavolejte znovu GenerateRandomNumberInRange a začněte od začátku. V opačném případě vrátí náhodné číslo uložené v sample.

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.