GroverOperator
class qiskit.circuit.library.GroverOperator(oracle, state_preparation=None, zero_reflection=None, reflection_qubits=None, insert_barriers=False, mcx_mode='noancilla', name='Q')
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, , besteht aus dem Phasenorakel, , der Nullphasenverschiebung oder Nullreflexion, , und einer Eingangszustandsvorbereitung :
In der Standard-Grover-Suche haben wir :
Die Operation 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 ) und dann wird der gesamte Zustand um den Mittelwert gespiegelt (mit ).
Diese Klasse ermöglicht die Festlegung einer anderen Zustandsvorbereitung, wie beispielsweise bei der Quantenamplitudenverstärkung (einer Verallgemeinerung des Grover-Algorithmus); ist möglicherweise keine Schicht aus Hadamard-Gattern [3].
Die Aktion des Phasenorakels ist definiert als
wobei , wenn 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 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 . Bevor der Grover-Operator in Grovers Algorithmus angewendet wird, werden die Qubits zunächst mit einer Anwendung des -Operators (oder Hadamard-Gates in der Standardformulierung) vorbereitet. Wir haben also immer eine Operation der Form . Daher ist es möglich, die Bitflip-Logik in 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 ist normalerweise definiert als
wobei die Identität auf qubits ist. Standardmäßig implementiert diese Klasse die negative Version , 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 ├
« └─────────────────┘└───────────────┘└────────────┘└───┘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.
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 verwendet.
- zero_reflection (QuantumCircuit |DensityMatrix |Operator | None) – Die Überlegungen zum Nullzustand, .
- 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