Övning – Skapa en slumpgenerator för kvanttal

Slutförd

I den här lektionen implementerar du den andra fasen i kvant slumptalsgeneratorn: kombinera flera slumpmässiga bitar för att bilda ett större slumpmässigt tal. Den här fasen bygger på den generator för slumpmässiga bitar som du redan har skapat. Du måste skriva lite klassisk kod för den här fasen.

Kan jag skriva klassisk kod i Q#?

Ja, det kan du. Kvantdatorer utför specialiserade uppgifter. Du använder inte en kvantdator för allt eftersom klassiska datorer fungerar bra för många uppgifter.

Precis som en grafikprocessor (GPU) eller annan specialiserad maskinvara vill du använda en kvantdator för de uppgifter som de passar bäst för. I det här fallet vill du skapa rent slumpmässiga bitar.

Därför kan du med Q# skriva klassisk kod som liknar programmeringsspråk som du redan känner till.

Nu ska vi se hur du kan använda Q#-funktioner för att skapa en komplett slumptalsgenerator.

Definiera logiken för slumptalsgeneratorn

Nu ska vi beskriva logiken för en slumptalsgenerator, förutsatt att den slumpmässiga bitgeneratorn som skapades i föregående enhet:

  1. Definiera max som det högsta antal som du vill generera.
  2. Definiera antalet slumpmässiga bitar som du behöver generera genom att beräkna hur många bitar, nBits, du måste uttrycka heltal upp till max.
  3. Generera en slumpmässig bitsträng som har längden nBits.
  4. Om bitsträngen representerar ett tal som är större än max går du tillbaka till steg tre.
  5. I annat fall är processen slutförd. Returnera det genererade talet som ett heltal.

Som exempel anger vi max till 12. Det vill: 12 är det största talet som du vill få från slumptalsgeneratorn.

Du behöver ${\lfloor ln(12) / ln(2) + 1 \rfloor}$, eller 4 bitar för att representera ett tal mellan 0 och 12. (För korthet hoppar vi över hur den här ekvationen ska härledas.)

Anta att du genererar bitsträngen ${1101_{\ binary}}$, som motsvarar ${13_{\ decimal}}$. Eftersom 13 är större än 12 upprepar du processen.

Sedan generar du bitsträngen ${0110_{\ binary}}$, som motsvarar ${6_{\ decimal}}$. Eftersom 6 är mindre än 12 är processen slutförd.

Slumptalsgeneratorn för kvant returnerar talet 6.

Skapa en fullständig slumptalsgenerator

Här expanderar RandomNumberGenerator.qs du filen för att skapa större slumptal.

Lägga till nödvändiga bibliotek

För den fullständiga slumptalsgeneratorn måste du inkludera tre Q#-bibliotek: Microsoft.Quantum.Math, Microsoft.Quantum.Intrinsicoch Microsoft.Quantum.Convert. Lägg till följande open direktiv så här RandomNumberGenerator.qs :

namespace QuantumRandomNumberGenerator {
open Microsoft.Quantum.Convert;
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Math;

// The rest of the code goes here.

}

Definiera åtgärden för kvant slumptal

Här definierar du åtgärden GenerateRandomNumberInRange. Den här åtgärden anropar åtgärden GenerateRandomBit upprepade gånger för att bygga en sträng med bitar.

Ändra RandomNumberGenerator.qs så här:

namespace QuantumRandomNumberGenerator {
    open Microsoft.Quantum.Convert;
    open Microsoft.Quantum.Intrinsic;
    open Microsoft.Quantum.Math;

    /// 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 is within the requested range.
        // Generate it again if it is outside the range.
        return sample > max ? GenerateRandomNumberInRange(max) | sample;
    }
}

Vi tar och går igenom den nya koden.

  • Du måste beräkna antalet bitar som behövs för att uttrycka heltal upp till max. Funktionen BitSizeI från Microsoft.Quantum.Math biblioteket konverterar ett heltal till det antal bitar som behövs för att representera det.
  • Åtgärden GenerateRandomNumberInRange använder en for-loop för att generera slumpmässiga tal tills den genererar ett som är lika med eller mindre än max. Loopen for fungerar exakt på samma sätt som en for loop i andra programmeringsspråk.
  • Variabeln bits är en föränderlig variabel. Föränderliga variabler kan ändras under beräkningen. Du kan använda direktivet set för att ändra värdet för en föränderlig variabel.
  • Funktionen ResultArrayAsInt kommer från Microsoft.Quantum.Convert biblioteket. Den här funktionen konverterar bitsträngen till ett positivt heltal.

Definiera startpunkten

Ditt program kan nu skapa slumpmässiga tal. Här definierar du programmets startpunkt.

Ändra RandomNumberGenerator.qs filen så här:

namespace QuantumRandomNumberGenerator {
    open Microsoft.Quantum.Convert;
    open Microsoft.Quantum.Intrinsic;
    open Microsoft.Quantum.Math;

    @EntryPoint()
    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 {
            set 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 the 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;
    }
}

Direktivet let deklarerar variabler som inte ändras under beräkningen. I utbildningssyfte definierar vi här det maximala värdet som 100.

Kommentar

Det här kodfragmentet körs för närvarande inte på några tillgängliga Azure Quantum-maskinvarumål, eftersom anropsbara ResultArrayAsInt kräver en QPU med fullständig beräkningsprofil.

Köra programmet

Nu ska vi prova vår nya slumptalsgenerator!

  1. Innan du kör programmet måste du ange målprofilen till Obegränsad. Välj Visa>kommandopalett, sök efter QIR, välj Q#: Ange Azure Quantum QIR-målprofilen och välj sedan Q#: obegränsad.
  2. Om du vill testa att köra programmet lokalt i den inbyggda simulatorn klickar du på Kör från listan med kommandon nedan @EntryPoint()eller trycker på Ctrl+F5. Dina utdata visas i felsökningskonsolen.
  3. Kör programmet igen för att se ett annat resultat.

Kommentar

Om målprofilen inte är inställd på Obegränsad får du ett fel när du kör programmet.

Grattis! Nu vet du hur du kombinerar klassisk logik med Q# för att skapa en slumpgenerator för kvanttal.

Bonusövning

Ändra programmet så att det även kräver att det genererade slumptalet är större än ett minimital, min, i stället för noll.