Sdílet prostřednictvím


Kurz: Implementace kvantového generátoru náhodných čísel v Q#

V tomto kurzu se naučíte napsat základní kvantový program, který Q# využívá povahu kvantové mechaniky k vytvoření náhodného čísla.

V tomto kurzu:

  • Vytvořte Q# program.
  • Projděte si hlavní součásti Q# programu.
  • Definujte logiku problému.
  • Zkombinujte klasické a kvantové operace a vyřešte problém.
  • Budete pracovat s qubity a superpozicí a vytvoříte kvantový generátor náhodných čísel.

Tip

Pokud chcete urychlit cestu k kvantovému computingu, podívejte se na kód s Využitím Azure Quantum, která je jedinečnou funkcí webu Azure Quantum. Tady můžete spouštět předdefinované Q# ukázky nebo vlastní Q# programy, vygenerovat nový Q# kód z výzev, otevřít a spustit kód ve VS Code pro web jedním kliknutím a pokládat Copilot jakékoli otázky týkající se kvantového computingu.

Požadavky

  • Spuštění ukázky kódu v Copilotu v Azure Quantum:

    • E-mailový účet Microsoft (MSA).
  • Vývoj a spuštění ukázky kódu v editoru Visual Studio Code:

    • Nejnovější verze editoru Visual Studio Code nebo otevření editoru VS Code na webu

    • Nejnovější verze rozšíření AzureQuantum Development Kit. Podrobnosti o instalaci najdete v tématu Instalace sady QDK ve VS Code.

    • Pokud chcete používat poznámkové bloky Jupyter, musíte také nainstalovat rozšíření Pythonu a Jupyter a nejnovější qsharp balíček Pythonu. Uděláte to tak, že otevřete terminál a spustíte následující příkaz:

      $ pip install --upgrade  qsharp
      

Definování problému

Klasické počítače nevytvářejí náhodná čísla, ale spíše pseudonáhodná čísla. Generátor pseudonáhodných čísel generuje deterministický sekvenci čísel na základě určité počáteční hodnoty, která se nazývá počáteční hodnota. Aby se počáteční hodnota přiblížila náhodné hodnotě, používá často aktuální čas z procesoru.

Kvantové počítače můžou na druhé straně generovat skutečně náhodná čísla. Důvodem je, že měření qubitu v superpozici je pravděpodobnostní proces. Výsledek měření je náhodný a neexistuje způsob, jak předpovědět výsledek. Toto je základní princip generátorů kvantových náhodných čísel.

Qubit je jednotka kvantových informací, která může být v superpozici. Při měření může být qubit buď ve stavu 0 , nebo ve stavu 1 . Před měřením ale stav qubitu představuje pravděpodobnost čtení 0 nebo 1 s měřením.

Začnete tím, že vezmete qubit v základním stavu, například nulu. Prvním krokem generátoru náhodných čísel je použití operace Hadamard k vložení qubitu do stejné superpozice. Výsledkem měření tohoto stavu je nula nebo jedna s 50% pravděpodobností každého výsledku, což je skutečně náhodný bit.

Neexistuje způsob, jak zjistit, co získáte po měření qubitu v superpozici, a výsledek je jiná hodnota při každém vyvolání kódu. Jak ale můžete toto chování použít k vygenerování větších náhodných čísel?

Řekněme, že tento proces čtyřikrát zopakujeme, takže se vygeneruje tato posloupnost binárních číslic:

$${0, 1, 1, 0}$$

Pokud tyto bity zřetězíte nebo spojíte do bitového řetězce, můžete vytvořit větší číslo. V tomto příkladu odpovídá bitová sekvence ${0110}$ hodnotě šest v desítkové soustavě.

$${0110_{\ binary} \equiv 6_{\ decimal}}$$

Pokud tento proces opakujete mnohokrát, můžete zkombinovat více bitů a vytvořit libovolné velké číslo. Pomocí této metody můžete vytvořit číslo, které se použije jako zabezpečené heslo, protože můžete mít jistotu, že žádný hacker nemůže určit výsledky posloupnosti měření.

Definování logiky generátoru náhodných čísel

