Latihan Bagian 2 - Membuat generator angka acak kuantum

Selesai

Dalam unit ini, Anda mengimplementasikan bagian kedua dari generator angka acak kuantum Anda. Anda menggabungkan beberapa bit acak untuk membentuk angka acak yang lebih besar. Bagian ini dibangun pada generator bit acak yang sudah Anda buat di unit sebelumnya.

Menggabungkan beberapa bit acak untuk membentuk angka yang lebih besar

Di unit sebelumnya, Anda membuat generator bit acak yang menempatkan qubit ke dalam status superposisi dan kemudian mengukur qubit tersebut untuk menghasilkan nilai bit acak baik 0 atau 1, masing-masing dengan probabilitas 50%. Nilai bit ini benar-benar acak, tidak ada cara untuk mengetahui sebelumnya apa hasil pengukurannya. Tetapi bagaimana Anda dapat menggunakan perilaku ini untuk menghasilkan angka acak yang lebih besar?

Jika Anda mengulangi proses empat kali, maka Anda mungkin menghasilkan urutan digit biner ini:

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

Jika Anda menggabungkan bit ini ke dalam string bit, maka Anda dapat membentuk angka yang lebih besar. Dalam contoh ini, urutan bit ${0110}$ dalam biner setara dengan angka 6 dalam desimal.

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

Untuk menghasilkan angka acak yang sangat besar, cukup ulangi proses ini berkali-kali. Kemudian, gabungkan semua bit ke dalam angka biner dan konversi angka biner tersebut menjadi angka desimal.

Menentukan logika generator angka acak

Sebelum Anda menulis kode Q#, mari kita garis besarkan logika untuk menghasilkan angka acak:

  1. Tentukan max sebagai angka desimal maksimum yang ingin Anda hasilkan.
  2. Tentukan jumlah bit acak, nBits, yang diperlukan untuk menghasilkan max.
  3. Hasilkan string bit acak yang panjangnya nBits.
  4. Jika string bit mewakili angka yang lebih besar dari max, maka kembali ke langkah sebelumnya.
  5. Jika tidak, prosesnya selesai. Mengembalikan angka yang dihasilkan sebagai bilangan bulat desimal.

Misalnya, mari kita tentukan max menjadi 12. Artinya, 12 adalah angka terbesar yang harus dihasilkan generator angka acak Anda.

Gunakan persamaan berikut untuk menentukan jumlah bit yang diperlukan untuk mewakili angka 12 dalam biner:

$${\lfloor ln(12) / ln(2) + 1 \rfloor}$$

Menurut persamaan ini, Anda memerlukan 4 bit untuk mewakili angka antara 0 dan 12.

Misalnya, Anda menghasilkan bit acak empat kali dan mendapatkan string bit ${1101_{\ biner}}$. Nilai dalam biner ini sama dengan 13 dalam desimal. Karena 13 lebih besar dari 12, Anda mengulangi prosesnya.

Selanjutnya, Anda menghasilkan string bit ${0110_{\ biner}}$, yang sama dengan ${6_{\ desimal}}$. Karena 6 kurang dari 12, proses selesai.

Generator angka acak kuantum mengembalikan angka 6.

Membuat generator angka acak lengkap di Q#

Di sini, Anda memperluas Main.qs file dari pelajaran sebelumnya untuk membangun generator angka acak Anda.

Mengimpor pustaka yang diperlukan

Pertama, impor namespace dari pustaka standar Q# yang berisi fungsi dan operasi yang Anda butuhkan untuk menulis program Anda. Pengkompilasi Q# memuat banyak fungsi dan operasi umum secara otomatis. Tetapi untuk generator angka acak kuantum, Anda memerlukan beberapa fungsi dan operasi tambahan dari dua namespace Q#: Microsoft.Quantum.Math dan Microsoft.Quantum.Convert.

Salin dan tempel arahan berikut import di awal file Anda Main.qs :

import Std.Convert.*;
import Std.Math.*;

Catatan

Anda dapat menggunakan Std alih-alih Microsoft.Quantum mengimpor fungsi dan operasi dari pustaka standar.

