Megosztás a következőn keresztül:


Oktatóanyag: Kvantum véletlenszerű számgenerátor implementálása Q#

Ebben az oktatóanyagban megtanulod egy alapszintű kvantumprogram írását Q#, amely a kvantummechanika természetét felhasználva véletlenszerű számot hoz létre.

Az oktatóanyag során az alábbi lépéseket fogja végrehajtani:

  • Hozzon létre egy Q# programot.
  • Tekintse át a program fő összetevőit Q# .
  • Definiálja a probléma logikáját.
  • A klasszikus és kvantumműveletek kombinálásával megoldhatja a problémát.
  • Qubitek és a szuperpozíció használata kvantumos véletlenszám-generátor létrehozásához.

Tipp

Ha fel szeretné gyorsítani a kvantum-számítástechnika folyamatát, tekintse meg az Azure Quantum-webhely egyedi funkcióját, az Azure Quantum-ot. Itt futtathat beépített mintákat vagy saját Q# programokat, új Q# kódot hozhat létre az üzeneteiből, megnyithatja és futtathatja a kódot a WEBES VS Code-ban Q#egy kattintással, és kérdéseket tehet fel a Copilotnak a kvantum-számítástechnikával kapcsolatban.

Előfeltételek

A probléma meghatározása

A klasszikus számítógépek nem véletlenszerű számokat, hanem pszeudo-számokat hoznak létre. A pszeudorandom számgenerátor egy determinisztikus számsorozatot hoz létre valamilyen kezdeti érték, úgynevezett mag alapján. Hogy minél jobban megközelítsük a véletlenszerű értékeket, a kiinduló érték a leggyakrabban a CPU órájának aktuális ideje lesz.

A kvantumszámítógépek viszont valóban véletlenszerű számokat hozhatnak létre. Ennek az az oka, hogy a szuperpozícióban lévő qubit mérése valószínűségi folyamat. A mérés eredménye véletlenszerű, és nincs mód az eredmény előrejelzésére. Ez a kvantum véletlenszerű számgenerátorok alapelve.

A qubit a kvantuminformációk egysége, amely szuperpozícióban lehet. Méréskor a qubitek csak 0 vagy 1 állapotban lehetnek. A mérés előtt azonban a qubit állapota egy 0 vagy egy 1 méréssel való beolvasásának valószínűségét jelenti.

Először egy alapállapotú qubitet kell vennie, például nullát. A véletlenszerű számgenerátor első lépése egy Hadamard-művelettel egyenlő szuperpozícióba helyezni a qubitet. Ennek az állapotnak a mérése nulla vagy egy értéket eredményez, mindkettő 50%-os valószínűséggel, ezáltal egy igazán véletlenszerű bitet hozva létre.

Nem lehet tudni, hogy mit kap a qubit szuperpozícióban való mérése után, és az eredmény minden alkalommal más érték, amikor meghívja a kódot. De hogyan használhatja ezt a viselkedést nagyobb véletlenszerű számok létrehozására?

Tegyük fel, hogy négyszer ismétli meg a folyamatot, így az alábbi bináris számjegyet kapja:

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

Ha összefűzi vagy kombinálja ezeket a biteket egy bitsztringbe, akkor egy nagyobb számot kap. Ebben a példában a ${0110}$ bitsorozat decimális formában a 6-nak felel meg.

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

Ha ezt a folyamatot többször is megismételi, több bitet is kombinálhat, hogy bármilyen nagy számot alkotjon. Ezzel a módszerrel létrehozhat egy számot, amelyet biztonságos jelszóként használhat, mivel biztos lehet abban, hogy egyetlen hacker sem tudja meghatározni a mérések sorozatának eredményeit.

A véletlenszám-generáló logikájának meghatározása

Vázoljuk fel a véletlenszerű számgenerátor logikáját:

  1. Adja meg max a létrehozni kívánt maximális számot.
  2. Adja meg a létrehozandó véletlenszerű bitek számát. Ez úgy történik, hogy kiszámítja, hány bitre van szüksége ahhoz, hogy az egészeket kifejezze max-ig.
  3. Generáljunk egy nBits hosszúságú véletlenszerű bitsztringet.
  4. Ha a bitsztring a max értékénél nagyobb szám, lépjünk vissza a harmadik lépéshez.
  5. Ellenkező esetben a folyamat befejeződött. A létrehozott számot adjuk vissza egész számként.

