Skip to main content
IBM Quantum Platform

GroverOperator

class qiskit.circuit.library.GroverOperator(oracle, state_preparation=None, zero_reflection=None, reflection_qubits=None, insert_barriers=False, mcx_mode='noancilla', name='Q')

GitHub

Basen: QuantumCircuit

Der Betreiber Grover.

Der Grover-Suchalgorithmus [1, 2] besteht aus wiederholten Anwendungen des so genannten Grover-Operators, der zur Verstärkung der Amplituden der gewünschten Ausgangszustände verwendet wird. Dieser Operator, Q\mathcal{Q}, besteht aus dem Phasenorakel, Sf\mathcal{S}_f, der Nullphasenverschiebung oder Nullreflexion, S0\mathcal{S}_0, und einer Eingangszustandsvorbereitung A\mathcal{A} :

Q=AS0A†Sf\mathcal{Q} = \mathcal{A} \mathcal{S}_0 \mathcal{A}^\dagger \mathcal{S}_f

In der Standard-Grover-Suche haben wir A=H⊗n\mathcal{A} = H^{\otimes n} :

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

Die Operation D=H⊗nS0H⊗nD = H^{\otimes n} \mathcal{S}_0 H^{\otimes n} wird auch als Diffusionsoperator bezeichnet. Aus dieser Formulierung geht hervor, dass der Grover-Operator aus zwei Schritten besteht: Zuerst multipliziert das Phasenorakel die guten Zustände mit -1 (mit Sf\mathcal{S}_f ) und dann wird der gesamte Zustand um den Mittelwert gespiegelt (mit DD ).

Diese Klasse ermöglicht die Festlegung einer anderen Zustandsvorbereitung, wie beispielsweise bei der Quantenamplitudenverstärkung (einer Verallgemeinerung des Grover-Algorithmus); A\mathcal{A} ist möglicherweise keine Schicht aus Hadamard-Gattern [3].

Die Aktion des Phasenorakels Sf\mathcal{S}_f ist definiert als

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

wobei f(x)=1f(x) = 1, wenn xx ein guter Zustand ist, und 0 andernfalls. Um die Tatsache hervorzuheben, dass dieses Orakel die Phase der guten Zustände umkehrt und nicht den Zustand eines Ergebnis-Qubits umkehrt, nennen wir Sf\mathcal{S}_f ein Phasenorakel.

Es ist zu beachten, dass man ein Phasenorakel leicht aus einem Bitflip-Orakel konstruieren kann, indem man das kontrollierte X-Gatter auf dem Ergebnis-Qubit durch ein X- und H-Gatter einklemmt. Zum Beispiel

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

Es besteht eine gewisse Flexibilität bei der Definition des Orakels und des Operators A\mathcal{A}. Bevor der Grover-Operator in Grovers Algorithmus angewendet wird, werden die Qubits zunächst mit einer Anwendung des A\mathcal{A} -Operators (oder Hadamard-Gates in der Standardformulierung) vorbereitet. Wir haben also immer eine Operation der Form ASfA†\mathcal{A} \mathcal{S}_f \mathcal{A}^\dagger. Daher ist es möglich, die Bitflip-Logik in A\mathcal{A} zu verlagern und das Orakel nur noch für Phasenumkehrungen über Z-Gatter auf der Grundlage der Bitflips einzusetzen. Ein möglicher Anwendungsfall hierfür sind Orakel, die die Zustands-Qubits nicht dekompilieren.

Die Null-Reflexion S0\mathcal{S}_0 ist normalerweise definiert als

S0=2∣0⟩⊗n⟨0∣⊗n−In\mathcal{S}_0 = 2 |0\rangle^{\otimes n} \langle 0|^{\otimes n} - \mathbb{I}_n

wobei In\mathbb{I}_n die Identität auf nn qubits ist. Standardmäßig implementiert diese Klasse die negative Version 2∣0⟩⊗n⟨0∣⊗n−In2 |0\rangle^{\otimes n} \langle 0|^{\otimes n} - \mathbb{I}_n, da diese einfach mit einem mehrfach kontrollierten Z zwischen X-Gattern auf dem Ziel-Qubit implementiert werden kann und die eingeführte globale Phase für den Grover-Algorithmus keine Rolle spielt.

Beispiele

>>> from qiskit.circuit import QuantumCircuit
>>> from qiskit.circuit.library import GroverOperator
>>> oracle = QuantumCircuit(2)
>>> oracle.z(0)  # good state = first qubit is |1>
>>> grover_op = GroverOperator(oracle, insert_barriers=True)
>>> grover_op.decompose().draw()
         ┌───┐ ░ ┌───┐ ░ ┌───┐          ┌───┐      ░ ┌───┐
state_0: ┤ Z ├─░─┤ H ├─░─┤ X ├───────■──┤ X ├──────░─┤ H ├
         └───┘ ░ ├───┤ ░ ├───┤┌───┐┌─┴─┐├───┤┌───┐ ░ ├───┤
state_1: ──────░─┤ H ├─░─┤ X ├┤ H ├┤ X ├┤ H ├┤ X ├─░─┤ H ├
               ░ └───┘ ░ └───┘└───┘└───┘└───┘└───┘ ░ └───┘
>>> 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 = GroverOperator(oracle, state_preparation)
>>> grover_op.decompose().draw()
         ┌───┐┌──────────┐┌───┐┌───┐┌───┐┌─────────┐
state_0: ┤ Z ├┤ RY(-0.2) ├┤ X ├┤ Z ├┤ X ├┤ RY(0.2) ├
         └───┘└──────────┘└───┘└───┘└───┘└─────────┘