Ganti nama operasi menjadi MainGenerateRandomBit

Program generator angka acak menggunakan Main operasi yang Anda tulis di unit sebelumnya untuk menghasilkan bit acak. Ganti nama Main operasi menjadi GenerateRandomBit agar operasi ini memiliki nama yang lebih deskriptif dan bukan titik masuk ke program.

Salin dan tempel kode berikut ke dalam Main.qs:

import Std.Convert.*;
import Std.Math.*;

operation GenerateRandomBit() : Result {
    // Allocate a qubit.
    use q = Qubit();
    
    // Set the qubit into superposition of 0 and 1 using the Hadamard 
    H(q);
    
    // Measure the qubit and store the result.    
    let result = M(q);
    
    // Reset qubit to the |0〉 state.
    Reset(q);
    
    // Return the result of the measurement.
    return result;
}

Menentukan operasi generator angka acak

Buat operasi baru yang disebut GenerateRandomNumberInRange. Operasi ini berulang kali memanggil operasi GenerateRandomBit untuk membangun string bit.

Salin kode berikut dan letakkan langsung sebelum operasi GenerateRandomBit di file Main.qs Anda.

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

Berikut adalah gambaran umum kode di GenerateRandomNumberInRange:

  • BitSizeI Panggil fungsi dari Std.Math pustaka untuk menghitung jumlah bit yang diperlukan untuk mewakili bilangan bulat yang disimpan di max.
  • Gunakan perulangan for untuk menghasilkan sejumlah bit acak yang sama dengan nBits. Panggil operasi Anda GenerateRandomBit untuk menghasilkan bit acak.
  • Di dalam perulangan for, gunakan statemen set untuk memperbarui variabel bits dengan setiap bit acak baru. Variabel bits adalah variabel yang dapat diubah, yang berarti bahwa nilai bits dapat berubah selama komputasi.
  • Panggil fungsi dari pustaka Std.Convert untuk mengonversi array bit di bits menjadi bilangan bulat positif yang disimpan di sample.
  • return Dalam pernyataan, periksa apakah sample lebih besar dari max. Jika sample lebih besar dari max, maka panggil GenerateRandomNumberInRange lagi dan mulai lagi. Jika tidak, kembalikan angka acak yang disimpan di sample.

Menambahkan titik masuk

Terakhir, tambahkan operasi titik masuk ke kode Anda sehingga pengkompilasi dapat menjalankan program Anda. Secara default, pengkompilasi Q# mencari operasi Main dan menggunakan Main sebagai titik masuk, terlepas dari lokasi Main dalam file Anda. Di sini, Main operasi menetapkan nilai untuk max dan memanggil GenerateRandomNumberInRange operasi untuk menghasilkan angka acak antara 0 dan max.

Misalnya, untuk menghasilkan angka acak antara 0 dan 100, salin kode berikut ke file Anda Main.qs :

operation Main() : Int {
    let max = 100;
    Message($"Generating a random number between 0 and {max}: ");

    // Generate random number in the 0..max range.
    return GenerateRandomNumberInRange(max);
}

Program akhir

Berikut adalah kode Q# lengkap untuk program Anda di Main.qs:

import Std.Convert.*;
import Std.Math.*;

operation Main() : Int {
    let max = 100;
    Message($"Generating 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's within the requested range.
    // Generate it again if it's 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);
    
    // 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.
    Reset(q);
    
    // Return the result of the measurement.
    return result;
}

Jalankan program

Cobalah generator angka acak kuantum baru Anda!

Untuk menjalankan program Anda, pilih lensa kode Jalankan dari daftar perintah di atas operasi Main. Atau, tekan Ctrl + F5. Output Anda ditampilkan di konsol debug. Jalankan program beberapa kali dan perhatikan bagaimana hasilnya berubah.

Selamat! Anda membuat generator nomor kuantum yang benar-benar acak di Q#.

Latihan Tambahan

Cobalah untuk memodifikasi program sehingga juga mengharuskan angka acak yang dihasilkan lebih besar dari beberapa angka positif minimum, min, bukan nol.