Példaként állítsuk be a max értékét 12-re. Vagyis a 12 a legnagyobb szám, amelyet jelszóként szeretne használni.

${\lfloor ln(12) / ln(2) + 1 \rfloor}$, vagy 4 bitre van szüksége a 0 és 12 közötti szám megjelenítéséhez. Használhatjuk a beépített függvényt BitSizeI, amely bármilyen egész számot vesz igénybe, és visszaadja az annak megjelenítéséhez szükséges bitek számát.

Például hozzuk létre a ${1101_{\ binary}}$ bitsorozatot, ami megegyezik a ${13_{\ decimal}}$-lal. Mivel a 13 nagyobb mint 12, megismételjük a folyamatot.

Következő lépésként létrehozza az ${0110_{\ binary}}$ bites sztringet, amely egyenértékű a ${6_{\ decimal}}$-mal. Mivel a 6 kisebb mint 12, a folyamat befejeződött.

A kvantum véletlenszerű számgenerátor a 6-os számot adja vissza jelszóként. A gyakorlatban egy nagyobb számot állítson be maximális értékként, mert az alacsonyabb számok könnyen feltörhetőek az összes lehetséges jelszó kipróbálásával. Valójában a jelszó kitalálásának vagy feltörésének nehézségének növelése érdekében ASCII-kóddal konvertálhat binárisokat szöveggé, és számokat, szimbólumokat és vegyeses betűket használva hozhat létre jelszót.

Véletlenszerű bitgenerátort írjon meg

Az első lépés egy Q# véletlenszerű bitet generáló művelet írása. Ez a művelet a véletlenszerű számgenerátor egyik építőeleme lesz.

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

Most tekintse meg az új kódot.

  • Ön határozza meg a GenerateRandomBit műveletet, amely nem vesz fel bemenetet, és típusértéket Resulthoz létre. A Result típus egy mérés eredményét jelöli, és két lehetséges értékkel rendelkezhet: Zero vagy One.
  • Egyetlen qubitet foglal le a use kulcsszóval. A leosztáskor a qubitek mindig |0〉 állapotban lesznek.
  • A művelettel H a qubitet egyenlő szuperpozícióba helyezheti.
  • A művelettel M megmérheti a qubitet, visszaadhatja a mért értéket (Zero vagy One).
  • A művelettel Reset visszaállíthatja a qubitet a(z) |0〉 állapotba.

Ha a qubitet szuperpozícióba helyezi a H művelettel, és a művelettel M együtt méri, az eredmény minden alkalommal más érték, amikor a kód meghívása történik.

A kód vizualizációja Q# a Bloch-gömbdel

A Bloch-gömbön az északi pólus a 0 klasszikus értéket jelöli, a déli pólus pedig az 1 klasszikus értéket. Minden szuperpozíció megadható a gömb egyik pontjaként (ezt a nyíl jelzi). Minél közelebb van a nyíl hegye a pólushoz, annál nagyobb a valószínűsége, hogy a qubit a mérésekor a pólushoz hozzárendelt klasszikus értékkel esik egybe. Az alábbi ábrán látható nyíl által ábrázolt qubitállapot például nagyobb valószínűséggel ad 0 értéket, ha megméri.

Egy olyan qubit állapotot ábrázoló diagram, amely nagy valószínűséggel méri a nullát.

Ezzel az ábrázolással megjelenítheti a kód műveletét:

  1. Először kezdje a(z) |0〉 állapotban inicializált qubittel, és alkalmazzon egy műveletet egy H egyenlő szuperpozíció létrehozásához, amelyben a 0 és az 1 valószínűsége megegyezik.

    Egy diagram, amely egy qubit szuperpozícióban való előkészítését mutatja be a hadamard kapu alkalmazásával.
  2. Ezután mérjük meg a qubitet, és mentsük a kimenetet:

    Egy qubit mérését és a kimenet mentését bemutató diagram.

Mivel a mérés eredménye véletlenszerű, és a 0 és az 1 mérés valószínűsége megegyezik, teljesen véletlenszerű bitet kapott. Ezt a műveletet többször is meghívhatja egész számok létrehozásához. Ha például háromszor hívja meg a műveletet három véletlenszerű bit lekéréséhez, véletlenszerű 3 bites számokat hozhat létre (azaz 0 és 7 közötti véletlenszerű számot).

