Skip to main content
IBM Quantum Platform

qiskit.circuit.library.grover_operator

qiskit.circuit.library.grover_operator(oracle, state_preparation=None, zero_reflection=None, reflection_qubits=None, insert_barriers=False, name='Q')

GitHub

Grover 연산자를 구축합니다.

그로버의 검색 알고리즘 [1, 2는] 원하는 출력 상태의 진폭을 증폭하는 데 사용되는 소위 그로버 연산자를 반복적으로 적용하는 것으로 구성됩니다. 이 연산자( Q\mathcal{Q} )는 위상 오라클( Sf\mathcal{S}_f ), 제로 위상 편이 또는 제로 반사( S0\mathcal{S}_0 ), 입력 상태 준비( A\mathcal{A} )로 구성됩니다:

Q=AS0ASf\mathcal{Q} = \mathcal{A} \mathcal{S}_0 \mathcal{A}^\dagger \mathcal{S}_f

표준 Grover 검색에는 A=Hn\mathcal{A} = H^{\otimes n} 이 있습니다:

Q=HnS0HnSf=DSf\mathcal{Q} = H^{\otimes n} \mathcal{S}_0 H^{\otimes n} \mathcal{S}_f = D \mathcal{S_f}

D=HnS0HnD = H^{\otimes n} \mathcal{S}_0 H^{\otimes n} 작업은 확산 연산자라고도 합니다. 이 공식에서 Grover의 연산자는 두 단계로 구성되어 있음을 알 수 있습니다. 먼저 위상 오라클이 좋은 상태에 -1 를 곱한 다음( Sf\mathcal{S}_f ), 전체 상태를 평균 주위에 반영합니다( DD ).

이 클래스를 사용하면 양자 진폭 증폭(그로버 알고리즘의 일반화)과 같이 서로 다른 상태 준비 과정을 설정할 수 있습니다. A\mathcal{A} 는 하다마르 게이트의 레이어가 아닐 수도 있습니다. [3].

위상 오라클 Sf\mathcal{S}_f 의 동작은 다음과 같이 정의됩니다

Sf:x(1)f(x)x\mathcal{S}_f: |x\rangle \mapsto (-1)^{f(x)}|x\rangle

여기서 xx 상태가 양호하면 f(x)=1f(x) = 1, 그렇지 않으면 0입니다. 이 오라클이 좋은 상태의 위상을 뒤집고 결과 큐비트의 상태를 뒤집지 않는다는 사실을 강조하기 위해 Sf\mathcal{S}_f 을 위상 오라클이라고 부릅니다.

비트플립 오라클로부터 위상 오라클을 쉽게 구성할 수 있는 방법은 결과 큐비트에 제어된 X 게이트를 X와 H 게이트로 샌드위치하는 것입니다. 인스턴스

Bitflip oracle     Phaseflip oracle
q_0: ──■──         q_0: ────────────■────────────
     ┌─┴─┐              ┌───┐┌───┐┌─┴─┐┌───┐┌───┐
out: ┤ X ├         out: ┤ X ├┤ H ├┤ X ├┤ H ├┤ X ├
     └───┘              └───┘└───┘└───┘└───┘└───┘

오라클 및 A\mathcal{A} 연산자를 정의하는 데 약간의 유연성이 있습니다. 그로버 알고리즘에서 그로버 연산자를 적용하기 전에 먼저 A\mathcal{A} 연산자(또는 표준 공식에서는 하다마드 게이트)를 한 번 적용하여 큐비트를 준비합니다. 따라서 항상 ASfA\mathcal{A} \mathcal{S}_f \mathcal{A}^\dagger 형식의 연산이 있습니다. 따라서 비트플립 로직을 A\mathcal{A} 으로 옮기고 오라클은 비트플립에 기반한 Z 게이트를 통해 위상 플립만 수행하도록 남겨둘 수 있습니다. 이에 대한 한 가지 가능한 사용 사례는 상태 큐비트의 계산을 해제하지 않는 오라클입니다.

제로 리플렉션 S0\mathcal{S}_0 은 일반적으로 다음과 같이 정의됩니다

S0=20n0nIn\mathcal{S}_0 = 2 |0\rangle^{\otimes n} \langle 0|^{\otimes n} - \mathbb{I}_n

여기서 In\mathbb{I}_nnn 쿼빗의 ID입니다. 기본적으로 이 클래스는 네거티브 버전 20n0nIn2 |0\rangle^{\otimes n} \langle 0|^{\otimes n} - \mathbb{I}_n 을 구현하는데, 이는 대상 큐비트에 X 게이트로 샌드위치된 다중 제어 Z로 간단히 구현할 수 있고 도입된 글로벌 위상은 Grover의 알고리즘에 중요하지 않기 때문입니다.

