Итерации и общий решатель Гровера
Функция grover_problem_oracle(n,variant) возвращает фазовый оракул на n кубитах; одинаковые n и variant дают одинаковый оракул. Вызов с print_solutions=True показывает его решения. Весь восстановленный исходный код функции и исходные вспомогательные функции сохранены ниже. Рисунок показывает пример вызова оракула.
1. Оракул grover_problem_oracle(4,variant=2) имеет одно решение.
a. Сколько итераций нужно, чтобы вероятность измерить решение превышала 90 процентов?
b. Найдите это состояние алгоритмом Гровера.
c. Что произойдёт, если применить больше итераций, чем найдено в a? Почему?
2. При двух решениях и четырёх кубитах сколько итераций нужно для вероятности успеха более 90 процентов? Проверьте ответ на grover_problem_oracle(4,variant=1), у которого два решения.
3. Напишите grover_solver(oracle,iterations), которая принимает вентиль оракула и целое число итераций и возвращает QuantumCircuit алгоритма Гровера с указанным числом итераций.
Алгоритм начинается с равномерной суперпозиции. Одна итерация состоит из фазового оракула и отражения относительно этой суперпозиции.
Полная исходная программа для задания:
#initialization
import matplotlib.pyplot as plt
import numpy as np
import math
# importing Qiskit
from qiskit import IBMQ, Aer, transpile, execute
from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister
from qiskit.providers.ibmq import least_busy
# import basic plot tools
from qiskit.visualization import plot_histogram
from qiskit.circuit.library import Diagonal
def grover_problem_oracle(n, variant=0, print_solutions=False):
np.random.seed(variant)
if n < 3:
nsolutions = 1
else:
nsolutions = np.random.randint(1, np.ceil((2**n)/4))
diagonal_elements = [-1]*nsolutions + [1]*((2**n) - nsolutions)
np.random.shuffle(diagonal_elements)
oracle_gate = Diagonal(diagonal_elements)
oracle_gate.name = "Oracle\nn=%i, var=%i" % (n, variant)
if print_solutions:
print("Solutions:")
for idx, e in enumerate(diagonal_elements):
if e < 1:
print("|%s>" % format(idx, "0%ib" % n))
return oracle_gate
def initialize_s(qc, qubits):
"""Apply a H-gate to 'qubits' in qc"""
for q in qubits:
qc.h(q)
return qc
def diffuser(nqubits):
qc = QuantumCircuit(nqubits)
# Apply transformation |s> -> |00..0> (H-gates)
for qubit in range(nqubits):
qc.h(qubit)
# Apply transformation |00..0> -> |11..1> (X-gates)
for qubit in range(nqubits):
qc.x(qubit)
# Do multi-controlled-Z gate
qc.h(nqubits-1)
qc.mct(list(range(nqubits-1)), nqubits-1) # multi-controlled-toffoli
qc.h(nqubits-1)
# Apply transformation |11..1> -> |00..0>
for qubit in range(nqubits):
qc.x(qubit)
# Apply transformation |00..0> -> |s>
for qubit in range(nqubits):
qc.h(qubit)
# We will return the diffuser as a gate
U_s = qc.to_gate()
U_s.name = "U$_s$"
return U_s
from qiskit_textbook.problems import grover_problem_oracle
## Example Usage
n = 4
oracle = grover_problem_oracle(n, variant=1) # 0th variant of oracle, with n qubits
qc = QuantumCircuit(n)
qc.append(oracle, [0,1,2,3])
qc.draw()
Сообщить об ошибке
Войти, чтобы отправить материал.