Пройти три шага поиска решения двоичного судоку
Исходный пример — двоичное судоку 2×2. В каждой строке и каждом столбце значения должны различаться. Расположение переменных v0,v1,v2,v3 показано на исходном рисунке; проверяются пары (0,1),(0,2),(1,3),(2,3). В исходнике после разобранного примера выделен цельный блок Your turn:
1. Создайте обратимую классическую схему, которая распознаёт правильное решение.
2. Используйте перенос фазы и обратное вычисление промежуточных данных, чтобы превратить эту схему в оракул.
3. Примените алгоритм Гровера для решения этого оракула.
Перед продолжением автор также просит убедиться в работе схемы проверки. Все входы v — вычислительные базисные состояния; рабочие кубиты c сначала равны 0000. Для фазового оракула выход готовится в $|-\rangle$. Исходная полная программа и схема приведены как контекст уже разобранного примера.
Полная исходная программа для задания:
#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
qasm_sim = Aer.get_backend('qasm_simulator')
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
clause_list = [[0,1],
[0,2],
[1,3],
[2,3]]
def XOR(qc, a, b, output):
qc.cx(a, output)
qc.cx(b, output)
var_qubits = QuantumRegister(4, name='v')
clause_qubits = QuantumRegister(4, name='c')
output_qubit = QuantumRegister(1, name='out')
cbits = ClassicalRegister(4, name='cbits')
qc = QuantumCircuit(var_qubits, clause_qubits, output_qubit, cbits)
def sudoku_oracle(qc, clause_list, clause_qubits):
# Compute clauses
i = 0
for clause in clause_list:
XOR(qc, clause[0], clause[1], clause_qubits[i])
i += 1
# Flip 'output' bit if all clauses are satisfied
qc.mct(clause_qubits, output_qubit)
# Uncompute clauses to reset clause-checking bits to 0
i = 0
for clause in clause_list:
XOR(qc, clause[0], clause[1], clause_qubits[i])
i += 1
sudoku_oracle(qc, clause_list, clause_qubits)
qc.draw()
var_qubits = QuantumRegister(4, name='v')
clause_qubits = QuantumRegister(4, name='c')
output_qubit = QuantumRegister(1, name='out')
cbits = ClassicalRegister(4, name='cbits')
qc = QuantumCircuit(var_qubits, clause_qubits, output_qubit, cbits)
# Initialize 'out0' in state |->
qc.initialize([1, -1]/np.sqrt(2), output_qubit)
# Initialize qubits in state |s>
qc.h(var_qubits)
qc.barrier() # for visual separation
## First Iteration
# Apply our oracle
sudoku_oracle(qc, clause_list, clause_qubits)
qc.barrier() # for visual separation
# Apply our diffuser
qc.append(diffuser(4), [0,1,2,3])
## Second Iteration
sudoku_oracle(qc, clause_list, clause_qubits)
qc.barrier() # for visual separation
# Apply our diffuser
qc.append(diffuser(4), [0,1,2,3])
# Measure the variable qubits
qc.measure(var_qubits, cbits)
qc.draw(fold=-1)
# Simulate and plot results
qasm_simulator = Aer.get_backend('qasm_simulator')
transpiled_qc = transpile(qc, qasm_simulator)
result = qasm_sim.run(transpiled_qc).result()
plot_histogram(result.get_counts())
Сообщить об ошибке
Войти, чтобы отправить материал.