Teljes véletlenszerű számgenerátor írása

  1. Először importálnia kell a szükséges névtereket a Q# standard kódtárból a programba. A Q# fordító sok gyakori függvényt és műveletet automatikusan betölt, azonban a teljes véletlenszerű számgenerátorhoz két Q# névtérből további függvényekre és műveletekre van szükség: Microsoft.Quantum.Mathés Microsoft.Quantum.Convert.

    import Microsoft.Quantum.Convert.*;
    import Microsoft.Quantum.Math.*;
    
  2. Ezután határozza meg a GenerateRandomNumberInRange műveletet. Ez a művelet többször meghívja a GenerateRandomBit műveletet a bitek sztringjének létrehozásához.

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

    Most vizsgáljuk meg az új kódot.

    • Ki kell számítania, hogy hány bit szükséges az egész számok kifejezéséhez legfeljebb max. A BitSizeI névtérből származó Microsoft.Quantum.Math függvény egy egész számot a reprezentáláshoz szükséges bitek számává alakít át.
    • A SampleRandomNumberInRange művelet egy for hurkot használ arra, hogy véletlenszerű számokat generáljon egészen addig, amíg az kisebb vagy egyenlő nem lesz a max értékével. A for hurok pontosan ugyanúgy működik, mint a for ciklusok más programozási nyelvekben.
    • A változó bits egy módosítható változó. A módosítható változó olyan, amely változhat a számítás közben. Ennek a módosítható változónak a módosításához a set direktívát használjuk.
    • A ResultArrayAsInt függvény az alapértelmezett Microsoft.Quantum.Convert névtérből pozitív egész számmá alakítja a bitsztringet.
  3. Végül hozzáad egy belépési pontot a programhoz. Alapértelmezés szerint a Q# fordító a Main műveletet keresi meg, és ott kezdi el a feldolgozást. Meghívja a GenerateRandomNumberInRange műveletet, hogy véletlenszerű számot hozzon létre 0 és 100 között.

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

    A let direktíva olyan változókat deklarál, amelyek nem változnak a számítás során. Itt a maximális értéket 100-ként definiálja.

    A művelettel kapcsolatos további információkért lásd: Main Belépési pontok.

  4. A véletlenszerű számgenerátor teljes kódja a következő:

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

A véletlenszerű számgenerátor program futtatása

A programot futtathatja a Copilotban az Azure Quantumban, a Visual Studio Code-ban pedig önálló Q# alkalmazásként vagy Python-gazdagépprogram használatával.

A Q# kódot ingyenesen tesztelheti a Copilottal az Azure Quantumban – mindössze egy Microsoft (MSA) e-mail-fiókra van szüksége. Az Azure Quantum Copilot-járól további információt az Azure Quantum felfedezése című témakörben talál.

  1. Nyissa meg a Copilotot az Azure Quantumban a böngészőben.

  2. Másolja és illessze be a következő kódot a kódszerkesztőbe.

    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. Válassza ki a futtatandó lövések számát, és válassza a Futtatás lehetőséget.

  4. Az eredmények a hisztogramban és az Eredmények mezőkben jelennek meg.

  5. A Kód magyarázata lehetőséget választva kérje meg a Copilototot, hogy magyarázza el Önnek a kódot.

Tipp.

Az Azure Quantum Copilotjából megnyithatja programját a webes VS Code-ban azáltal, hogy a kódszerkesztő jobb sarkában található VS Code emblémára kattint.

Feljegyzés

Ez a kódrészlet jelenleg nem fut elérhető Azure Quantum-hardverentargets, mivel a hívhatóhoz ResultArrayAsInt teljes számítási profillal rendelkező QPU szükséges.

További Q# oktatóanyagok:

  • A kvantum-összefonódás bemutatja, hogyan írhat olyan Q# programot, amely manipulálja és méri a qubiteket, és bemutatja a szuperpozíció és az összefonódás hatásait.
  • A Grover keresési algoritmusa bemutatja, hogyan írhat olyan Q# programot, amely a Grover keresési algoritmusát használja.
  • A Quantum Fourier Transforms bemutatja, hogyan írhat olyan Q# programot, amely közvetlenül kezeli az adott qubiteket.
  • A Quantum Katas öngyors oktatóanyagok és programozási gyakorlatok, amelyek célja a kvantum-számítástechnika és Q# a programozás elemeinek egyidejű tanítása.