Tutorial: Implementar um Gerador de Números Aleatórios Quântico em Q#Tutorial: Implement a Quantum Random Number Generator in Q#

Um exemplo simples de um algoritmo quântico escrito Q# é um gerador de números aleatórios quânticos.A simple example of a quantum algorithm written in Q# is a quantum random number generator. Este algoritmo tira partido da natureza da mecânica quântica para produzir um número aleatório.This algorithm leverages the nature of quantum mechanics to produce a random number.

Pré-requisitosPrerequisites

Escrever uma Q# operaçãoWrite a Q# operation

Q# código de operaçãoQ# operation code

  1. Substitua o conteúdo do ficheiro Program.qs pelo seguinte código:Replace the contents of the Program.qs file with the following code:
namespace Qrng {
    open Microsoft.Quantum.Convert;
    open Microsoft.Quantum.Math;
    open Microsoft.Quantum.Measurement;
    open Microsoft.Quantum.Canon;
    open Microsoft.Quantum.Intrinsic;
    
    operation SampleQuantumRandomNumberGenerator() : Result {
        using (q = Qubit())  {  // Allocate a qubit.
            H(q);               // Put the qubit to superposition. It now has a 50% chance of being 0 or 1.
            return MResetZ(q);  // Measure the qubit value.
        }
    }
}

Conforme mencionado no nosso artigo Compreender a computação quântica, um qubit é uma unidade de informações quânticas que pode estar em sobreposição.As mentioned in our Understanding quantum computing article, a qubit is a unit of quantum information that can be in superposition. Quando medido, um qubit só pode ser 0 ou 1.When measured, a qubit can only be either 0 or 1. No entanto, antes da medição, o estado do qubit representa a probabilidade de ler um 0 ou um 1 com uma medição.However, before measurement, the state of the qubit represents the probability of reading either a 0 or a 1 with a measurement. Este estado de probabilidade é conhecido como sobreposição.This probabilistic state is known as superposition. Podemos utilizar esta probabilidade para gerar números aleatórios.We can use this probability to generate random numbers.

Na nossa Q# operação, introduzimos o Qubit tipo de dados, nativo Q# de.In our Q# operation, we introduce the Qubit datatype, native to Q#. Apenas podemos alocar um Qubit com uma instrução using.We can only allocate a Qubit with a using statement. Depois de alocados, os qubits estão sempre no estado Zero.When it gets allocated, a qubit is always in the Zero state.

Com a operação H, podemos colocar o Qubit em sobreposição.Using the H operation, we are able to put our Qubit in superposition. Para medir um qubit e ler o seu valor, pode utilizar a operação intrínseca M.To measure a qubit and read its value, you use the M intrinsic operation.

Ao colocar o Qubit em sobreposição e ao medi-lo, o resultado será um valor diferente sempre que o código for invocado.By putting our Qubit in superposition and measuring it, our result will be a different value each time the code is invoked.

Quando um Qubit é desalocado, tem de ser definido explicitamente de volta para o estado Zero. Caso contrário, o simulador reportará um erro de runtime.When a Qubit is deallocated it must be explicitly set back to the Zero state, otherwise the simulator will report a runtime error. Uma forma fácil de conseguir isto é ao invocar Reset.An easy way to achieve this is invoking Reset.

Visualizar o código com a Esfera de BlochVisualizing the code with the Bloch sphere

Na Esfera de Bloch, o polo norte representa o valor clássico 0 e o polo sul representa o valor clássico 1.In the Bloch sphere, the north pole represents the classical value 0 and the south pole represents the classical value 1. Qualquer sobreposição pode ser representada por um ponto na esfera (representada por uma seta).Any superposition can be represented by a point on the sphere (represented by an arrow). Quanto mais próximo estiver o fim da seta de um polo, maior a probabilidade de o qubit ser incluído no valor clássico atribuído a esse polo quando medido.The closer the end of the arrow to a pole the higher the probability the qubit collapses into the classical value assigned to that pole when measured. Por exemplo, o estado do qubit representado pela seta vermelha abaixo tem uma probabilidade mais alta de originar o valor 0 se for medido.For example, the qubit state represented by the red arrow below has a higher probability of giving the value 0 if we measure it.