Pojďme si zpřesnit logiku generátoru náhodných čísel:

  1. Definujte max jako maximální počet, který chcete vygenerovat.
  2. Definujte počet náhodných bitů, které potřebujete vygenerovat. To se provádí výpočetm, kolik bitů, nBitsmusíte vyjádřit celá čísla až 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 ke kroku 3.
  5. Tím je proces hotový. Vraťte vygenerované číslo jako celé číslo.

Příklad: Nastavíme hodnotu max na 12. To znamená, že 12 je největší číslo, které chcete použít jako heslo.

Potřebujete ${\lfloor ln(12) / ln(2) + 1 \rfloor}$ nebo 4 bity, aby představovaly číslo mezi 0 a 12. Můžeme použít předdefinované funkce BitSizeI, která přebírá jakékoli celé číslo a vrací počet bitů potřebných k jeho reprezentaci.

Řekněme, že vygenerujete bitový řetězec ${1101_{\ binary}}$, který odpovídá ${13_{\ decimal}}$. Protože 13 je větší než 12, proces se zopakuje.

Dále vygenerujete bitový řetězec ${0110_{\ binary}}$, který odpovídá ${6_{\ decimal}}$. Protože 6 je menší než 12, proces se dokončí.

Generátor kvantových náhodných čísel vrátí jako heslo číslo 6. V praxi nastavte větší číslo jako maximum, protože nižší čísla jsou snadné prolomit pouhým pokusem o všechna možná hesla. Ve skutečnosti můžete ke zvýšení složitosti hádání nebo prolomení hesla použít kód ASCII k převodu binárního souboru na text a k vygenerování hesla pomocí čísel, symbolů a smíšených písmen.

Zápis generátoru náhodných bitů

Prvním krokem je napsat Q# operaci, která generuje náhodný bit. Tato operace bude jedním z stavebních bloků generátoru náhodných čísel.

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;
}

Teď se podívejte na nový kód.

  • Definujete GenerateRandomBit operaci, která nepřijímá žádný vstup a vytváří hodnotu typu Result. Typ Result představuje výsledek měření a může mít dvě možné hodnoty: Zero nebo One.
  • Přidělíte jeden qubit s klíčovým slovem use . Když se přidělí, qubit je vždy ve stavu |0〉.
  • Pomocí H operace umístíte qubit do stejné superpozice.
  • Tuto operaci použijete M k měření qubitu, vrátí naměřenou hodnotu (Zero nebo One).
  • Pomocí Reset operace resetujete qubit do stavu |0〉.

Když umístíte qubit do superpozice s H operací a změříte ho M s operací, výsledek je při každém vyvolání kódu jiná hodnota.

Q# Vizualizace kódu pomocí Bloch sphere

Severní pól na Blochově kouli představuje klasickou hodnotu 0 a jižní pól představuje klasickou hodnotu 1. Každá superpozice může být reprezentována bodem na kouli (reprezentovaný šipkou). Čím blíž je konec šipky k pólu, tím vyšší je pravděpodobnost, že se qubit při změření převede na klasickou hodnotu přiřazenou k příslušnému pólu. Například stav qubitu reprezentovaný šipkou na následujícím obrázku má vyšší pravděpodobnost, že hodnotu 0 dáte, pokud ji změříte.

Diagram znázorňující stav qubitu s vysokou pravděpodobností měření nuly

Pomocí této reprezentace můžete vizualizovat, co kód dělá:

  1. Nejprve začněte s qubitem inicializovaným ve stavu |0〉 a pomocí H operace vytvořte stejnou superpozici, ve které jsou pravděpodobnosti 0 a 1 stejné.

    Diagram znázorňující přípravu qubitu v superpozici použitím hadamardové brány
  2. Pak změřte qubit a uložte výstup:

    Diagram znázorňující měření qubitu a uložení výstupu

Vzhledem k tomu, že výsledek měření je náhodný a pravděpodobnosti měření 0 a 1 jsou stejné, získali jste zcela náhodný bit. Tuto operaci můžete volat několikrát, abyste vytvořili celá čísla. Pokud například operaci zavoláte třikrát, abyste získali tři náhodné bity, můžete vytvořit náhodná 3bitová čísla (to znamená náhodné číslo v rozmezí od 0 do 7).

