Упражнение, часть 2. Создание генератора квантовых случайных чисел
В этом уроке вы реализуете второй этап генератора квантовых случайных чисел: объединение нескольких случайных битов для формирования большего случайного числа. На этом этапе создается генератор случайных битов, который вы уже создали в предыдущем уроке.
Объединение нескольких случайных битов для формирования большего числа
В предыдущем уроке вы создали случайный генератор битов, который создает случайный бит, поместив кубитов в суперпозицию и измеряя его.
При измерении кубита вы получите случайный бит (0 или 1) с равной 50% вероятностью. Значение этого бита действительно случайно, нет способа знать, что вы получаете после измерения. Но как можно использовать это поведение для создания больших случайных чисел?
Предположим, что вы повторяете этот процесс четыре раза, создав следующую последовательность двоичных цифр:
$${0, 1, 1, 0}$$
Если сцепить (или объединить) эти биты в битовую строку, можно получить большее число. В этом примере битовая последовательность ${0110}$ эквивалентна шести в десятичном формате.
$${0110_{\ binary} \equiv 6_{\ decimal}}$$
Если повторить этот процесс много раз, можно объединить несколько битов для формирования любого большого числа.
Определение логики генератора случайных чисел
Давайте рассмотрим логику генератора случайных чисел, укажите генератор случайных битов, встроенный в предыдущем уроке:
- Определите
max
как максимальное число, которое требуется создать. - Определите число случайных битов, которые необходимо создать, вычисляя, сколько битов,
nBits
необходимо выразить целые числа доmax
. - Создание случайной битовой строки, длина которой равна
nBits
. - Если битовая строка представляет число больше
max
, выполняется возврат к шагу 3. - В противном случае процесс завершается. Возврат созданного числа в виде целого числа.
В качестве примера зададим для max
значение 12. То есть 12 — это наибольшее число, которое нужно получить из генератора случайных чисел.
Для представления числа от 0 до 12 требуется ${\lfloor ln(12) / ln(2) + 1 \rfloor}$ или 4 бита. (Для краткости мы пропустим, как наследовать это уравнение.)
Предположим, что вы создаете битовую строку $${1101_{\ binary}}$, которая эквивалентна ${13_{\ decimal}}$. Так как 13 больше 12, вы повторяете процесс.
Затем создается битовая строка ${0110_{\ binary}}$, которая эквивалентна ${6_{\ decimal}}$. Так как 6 меньше 12, процесс завершен.
Генератор квантовых случайных чисел возвращает число 6.
Создание генератора комплексных случайных чисел
Здесь вы разверните Main.qs
файл, чтобы создать более крупные случайные числа.
Импорт необходимых библиотек
Сначала необходимо импортировать необходимые пространства имен из стандартной библиотеки Q# в программу. Компилятор Q# автоматически загружает множество распространенных функций и операций, однако для полного генератора квантовых случайных чисел требуется несколько дополнительных функций и операций из двух пространств имен Q#: Microsoft.Quantum.Math
и Microsoft.Quantum.Convert
.
Скопируйте и вставьте следующие import
директивы в начало Main.qs
файла:
import Microsoft.Quantum.Convert.*;
import Microsoft.Quantum.Math.*;
Переименование операции в Main
GenerateRandomBit
Для полного генератора случайных чисел вы будете повторно использовать операцию, определенную в предыдущем уроке. Однако имя Main
операции является точкой входа программы и должно быть уникальным. Чтобы избежать путаницы, необходимо переименовать операцию GenerateRandomBit
в Main
.
Операция GenerateRandomBit
должна выглядеть следующим образом:
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;
}
Определение операции квантового случайного числа
Здесь вы определяете операцию GenerateRandomNumberInRange
. Эта операция многократно вызывает операцию GenerateRandomBit
для создания строки битов.
Скопируйте следующий код и вставьте его перед операцией GenerateRandomBit
в Main.qs
файл:
/// 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;
}
Рассмотрим этот новый код.
- Необходимо вычислить количество битов, необходимых для выражения целых чисел до
max
. ФункцияBitSizeI
изMicrosoft.Quantum.Math
библиотеки преобразует целое число в число битов, необходимых для представления. - Операция
GenerateRandomNumberInRange
использует циклfor
для создания случайных чисел до тех пор, пока не будет получено значение, которое меньше или равноmax
. Циклfor
работает точно так же, какfor
цикл на других языках программирования. - Переменная — это изменяемая переменная
bits
. Изменяемая переменная может изменяться во время вычисления. Для изменения значения изменяемой переменной используется директиваset
. - Функция
ResultArrayAsInt
поступает из библиотекиMicrosoft.Quantum.Convert
. Эта функция преобразует битовую строку в положительное целое число.
Добавление точки входа
Наконец, вы добавите точку входа в программу. По умолчанию компилятор Q# ищет Main
операцию и начинает обработку там, независимо от того, где он расположен. Операция Main
вызывает GenerateRandomNumberInRange
операцию для создания случайного числа от 0 до max
числа. В этом примере вы определяете максимальное значение как 100.
Скопируйте и вставьте следующий код в Main.qs
файл:
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);
}
Окончательная программа
Файл Main.qs
должен выглядеть следующим образом:
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 {
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);
// 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;
}
Запуск программы
Попробуем воспользоваться нашим новым генератором случайных чисел.
- Перед запуском программы необходимо задать для целевого профиля значение "Неограниченный". Выберите "Просмотреть>палитру команд", найдите QIR, выберите Q#: Задайте целевой профиль QIR Azure Quantum, а затем выберите Q#: неограниченный.
- Чтобы запустить программу, выберите "Выполнить " из списка команд над
Main
операцией или нажмите клавиши CTRL+F5. Выходные данные будут отображаться в консоли отладки. - Запустите программу еще раз, чтобы увидеть другой результат.
Примечание.
Если целевой профиль не имеет значения "Неограниченная", при запуске программы появится ошибка.
Поздравляем! Теперь вы узнали, как комбинировать классическую логику с Q# для создания квантового генератора случайных чисел.
Дополнительное упражнение
Попробуйте изменить программу, чтобы также требовалось, чтобы созданное случайное число было больше некоторого минимального числа, min
а не нуля.