>>> 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 = GroverOperator(oracle, state_preparation,
... reflection_qubits=reflection_qubits)
>>> grover_op.decompose().draw()
                                      ┌───┐          ┌───┐
state_0: ──────────────────────■──────┤ X ├───────■──┤ X ├──────────■────────────────
                               │      └───┘       │  └───┘          │
state_1: ──────────────────────┼──────────────────┼─────────────────┼────────────────
                               │                  │                 │
state_2: ──────────────────────┼──────────────────┼─────────────────┼────────────────
         ┌───┐┌──────────┐┌────┴─────┐┌───┐┌───┐┌─┴─┐┌───┐┌───┐┌────┴────┐┌─────────┐
state_3: ┤ Z ├┤ RY(-0.5) ├┤ RY(-0.1) ├┤ X ├┤ H ├┤ X ├┤ H ├┤ X ├┤ RY(0.1) ├┤ RY(0.5) ├
         └───┘└──────────┘└──────────┘└───┘└───┘└───┘└───┘└───┘└─────────┘└─────────┘
>>> mark_state = Statevector.from_label('011')
>>> diffuse_operator = 2 * DensityMatrix.from_label('000') - Operator.from_label('III')
>>> grover_op = GroverOperator(oracle=mark_state, zero_reflection=diffuse_operator)
>>> grover_op.decompose().draw(fold=70)
         ┌─────────────────┐      ┌───┐                          »
state_0: ┤0                ├──────┤ H ├──────────────────────────»
         │                 │┌─────┴───┴─────┐     ┌───┐          »
state_1: ┤1 UCRZ(0,pi,0,0) ├┤0              ├─────┤ H ├──────────»
         │                 ││  UCRZ(pi/2,0) │┌────┴───┴────┐┌───┐»
state_2: ┤2                ├┤1              ├┤ UCRZ(-pi/4) ├┤ H ├»
         └─────────────────┘└───────────────┘└─────────────┘└───┘»
«         ┌─────────────────┐      ┌───┐
«state_0: ┤0                ├──────┤ H ├─────────────────────────
«         │                 │┌─────┴───┴─────┐    ┌───┐
«state_1: ┤1 UCRZ(pi,0,0,0) ├┤0              ├────┤ H ├──────────
«         │                 ││  UCRZ(pi/2,0) │┌───┴───┴────┐┌───┐
«state_2: ┤2                ├┤1              ├┤ UCRZ(pi/4) ├┤ H ├
«         └─────────────────┘└───────────────┘└────────────┘└───┘
Siehe auch

Die grover_operator() implementiert dieselbe Funktionalität, hält aber die MCXGate abstrakt, so dass der Compiler die optimale Dekomposition wählen kann. Wir empfehlen die Verwendung von grover_operator() zu verwenden, die die Schaltung nicht in ein undurchsichtiges Gatter verwandelt.

Quellenangaben:

[1] L. K. Grover (1996), A fast quantum mechanical algorithm for database search, arXiv:quant-ph/9605043.

[2] I. Chuang & M. Nielsen, Quantum Computation and Quantum Information, Cambridge: Cambridge University Press, 2000. Kapitel 6.1.2.

[3] Brassard, G., Hoyer, P., Mosca, M., & Tapp, A. (2000). Quantenamplitudenverstärkung und -schätzung. arXiv:quant-ph/0005055.

Veraltet seit Version 2.1

Die Klasse qiskit.circuit.library.grover_operator.GroverOperator ist ab Qiskit 2.1 veraltet. Sie wird in Qiskit 3.0 entfernt. Verwenden Sie stattdessen qiskit.circuit.library.grover_operator.

Parameter

  • oracle (QuantumCircuit |Statevector) – Das Phasenorakel, das eine Reflexion über den fehlerhaften Zustand implementiert. Beachten Sie, dass es sich hierbei nicht um ein Bitflip-Orakel handelt; weitere Informationen finden Sie im Docstring.
  • state_preparation (QuantumCircuit | None) – Der Bediener bereitet den guten und den schlechten Zustand vor. Beim Grover-Algorithmus handelt es sich um ein n-Qubit-Hadamard-Gatter, und zur Amplitudenverstärkung oder -schätzung wird der Operator A\mathcal{A} verwendet.
  • zero_reflection (QuantumCircuit |DensityMatrix |Operator | None) – Die Überlegungen zum Nullzustand, S0\mathcal{S}_0.
  • reflection_qubits (list[int] | None) – Qubits, auf die die Nullreflexion wirkt.
  • insert_barriers (bool) – Ob Barrieren zwischen den Reflexionen und A eingefügt werden sollen.
  • mcx_mode (str) – Der zu verwendende Modus für die Erstellung der Standard-Null-Reflexion.
  • name (str) – Der Name des Stromkreises.

Attribute

oracle

Das Orakel führt eine Reflexion über den schlechten Zustand durch.

reflection_qubits

Reflexionsqubits, auf die S0 angewendet wird (wenn S0 nicht vom Benutzer angegeben wird).

state_preparation

Der Teilschaltkreis, der den A-Operator oder Hadamards implementiert.

zero_reflection

Der Teilstromkreis, der die Reflexion um 0.

name

Typ: str

Ein von Menschen lesbarer Name für den Stromkreis.

Beispiel

from qiskit import QuantumCircuit

qc = QuantumCircuit(2, 2, name="my_circuit")
print(qc.name)
my_circuit
War diese Seite hilfreich?
Melden Sie auf GitHub einen Fehler, einen Tippfehler oder fordern Sie Inhalte an.