Napsání kompletního generátoru náhodných čísel

  1. Nejprve je potřeba importovat požadované obory názvů ze Q# standardní knihovny do programu. Q# Kompilátor načte mnoho běžných funkcí a operací automaticky, ale pro kompletní generátor náhodných čísel potřebujete některé další funkce a operace ze dvou Q# oborů názvů: Microsoft.Quantum.Matha Microsoft.Quantum.Convert.

    import Microsoft.Quantum.Convert.*;
    import Microsoft.Quantum.Math.*;
    
  2. Dále definujete GenerateRandomNumberInRange operaci. Tato operace opakovaně volá operaci GenerateRandomBit pro sestavení řetězce bitů.

    /// 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;
    }
    
    

    Krátce si zrevidujme nový kód.

    • Potřebujete vypočítat počet bitů potřebných k vyjádření celých čísel až do max. Funkce BitSizeI z Microsoft.Quantum.Math oboru názvů převede celé číslo na počet bitů potřebných k jeho reprezentaci.
    • Operace SampleRandomNumberInRange používá smyčku for ke generování náhodných čísel, dokud nevygeneruje hodnotu, která je menší než nebo rovna max. Smyčka for funguje přesně stejně jako smyčka for v jiných programovacích jazycích.
    • Proměnná bits je proměnlivá proměnná. Měnitelná proměnná je taková, která se může během výpočtu změnit. Pomocí direktivy set můžete změnit hodnotu měnitelné proměnné.
    • Funkce ResultArrayAsInt z výchozího Microsoft.Quantum.Convert oboru názvů převede bitový řetězec na kladné celé číslo.
  3. Nakonec do programu přidáte vstupní bod. Ve výchozím nastavení Q# kompilátor vyhledá Main operaci a začne tam zpracovávat. GenerateRandomNumberInRange Volá operaci, aby vygenerovala náhodné číslo mezi 0 a 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);
    }
    

    Direktiva let deklaruje proměnné, které se během výpočtu nemění. Tady definujete maximální hodnotu jako 100.

    Další informace o Main operaci naleznete v tématu Vstupní body.

  4. Úplný kód generátoru náhodných čísel je následující:

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;
}

Spuštění programu generátoru náhodných čísel

Program můžete spustit v Copilotu v Azure Quantum a v editoru Visual Studio Code jako samostatnou Q# aplikaci nebo pomocí hostitelského programu Pythonu.

Svůj Q# kód můžete otestovat pomocí Copilotu v Azure Quantum zdarma – vše, co potřebujete, je e-mailový účet Microsoft (MSA). Další informace o copilotu v Azure Quantum najdete v tématu Prozkoumání Azure Quantum.

  1. V prohlížeči otevřete Copilot v Azure Quantum.

  2. Zkopírujte a vložte následující kód do editoru kódu.

    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.
    }
    
    
  3. Vyberte počet snímků, které chcete spustit, a vyberte Spustit.

  4. Výsledky se zobrazí v histogramu a v polích Výsledky .

  5. Výběrem možnosti Vysvětlit kód zobrazíte výzvu Ke zkopírování, aby vám kód vysvětlil.

Tip

Z Copilotu ve službě Azure Quantum můžete program otevřít ve VS Code pro web výběrem tlačítka s logem VS Code v pravém rohu editoru kódu.

Poznámka:

Tento fragment kódu se momentálně nespouští na žádném dostupném hardwaru targetsAzure Quantum, protože volatelný ResultArrayAsInt vyžaduje QPU s úplným výpočetním profilem.

Prozkoumejte další Q# kurzy:

  • Kvantové propletení ukazuje, jak napsat Q# program, který manipuluje s qubity a měří je a ukazuje účinky superpozice a propletení.
  • Groverův vyhledávací algoritmus ukazuje, jak napsat Q# program, který používá Groverův vyhledávací algoritmus.
  • Quantum Fourier Transforms zkoumá, jak napsat Q# program, který přímo řeší konkrétní qubity.
  • Kvantové katy jsou kurzy a programovací cvičení zaměřená na výuku prvků kvantového computingu a Q# programování současně.