Esercitazione: Implementare un generatore quantistico di numeri casuali in Q#
Informazioni su come scrivere un programma quantistico di base in Q# che sfrutta la natura della meccanica quantistica per produrre un numero casuale.
In questa esercitazione si apprenderà come
- Creare un progetto Q#.
- Preparare l'ambiente di sviluppo per la scrittura di programmi quantistici in Q#.
- Comprendere come sono strutturati i programmi Q#.
- Usare qubit e sovrapposizioni per creare un generatore quantistico di numeri casuali.
Prerequisiti
- Quantum Development KitInstallare (QDK) usando il linguaggio e l'ambiente di sviluppo preferito. Questa esercitazione presenta la soluzione in tre formati diversi:
- Q# Autonomo
- Q# e Python
- Q# e C #
- Se QDK è già installato, assicurarsi di averlo aggiornato (e, se applicabile, di aver aggiornato il pacchetto qsharp Python) alla versione più recente.
Creazione di un progetto Q#
La prima cosa da fare è creare un nuovo progetto Q#. Questa esercitazione usa l'ambiente basato su applicazioni Q# con VS Code, ma è possibile usare l'IDE preferito.
Per creare un nuovo progetto in Visual Studio Code:
- Selezionare Visualizza ->Riquadro comandi, quindi Q#: Crea nuovo progetto.
- Selezionare Standalone console application (Applicazione console autonoma).
- Selezionare un percorso in cui salvare il progetto, assegnare al progetto il nome Qrng e selezionare Crea progetto.
- Al termine dell'operazione, selezionare Open new project... (Apri nuovo progetto...) in basso a destra.
Vengono generati due file: il file di progetto, Qrng.csproj, e un modello di applicazione Q#, Program.qs, che verrà usato per scrivere l'applicazione.
Scrivere un'operazione Q#
A questo punto, è necessario sostituire il contenuto del file Program.qs con il codice seguente:
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 {
// Allocate a qubit
use q = Qubit();
// Put the qubit to superposition
// It now has a 50% chance of being measured 0 or 1
H(q);
// Measure the qubit value
return M(q);
}
}
Osservare il nuovo codice.
- Prima
open
gli spazi dei nomi necessari dalle librerie Q# per le funzioni e le operazioni richieste. - Viene definita l'operazione
SampleQuantumRandomNumberGenerator
, che non accetta input e produce un valore di tipoResult
. Il tipoResult
rappresenta il risultato di una misurazione e può avere due valori:Zero
oOne
. - Allocare un singolo qubit con la parola chiave
use
. - Usare l'operazione
H
(Hadamard) per posizionare il qubit in una sovrapposizione uguale. - Usare l'operazione
M
per misurare il qubit e restituire il valore misurato (Zero
oOne
).
Come illustrato nell'articolo Informazioni sul calcolo quantistico, un qubit è un'unità di informazioni quantistiche che possono essere in sovrapposizione. Quando viene misurato, un qubit può trovarsi solo nello stato 0 o 1. Tuttavia, prima della misurazione, lo stato del qubit rappresenta la probabilità di leggere un valore 0 o 1 con una misurazione. In questo esempio, prima della misurazione il qubit si trova in una sovrapposizione uguale, il che significa che c'è una probabilità del 50% di leggere 0 e del 50% di leggere 1. È possibile usare questa probabilità per generare numeri casuali.
L'operazione SampleQuantumRandomNumberGenerator
definita dall'utente introduce il tipo di dati Qubit
, nativo di Q#. È possibile allocare Qubit
solo con un'istruzione use
. Quando viene allocato, un qubit si trova sempre nello stato Zero
.
Inserendo il qubit in sovrapposizione con l'operazione H
e misurandolo con l'operazione M
, il risultato è un valore diverso ogni volta che viene richiamato il codice.
Visualizzazione del codice con la sfera di Bloch
Nella sfera di Bloch il polo nord rappresenta il valore classico 0, mentre il polo sud rappresenta il valore classico 1. Qualsiasi sovrapposizione può essere rappresentata da un punto sulla sfera (rappresentato da una freccia). Più vicina è la fine della freccia a un polo, più alta è la probabilità che il qubit collassi nel valore classico assegnato a tale polo quando viene misurato. Ad esempio, lo stato del qubit rappresentato dalla freccia rossa nella figura seguente ha una probabilità più elevata di restituire il valore 0 se lo si misura.

È possibile usare questa rappresentazione per visualizzare le operazioni eseguite dal codice:
- Iniziare con un qubit inizializzato nello stato 0 e applicare un'operazione
H
per creare una sovrapposizione uguale in cui le probabilità di 0 e 1 siano le stesse.

- Quindi misurare il qubit e salvare l'output:

Poiché il risultato della misurazione è casuale e le probabilità di misurare 0 e 1 sono identiche, si è ottenuto un bit completamente casuale. È possibile chiamare questa operazione più volte per creare numeri interi. Ad esempio, se si chiama l'operazione tre volte per ottenere tre bit casuali, è possibile creare numeri casuali a 3 bit, ovvero un numero casuale compreso tra 0 e 7.
Creare un generatore di numeri casuali completo
Ora che è disponibile un'operazione Q# che genera bit casuali, è possibile combinare più bit casuali per compilare un generatore quantistico di numeri casuali completo. È possibile eseguire il programma come applicazione Q# autonoma o usare un programma host in Python o .NET per chiamare il codice Q#.
Definire la logica del generatore di numeri casuali
Prima esaminare come deve essere la logica di un generatore di numeri casuali, a condizione che sia disponibile un generatore di bit casuali:
- Definire max come numero massimo da generare.
- Definire il numero di bit casuali che è necessario generare. Questa operazione viene eseguita calcolando il numero di bit, numBits, necessari per esprimere numeri interi fino a max.
- Generare una stringa di bit casuale di lunghezza numBits.
- Se la stringa di bit rappresenta un numero maggiore di max, tornare al passaggio tre.
- In caso contrario, il processo è completato. Restituire il numero generato come valore intero.
Definire l'operazione
Definire quindi l'operazione SampleRandomNumberInRange
, che usa un ciclo for
per chiamare ripetutamente l'operazione SampleQuantumRandomNumberGenerator
e compilare una stringa di bit.
Modificare Program.qs in modo da aggiungere la nuova operazione:
namespace Qrng {
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Measurement;
open Microsoft.Quantum.Math;
open Microsoft.Quantum.Convert;
operation SampleQuantumRandomNumberGenerator() : Result {
// Allocate a qubit
use q = Qubit();
// Put the qubit to superposition
// It now has a 50% chance of being measured 0 or 1
H(q);
// Measure the qubit value
return M(q);
}
operation SampleRandomNumberInRange(max : Int) : Int {
mutable output = 0;
repeat {
mutable bits = [];
for idxBit in 1..BitSizeI(max) {
set bits += [SampleQuantumRandomNumberGenerator()];
}
set output = ResultArrayAsInt(bits);
} until (output <= max);
return output;
}
}
A questo punto esaminare per un attimo la nuova operazione.
- Per calcolare il numero di bit necessari per esprimere numeri interi fino a
max
, usare la funzioneBitSizeI
. - L'operazione
SampleRandomNumberInRange
usa un ciclorepeat
per generare numeri casuali fino a quando non viene generato un valore uguale o minore dimax
. - Il ciclo
for
all'interno direpeat
funziona esattamente come un ciclo negli altri linguaggi di programmazione. - In questo esempio
output
ebits
sono variabili modificabili. Una variabile modificabile può cambiare durante il calcolo. Per cambiare il valore di un valore mutabile, si usa la direttivaset
. - La funzione
ResultArrayAsInt
converte la stringa di bit in un numero intero positivo.
Il programma Qrng
può ora generare numeri interi casuali.
Eseguire il programma di generazione di numeri casuali
Usando la versione finale del codice Q#,
namespace Qrng {
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Measurement;
open Microsoft.Quantum.Math;
open Microsoft.Quantum.Convert;
operation SampleQuantumRandomNumberGenerator() : Result {
// Allocate a qubit
use q = Qubit();
// Put the qubit to superposition
// It now has a 50% chance of being measured 0 or 1
H(q);
// Measure the qubit value
return M(q);
}
operation SampleRandomNumberInRange(max : Int) : Int {
mutable output = 0;
repeat {
mutable bits = [];
for idxBit in 1..BitSizeI(max) {
set bits += [SampleQuantumRandomNumberGenerator()];
}
set output = ResultArrayAsInt(bits);
} until (output <= max);
return output;
}
}
selezionare la scheda per il linguaggio e l'ambiente preferiti e seguire le istruzioni per eseguire o chiamare il programma Q#.
- Applicazione Q# autonoma con Visual Studio o Visual Studio Code
- Python con Visual Studio Code o il prompt dei comandi
- C# con Visual Studio Code o Visual Studio
Un'applicazione Q# autonoma richiede EntryPoint
in modo che il compilatore Q# sappia dove avviare il programma. Per creare l'applicazione Q# completa, aggiungere il punto di ingresso seguente al programma Q#, Program.qs:
namespace Qrng {
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Measurement;
open Microsoft.Quantum.Math;
open Microsoft.Quantum.Convert;
operation SampleQuantumRandomNumberGenerator() : Result {
// Allocate a qubit.
use q = Qubit();
// Put the qubit to superposition.
H(q);
// It now has a 50% chance of being measured 0 or 1.
// Measure the qubit value.
return M(q);
}
operation SampleRandomNumberInRange(max : Int) : Int {
mutable output = 0;
repeat {
mutable bits = [];
for idxBit in 1..BitSizeI(max) {
set bits += [SampleQuantumRandomNumberGenerator()];
}
set output = ResultArrayAsInt(bits);
} until (output <= max);
return output;
}
@EntryPoint()
operation SampleRandomNumber() : Int {
let max = 50;
Message($"Sampling a random number between 0 and {max}: ");
return SampleRandomNumberInRange(max);
}
}
Il programma esegue l'operazione o la funzione contrassegnata con l'attributo @EntryPoint()
in un simulatore o in uno strumento di stima delle risorse, a seconda della configurazione del progetto e delle opzioni della riga di comando.
In Visual Studio è sufficiente premere Ctrl + F5 per eseguire lo script.
In VS Code compilare Program.qs la prima volta digitando nel terminale quanto segue:
dotnet build
Per le esecuzioni successive non è necessario ripetere la compilazione. Per eseguirlo, digitare il comando seguente e premere INVIO:
dotnet run --no-build
Nota
Questo frammento di codice non viene attualmente eseguito in alcun hardware targetsAzure Quantum disponibile, perché il chiamabile ResultArrayAsInt
richiede una QPU con profilo di calcolo completo.
Passaggi successivi
Esplorare altre esercitazioni su Q#:
- Esplorare l'entanglement con Q# mostra come scrivere un programma Q# che modifichi e misuri i qubit e mostra gli effetti della sovrapposizione e dell'entanglement.
- Implementare l'algoritmo di ricerca di Grover in Q# mostra come scrivere un programma Q# che usi l'algoritmo di ricerca di Grover per risolvere un problema di colorazione del grafo.
- Scrivere e simulare programmi a livello di qubit in Q# esplora come scrivere un programma Q# che operi direttamente su qubit specifici.