Grover 알고리즘
사용 시간 예측: Eagle r3 프로세서에서 1분 미만 (참고: 이는 예측치이며 실제 실행 시간은 다를 수 있습니다.)
배경
진폭 증폭(Amplitude amplification)은 범용 양자 알고리즘(또는 서브루틴)으로, 여러 고전 알고리즘에 비해 이차적 속도 향상을 얻는 데 활용할 수 있습니다. Grover 알고리즘은 비구조적 탐색 문제에서 이 속도 향상을 처음으로 입증한 알고리즘입니다. Grover 탐색 문제를 공식화하려면 하나 이상의 계산 기저 상태를 찾고자 하는 상태로 표시하는 오라클 함수와, 표시된 상태의 진폭을 높이고 나머지 상태를 억제하는 증폭 Circuit이 필요합니다.
여기서는 Grover 오라클을 구성하는 방법과 Qiskit Circuit 라이브러리의 grover_operator()를 사용하여 Grover 탐색 인스턴스를 손쉽게 설정하는 방법을 소개합니다. 런타임 Sampler 프리미티브를 통해 Grover Circuit을 원활하게 실행할 수 있습니다.
요구 사항
이 튜토리얼을 시작하기 전에 다음이 설치되어 있는지 확인하세요:
- Qiskit SDK v1.4 이상 (시각화 지원 포함)
- Qiskit Runtime (
pip install qiskit-ibm-runtime) v0.36 이상
설정
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
# Built-in modules
import math
# Imports from Qiskit
from qiskit import QuantumCircuit
from qiskit.circuit.library import grover_operator, MCMTGate, ZGate
from qiskit.visualization import plot_distribution
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
# Imports from Qiskit Runtime
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import SamplerV2 as Sampler
def grover_oracle(marked_states):
"""Build a Grover oracle for multiple marked states
Here we assume all input marked states have the same number of bits
Parameters:
marked_states (str or list): Marked states of oracle
Returns:
QuantumCircuit: Quantum circuit representing Grover oracle
"""
if not isinstance(marked_states, list):
marked_states = [marked_states]
# Compute the number of qubits in circuit
num_qubits = len(marked_states[0])
qc = QuantumCircuit(num_qubits)
# Mark each target state in the input list
for target in marked_states:
# Flip target bit-string to match Qiskit bit-ordering
rev_target = target[::-1]
# Find the indices of all the '0' elements in bit-string
zero_inds = [
ind
for ind in range(num_qubits)
if rev_target.startswith("0", ind)
]
# Add a multi-controlled Z-gate with pre- and post-applied X-gates (open-controls)
# where the target bit-string has a '0' entry
if zero_inds:
qc.x(zero_inds)
qc.compose(MCMTGate(ZGate(), num_qubits - 1, 1), inplace=True)
if zero_inds:
qc.x(zero_inds)
return qc
1단계: 고전적 입력을 양자 문제로 매핑하기
Grover 알고리즘에는 하나 이상의 표시된 계산 기저 상태를 지정하는 오라클이 필요합니다. 여기서 "표시된"이란 위상이 -1인 상태를 의미합니다. controlled-Z Gate 또는 Qubit에 대한 다중 제어 일반화는 상태('1'* 비트 문자열)를 표시합니다. 이진 표현에 하나 이상의 '0'이 있는 기저 상태를 표시하려면 controlled-Z Gate 전후에 해당 Qubit에 X Gate를 적용해야 합니다. 이는 해당 Qubit에 열린 제어(open-control)를 두는 것과 동일합니다. 다음 코드에서는 비트 문자열 표현으로 정의된 하나 이상의 입력 기저 상태를 표시하는 오라클을 정의합니다. 다중 제어 Z Gate를 구현하기 위해 MCMT Gate를 사용합니다.
# To run on hardware, select the backend with the fewest number of jobs in the queue
service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=127
)
backend.name
'ibm_brisbane'
특정 Grover 인스턴스
오라클 함수가 준비되었으니, 이제 Grover 탐색의 특정 인스턴스를 정의할 수 있습니다. 이 예제에서는 세 Qubit 계산 공간의 여덟 가지 가능한 상태 중 두 개의 계산 상태를 표시합니다:
marked_states = ["011", "100"]
oracle = grover_oracle(marked_states)
oracle.draw(output="mpl", style="iqp")
marked_states = ["011", "100"]
oracle = grover_oracle(marked_states)
oracle.draw(output="mpl", style="iqp")

marked_states = ["011", "100"]
oracle = grover_oracle(marked_states)
oracle.draw(output="mpl", style="iqp")
