7 Grover’s search algorithm
This chapter introduces Grover’s search as a practical example of the hybrid quantum–classical workflow for solving classical problems on a quantum computer. It frames unstructured search as finding any n-bit input x such that a deterministic function f(x)=1, with access only through an oracle, and motivates why many tasks (notably constraint satisfaction) can be reduced to this model. The chapter emphasizes an end-to-end mindset: classical preprocessing to build the problem instance, a quantum subroutine to gain speedup, and classical post-processing to validate or iterate, with later chapters applying and benchmarking the approach on richer problems.
The core abstraction is the quantum oracle. Two forms are used: marking oracles, which act on n+1 qubits and flip a target qubit when f(x)=1, and phase oracles, which act on n qubits and multiply marked basis states by −1. Because algorithms typically need phase oracles while implementations are often easier as marking oracles, the chapter shows how to convert between them via phase kickback. It provides compact Qiskit and Q# patterns to build marking oracles for “marked-list” functions, to realize phase oracles with a single auxiliary qubit, and to unit test them: compare matrices for phase oracles (diagonal ±1) and compare action against a classical function for marking oracles. These pieces set up the building blocks required by Grover’s search.
Grover’s algorithm prepares an equal superposition over the search space (“mean”), then repeats two reflections: a phase flip of the solutions (the oracle) and a reflection about the mean (the “diffusion” step). Geometrically, each iteration rotates the state toward the solutions by 2θ, where sin θ=√(M/N). The success probability rises, peaks, then oscillates, so the iteration count matters: the optimal number is about (π/4)√(N/M). If M is unknown, simple heuristics (e.g., doubling the iteration count across runs) work well, and results should be verified classically since Grover is probabilistic. Compared with random classical querying (≈N/M checks), Grover achieves a quadratic asymptotic speedup (≈√(N/M) oracle calls). The chapter gives Qiskit and Q# implementations that assemble the iteration from a phase oracle and the mean-preparation operator, outlines end-to-end testing (including deterministic cases like M/N=1/4 with one iteration), and tees up applications (such as N queens) and performance analysis in subsequent chapters.
Solving a classical problem on a quantum computer involves converting the problem to its “quantum” formulation, implementing the quantum algorithm as code, and evaluating the performance of the quantum solution to compare it to that of the classical algorithms for solving the same problem.
A quantum algorithm can combine classical and quantum computations. Typically, it starts with a classical data preprocessing step that prepares input data for the quantum computation and passes it to the quantum subroutine. The results of the quantum computation are then fed into another classical step, post-processing, that converts them into the final problem solution. Some of these steps can be omitted for simple algorithms or repeated with some variation for iterative algorithms.
The effect of the phase oracle for the function that marks values \(001\) and \(110\) on a superposition state with real amplitudes. The amplitudes of the basis states that correspond to the marked values (striped bars) are multiplied by \(-1\). The rest of the amplitudes do not change.
The effect of the marking oracle for the function that marks values \(001\) and \(110\) on a superposition state with real amplitudes. For each marked value, there are two basis states with the input qubits in the corresponding state (marked with striped bars): for one of them, the target qubit is in the \(\ket{0}\) state, and for the other one — in the \(\ket{1}\) state. The amplitudes of these pairs of basis states are swapped. The rest of the amplitudes do not change.
The main states used in Grover’s search algorithm. \(\ket{\textrm{mean}}\) is the superposition of all basis states in the search space (that is, states that correspond to bit strings that are potential solutions to the problem). These bit strings can be split in two groups: the ones that are solutions (included in the superposition \(\ket{\textrm{solutions}}\)) and the ones that are not (\(\ket{\textrm{non-solutions}}\)). The angle \(\theta\) is defined by the number of problem solutions and the size of the search space.
The main operations used in Grover’s search algorithm. Applying the phase oracle reflects the system state about the horizontal axis, the average of all non-solutions. “Reflection about the mean” reflects the system state about the mean state, the average of all states in the search space. Together, these two operations rotate the state of the system counterclockwise by a fixed angle.
The overall structure of Grover’s search algorithm. You start by preparing the system in the mean state, the average of all states in the search space. Then you apply several iterations, each composed of applying the phase oracle followed by a reflection about the mean. Finally, you measure the system and check whether the result is an answer to the problem.
Each iteration of Grover’s algorithm rotates the state of the system in counterclockwise direction by the angle \(2\theta\). Up to a certain point, each iteration rotates the state closer to the vertical axis, the \(\ket{\textrm{solutions}}\) state. The closer the state is to \(\ket{\textrm{solutions}}\), the higher the probability of the measurement yielding a correct answer is. If you apply too many iterations (in this case, three or more), the state will go beyond vertical, and further iterations will decrease success probability.
Summary
- Programs that utilize quantum algorithms are often hybrid: they combine quantum computations with classical preprocessing for preparing the inputs to the quantum subroutine and post-processing for interpreting its outputs and producing the final answer or making decisions about the next computation to run.
- Unstructured search problem gives you a deterministic function that converts an input bit string into a single bit \(0\) or \(1\). Your goal is to find an input \(x_0\) for which the value of the function \(f(x_0) = 1\).
- An oracle is a tool that allows you to calculate the function for any given input but does not expose any information about the internal implementation of that function. Oracles are used in both classical and quantum computing to discuss generic algorithms that do not depend on the specific problem instance.
- Phase oracles encode the values of the functions in the signs of amplitudes of the input basis states.
- Marking oracles encode the values of the functions in the state of an additional qubit.
- You can convert a marking oracle into a phase oracle and vice versa using variants of the phase kickback trick.
- Grover’s search algorithm can solve the unstructured search problem for a function given as a quantum oracle. It offers a quadratic speedup in the number of queries to the quantum oracle compared to the “bruteforce” classical algorithm that has access to the function only via a classical oracle.
- Grover’s algorithm is a probabilistic algorithm; it produces the correct result with high probability, but not in \(100%\) of cases. You need to validate the answer \(x_0\) it gives you by calculating the value \(f(x_0)\) using a classical computation and checking that it is indeed \(1\).
FAQ
What problem does Grover’s algorithm solve?
Grover’s algorithm solves the unstructured search problem: given a deterministic Boolean function f(x) accessible only via an oracle, find any input x0 such that f(x0) = 1 using as few queries as possible. It achieves a quadratic asymptotic speedup over the best classical random search: about (π/4)·√(N/M) oracle calls versus N/M classically, where N is the search-space size and M is the number of solutions.How does Grover’s algorithm work at a high level?
It starts in the “mean” state (equal superposition over the search space), then repeats K iterations, each composed of (1) applying the phase oracle U_f that flips the phase of solution states, and (2) a reflection about the mean. Each iteration is a rotation by 2θ in the 2D subspace spanned by |solutions⟩ and |non-solutions⟩, amplifying solution amplitudes. A final measurement yields a solution with high probability if K is chosen near-optimal.What’s the difference between marking oracles and phase oracles?
- Phase oracle (n qubits): encodes f(x) in phase, U_p|x⟩ = (−1)^{f(x)}|x⟩. It leaves basis states intact except possibly a sign flip.- Marking oracle (n+1 qubits): uses an extra target qubit y and flips it when f(x)=1, U_m|x⟩|y⟩ = |x⟩|y ⊕ f(x)⟩. Marking oracles are often easier to implement from reversible classical logic; many algorithms (including Grover) prefer the phase form.
How do I convert a marking oracle into a phase oracle (phase kickback)?
Prepare an ancilla in |−⟩ = (|0⟩ − |1⟩)/√2 and apply the marking oracle U_m to (input, ancilla). Because X acting on |−⟩ adds a −1 phase, the ancilla is unchanged and the input picks up (−1)^{f(x)}: U_m|x⟩|−⟩ = (−1)^{f(x)}|x⟩|−⟩. You can then discard (or reuse) the ancilla; in Q# it can be released, in Qiskit it typically remains as part of the circuit.Can I convert a phase oracle back into a marking oracle?
Yes, if you have a controlled version of the phase oracle. Steps for input |x⟩|0⟩: (1) apply H to the target, (2) apply controlled-U_p with the target as control and the input as target, (3) apply H to the target again. The target ends as |f(x)⟩, producing the behavior of a marking oracle.What is the “mean” state and how is the search space chosen?
The mean is the equal superposition over all states in the chosen search space: |mean⟩ = (1/√N) Σ_x |x⟩. Often the search space is all n-bit strings (N=2^n), prepared by applying H to each qubit. If the problem has structure, you can restrict the search space to valid candidates to reduce N, simplify the oracle, and speed up the algorithm.How many iterations should I run?
Let sin θ = √(M/N). Each iteration rotates the state by 2θ; after K iterations, the angle from |non-solutions⟩ is (2K+1)θ. The optimum is near (2K+1)θ ≈ π/2, giving K ≈ (π/4)√(N/M) when M ≪ N. Using too many iterations overshoots and reduces success probability; it oscillates with K.What if I don’t know the number of solutions M?
- Use an estimate of M to pick K; success probability is often robust to small errors.- If no estimate is available, use a doubling (exponential) schedule: run with 1, 2, 4, … iterations until a valid solution is found. This adds only a small overhead compared to the optimum K.
Is Grover’s algorithm always the right choice?
No. If the fraction of solutions p = M/N is large, simple classical Monte Carlo (pick random x and test f(x)) finds a solution in O(1/p) trials and is typically faster in practice. Also, Grover offers only quadratic asymptotic speedup and involves slow quantum oracles; practical advantage depends on constant factors and the cost to implement the oracle.What are key implementation and testing tips (Q# and Qiskit)?
- Phase-oracle matrix: diagonal with ±1 entries on the main diagonal (−1 where f(x)=1).- Marking→phase in Qiskit: the ancilla used for phase kickback stays in the circuit; the overall unitary is block-diagonal diag(U_p, I) with respect to the ancilla basis. In Q#, the ancilla can be allocated, uncomputed, and released.
- Reflection-about-mean: implement as V (2|0⟩⟨0| − I) V† where V prepares |mean⟩ from |0…0⟩; realize 2|0⟩⟨0| − I via X…X, multi-controlled Z, then uncompute X…X.
- Testing oracles: for phase oracles, compare extracted matrices to the expected diagonal; for marking oracles, compare action against classical f(x).
- Testing end-to-end Grover: run multiple shots; verify outputs satisfy f(x)=1. Use deterministic cases (e.g., M/N = 1/4 → one iteration yields 100% success) to catch bugs such as bit-ordering (endianness) errors.
Quantum Programming in Depth ebook for free