A qubit state with a high probability of measuring zero

Podemos utilizar esta representação para visualizar o que o código está a fazer:We can use this representation to visualize what the code is doing:

  • Primeiro, começamos com um qubit inicializado no estado 0 e aplicamos H para criar uma sobreposição em que as probabilidades de 0 e 1 são iguais.First we start with a qubit initialized in the state 0 and apply H to create a superposition in which the probabilities for 0 and 1 are the same.
Preparing a qubit in superposition
  • Em seguida, medimos o qubit e guardamos a saída:Then we measure the qubit and save the output:
Measuring a qubit and saving the output

Como o resultado da medição é completamente aleatório, obtivemos um bit aleatório.Since the outcome of the measurement is completely random, we have obtained a random bit. Podemos chamar esta operação várias vezes para criar números inteiros.We can call this operation several times to create integers. Por exemplo, se chamarmos a operação três vezes para obter três bits aleatórios, poderemos criar números aleatórios de 3 bits (ou seja, um número aleatório entre 0 e 7).For example, if we call the operation three times to obtain three random bits, we can build random 3-bit numbers (that is, a random number between 0 and 7).

Criar um gerador de números aleatórios completoCreating a complete random number generator

Agora que temos uma Q# operação que gera bits aleatórios, podemos usá-lo para construir um gerador de números quânticos aleatórios.Now that we have a Q# operation that generates random bits, we can use it to build a complete quantum random number generator. Podemos usar uma Q# aplicação ou usar um programa de anfitrião.We can use a Q# application or use a host program.

Para criar a Q# aplicação completa, adicione o seguinte ponto de entrada ao seu Q# programa:To create the full Q# application, add the following entry point to your Q# program:

operation SampleRandomNumberInRange(max : Int) : Int {
    mutable bits = new Result[0];
    for (idxBit in 1..BitSizeI(max)) {
        set bits += [SampleQuantumRandomNumberGenerator()];
    }
    let sample = ResultArrayAsInt(bits);
    return sample > max
           ? SampleRandomNumberInRange(max)
           | sample;
}

@EntryPoint()
operation SampleRandomNumber() : Int {
    let max = 50;
    Message($"Sampling a random number between 0 and {max}: ");
    return SampleRandomNumberInRange(max);
}

O programa executará a operação ou função marcada com o @EntryPoint() atributo num simulador ou estimador de recursos, dependendo da configuração do projeto e das opções de linha de comando.The program will run the operation or function marked with the @EntryPoint() attribute on a simulator or resource estimator, depending on the project configuration and command-line options.

namespace Qrng {
    open Microsoft.Quantum.Convert;
    open Microsoft.Quantum.Math;
    open Microsoft.Quantum.Measurement;
    open Microsoft.Quantum.Canon;
    open Microsoft.Quantum.Intrinsic;
    
    operation SampleQuantumRandomNumberGenerator() : Result {
        using (q = Qubit())  {  // Allocate a qubit.
            H(q);               // Put the qubit to superposition. It now has a 50% chance of being 0 or 1.
            return MResetZ(q);  // Measure the qubit value.
        }
    }

    operation SampleRandomNumberInRange(max : Int) : Int {
        mutable bits = new Result[0];
        for (idxBit in 1..BitSizeI(max)) {
            set bits += [SampleQuantumRandomNumberGenerator()];
        }
        let sample = ResultArrayAsInt(bits);
        return sample > max
               ? SampleRandomNumberInRange(max)
               | sample;
    }
    
    @EntryPoint()
    operation SampleRandomNumber() : Int {
        let max = 50;
        Message($"Sampling a random number between 0 and {max}: ");
        return SampleRandomNumberInRange(max);
    }
}

No Visual Studio, basta premir Ctrl + F5 para executar o script.In Visual Studio, simply press Ctrl + F5 to run the script.

No VS Code, crie o ficheiro Program.qs pela primeira vez ao escrever o seguinte no terminal:In VS Code, build the Program.qs the first time by typing the below in the terminal:

dotnet build

Para as execuções subsequentes, não há necessidade de o criar novamente.For subsequent runs, there is no need to build it again. Para o executar, escreva o seguinte comando e prima Enter:To run it, type the following command and press enter:

dotnet run --no-build