№ 1920Квантовые вычисленияУровень 3

Итерации и общий решатель Гровера

Функция 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()
Рисунок к задаче 1920

Сообщить об ошибке

Войти, чтобы отправить материал.