예:

위상 오라클만으로 Grover 연산자를 구성할 수 있습니다:

from qiskit.circuit import QuantumCircuit
from qiskit.circuit.library import grover_operator

oracle = QuantumCircuit(2)
oracle.z(0)  # good state = first qubit is |1>
grover_op = grover_operator(oracle, insert_barriers=True)
grover_op.draw("mpl")
이전 코드에서 출력한 회로도입니다.

상태 준비를 수정할 수도 있습니다:

oracle = QuantumCircuit(1)
oracle.z(0)  # the qubit state |1> is the good state
state_preparation = QuantumCircuit(1)
state_preparation.ry(0.2, 0)  # non-uniform state preparation
grover_op = grover_operator(oracle, state_preparation)
grover_op.draw("mpl")
이전 코드에서 출력한 회로도입니다.

또한 제로 리플렉션이 어떤 큐비트에 작용해야 하는지 표시할 수도 있습니다. 이는 일부 큐비트가 스크래치 공간으로만 사용되지만 오라클에 영향을 미치지 않아야 하는 경우에 유용합니다:

oracle = QuantumCircuit(4)
oracle.z(3)
reflection_qubits = [0, 3]
state_preparation = QuantumCircuit(4)
state_preparation.cry(0.1, 0, 3)
state_preparation.ry(0.5, 3)
grover_op = grover_operator(oracle, state_preparation, reflection_qubits=reflection_qubits)
grover_op.draw("mpl")
이전 코드에서 출력한 회로도입니다.

오라클과 제로 리플렉션은 객체로 qiskit.quantum_info 전달할 수도 있습니다:

from qiskit.quantum_info import Statevector, DensityMatrix, Operator

mark_state = Statevector.from_label("011")
reflection = 2 * DensityMatrix.from_label("000") - Operator.from_label("III")
grover_op = grover_operator(oracle=mark_state, zero_reflection=reflection)
grover_op.draw("mpl")
이전 코드에서 출력한 회로도입니다.

많은 수의 큐비트에 대해 제로 반사에 사용되는 다중 제어 X 게이트는 다양한 방식으로 합성할 수 있습니다. 사용 가능한 큐비트 수에 따라 컴파일러는 다른 구현을 선택합니다:

from qiskit import transpile, Qubit
from qiskit.circuit import QuantumCircuit
from qiskit.circuit.library import grover_operator

oracle = QuantumCircuit(10)
oracle.z(oracle.qubits)
grover_op = grover_operator(oracle)

# without extra qubit space, the MCX synthesis is expensive
basis_gates = ["u", "cx"]
tqc = transpile(grover_op, basis_gates=basis_gates)
is_2q = lambda inst: len(inst.qubits) == 2
print("2q depth w/o scratch qubits:", tqc.depth(filter_function=is_2q))  # > 350

# add extra bits that can be used as scratch space
grover_op.add_bits([Qubit() for _ in range(num_qubits)])
tqc = transpile(grover_op, basis_gates=basis_gates)
print("2q depth w/ scratch qubits:", tqc.depth(filter_function=is_2q)) # < 100

매개변수

  • oracle (QuantumCircuit |Statevector) – 불량 상태에 대한 반성을 구현하는 페이즈 오라클. 이 기능은 비트 플립 오라클이 아니라는 점에 유의하십시오. 자세한 내용은 문서 문자열을 참조하십시오.
  • state_preparation (QuantumCircuit | None) – 양호 상태와 불량 상태를 준비하는 작업자. 그로버 알고리즘의 경우, 이는 n-큐비트 하다마르 게이트이며, 진폭 증폭 또는 추정 시에는 연산자 A\mathcal{A} 가 사용된다.
  • zero_reflection (QuantumCircuit |DensityMatrix |Operator | None) – 제로 상태에 대한 고찰, S0\mathcal{S}_0.
  • reflection_qubits (list[int] | None) – 제로 반사가 작용하는 큐비트입니다.
  • insert_barriers (bool) – 리플렉션과 A 사이에 장벽을 삽입해야 하는지 여부입니다.
  • name (str) – 서킷의 이름입니다.

참조 자료:

[1] L. K. Grover (1996), 데이터베이스 검색을 위한 빠른 양자역학적 알고리즘, arXiv:quant-ph/9605043.

[2] I. Chuang & M. 닐슨, 양자 계산 및 양자 정보, 캠브리지: 캠브리지 대학 출판부, 2000. 장 6.1.2.

[3] 브라사르, G., 호이어, P., 모스카, M., & 태프, A. (2000). 양자 진폭 증폭 및 추정. arXiv:quant-ph/0005055.

이 페이지가 도움이 되었습니까?
GitHub에서 버그, 오타를 보고하거나 컨텐츠를 요청하십시오.