qalgora-Q Docs Hub量子文档 ✦ Ask AI✦ 问问文档

Deutsch's Algorithm

Historically the first algorithm to demonstrate a quantum speedup: with a single oracle query, decide whether a one-bit function is constant or balanced — where a classical deterministic algorithm must query twice. Deutsch's algorithm needs a single oracle query and is always correct.

The problem it solves

Consider a Boolean function f that takes one bit in and returns one bit out. There are only four such functions, and they fall into two classes:

ClassFunctionsSignature
Constantf(x)=0 or f(x)=1both inputs give the same output
Balancedf(x)=x or f(x)=1⊕xthe two inputs give different outputs

We do not care which specific function f is — only which class it belongs to. Classically, knowing f(0) alone (or f(1) alone) settles nothing: you must learn both values and compare them. A classical deterministic algorithm therefore needs 2 queries; Deutsch's algorithm needs just 1 oracle query, and is always correct.

Intuition — asking for a global property in one question

The key realisation is that "constant vs. balanced" is a global property: it depends only on the parity (XOR) of the two values, f(0)⊕f(1). A constant function has parity 0; a balanced function has parity 1. A classical circuit can only probe the function at one point per query, so it can never read out this global parity directly.

A quantum circuit can feed both inputs through the oracle in superposition at once, then use interference to collect "the difference between the two points" into a single measurement. Instead of evaluating the function point by point, we ask directly: "are these two points the same or not?"

Why it works — phase kickback

The trick is to prepare the auxiliary qubit in the state |−⟩ = (|0⟩ − |1⟩)/√2 (the code does this with an x followed by an h). When the reversible oracle |x⟩|y⟩ → |x⟩|y⊕f(x)⟩ acts on |−⟩, something elegant happens: the XOR no longer flips the auxiliary qubit, but instead kicks back a phase of (−1)f(x) onto the data qubit:

|x⟩|−⟩ → (−1)f(x) |x⟩|−⟩

So the data qubit goes from (|0⟩+|1⟩)/√2 to ((−1)f(0)|0⟩ + (−1)f(1)|1⟩)/√2. The relative phase between the two components encodes exactly the parity f(0)⊕f(1) we are after:

  • If f(0)=f(1) (constant), the two phases agree and the state is proportional to |0⟩+|1⟩ = |+⟩.
  • If f(0)≠f(1) (balanced), the two phases differ and the state is proportional to |0⟩−|1⟩ = |−⟩.

A final Hadamard on the data qubit maps |+⟩ back to |0⟩ and |−⟩ back to |1⟩. The measurement is therefore deterministic: read 0 for constant, read 1 for balanced.

The mechanism

StepRole
Prepare |−⟩ auxiliaryConverts the oracle's output XOR into a kick-backable phase rather than an actual flip of the auxiliary qubit.
Superpose the data qubitLets the oracle act on |0⟩ and |1⟩ "at once", folding both values of f into one state.
Phase kickbackWrites (−1)f(x) into the relative phase of the data qubit's components.
Closing Hadamard interferenceTranslates the phase difference into a readable 0/1, interfering constant and balanced onto different measurement basis states.
The oracle never reveals f itself
We never read out either f(0) or f(1) individually. The algorithm extracts only their parity — a global relationship. That is precisely why it wins with fewer queries: it asks a smarter question, not one that "sees more".

What it shows — and what it doesn't

  • A toy, but a genuine one. Deutsch's algorithm has no practical use of its own, but it is the first clean proof that quantum can solve a problem with fewer queries — the advantage is in query complexity, not runtime or memory.
  • The advantage is deterministic. There is no probabilistic trade-off here: a classical deterministic algorithm needs 2 queries, quantum needs 1, and it is right every time.
  • It generalises. Extended to an n-bit function (promised constant or balanced) it becomes the Deutsch–Jozsa algorithm: classically up to 2n−1+1 queries in the worst case, quantum still just 1 — from exponential to constant. (This compares against deterministic/exact classical algorithms; a bounded-error randomized classical algorithm also needs only a constant number of queries.)
  • It breaks nothing. The real legacy is phase kickback itself — Bernstein–Vazirani, Simon, and even Grover all reuse it.

The algorithm, step by step

  1. Prepare the auxiliary qubit in |−⟩ (flip with x, then h).
  2. Apply h to the data qubit to make the |+⟩ superposition.
  3. Call the oracle; via phase kickback, the parity f(0)⊕f(1) is written into the data qubit's relative phase.
  4. Apply h again to the data qubit, turning the phase difference into a computational 0 or 1.
  5. Measure: 0 ⇒ constant, 1 ⇒ balanced.

Seeing it in code

Read it line by line against the theory above: x(q[1]) followed by h(q[1]) prepares the auxiliary qubit in |−⟩; h(q[0]) superposes the data qubit; when oracle_balanced=True is passed, the x.ctrl(q[0], q[1]) CNOT is the balanced oracle f(x)=x, and it is what triggers phase kickback; the closing h(q[0]) completes the interference so that mz(q[0]) reports the function's class deterministically.

The example only demonstrates the constant oracle f(x)=0 and the balanced oracle f(x)=x. To realize f(x)=1, add one x(q[1]) on the auxiliary qubit in the oracle; to realize f(x)=1⊕x, add an auxiliary flip on top of the CNOT. Whichever constant or balanced oracle you pick, the measurement still stabilizes to 0 (constant) or 1 (balanced) respectively.

import qalgora

@qalgora.kernel
def deutsch(oracle_balanced: bool):
    q = qalgora.qvector(2)
    x(q[1])
    h(q[0]); h(q[1])
    if oracle_balanced:          # f(x) = x  ->  CNOT oracle
        x.ctrl(q[0], q[1])
    h(q[0])
    mz(q[0])                     # 0 => constant, 1 => balanced

print(qalgora.sample(deutsch, True))    # balanced -> always 1
print(qalgora.sample(deutsch, False))   # constant -> always 0
Try it yourself
Swap in the other balanced function f(x)=1⊕x (add an extra x on q[1] after the CNOT) and confirm the result still locks to 1. Then try the two constant oracles — you will see the qubit's counts always collapse to a single deterministic peak, a direct demonstration of interference being exact.

References

  • D. Deutsch, "Quantum theory, the Church-Turing principle and the universal quantum computer," Proc. R. Soc. Lond. A 400, 97-117 (1985). doi:10.1098/rspa.1985.0070

Deutsch 算法

历史上第一个展示量子加速的算法:仅凭一次谕示(oracle)查询,就能判断一个一比特函数是常值还是平衡——而经典确定性算法必须查询两次。

它解决的问题

设想一个布尔函数 f,输入一个比特、输出一个比特。它只可能是以下四种之一,并被划入两类:

类型函数特征
常值f(x)=0 或 f(x)=1两个输入给出相同输出
平衡f(x)=x 或 f(x)=1⊕x两个输入给出不同输出

我们不关心 f 具体是哪一个,只想知道它属于哪一类。经典上,单看 f(0) 或 f(1) 中任意一个都无法定论——你必须把两个值都问出来,再比较。也就是说,经典确定性算法需要 2 次查询;Deutsch 算法只需 1 次 oracle 查询,并且确定正确。

直觉 一次提问问出全局性质

关键的认识是:常值与平衡的区别其实是一个全局属性——它取决于 f(0) 与 f(1) 的奇偶(异或),即 f(0)⊕f(1)。常值函数该奇偶为 0,平衡函数该奇偶为 1。经典电路一次只能探测函数在某一个点的值,因此无法直接读出这个全局奇偶。

量子电路则可以把两个输入做成叠加同时送入谕示,再用干涉把"两点之差"这一全局信息汇聚到一次测量里。换句话说,我们不去逐点求值,而是直接询问"这两点是否相同"。

为何成立 相位回踢

诀窍在于把辅助比特预备成 |−⟩ = (|0⟩ − |1⟩)/√2 这一状态(代码中先 xh 得到)。当谕示以可逆形式 |x⟩|y⟩ → |x⟩|y⊕f(x)⟩ 作用在 |−⟩ 上时,会发生一件漂亮的事:异或不再改变辅助比特,而是把一个 (−1)f(x) 的相位回踢到数据比特上:

|x⟩|−⟩ → (−1)f(x) |x⟩|−⟩

于是数据比特从 (|0⟩+|1⟩)/√2 变成 ((−1)f(0)|0⟩ + (−1)f(1)|1⟩)/√2。两个分量的相对相位恰好编码了我们想要的奇偶 f(0)⊕f(1):

  • 若 f(0)=f(1)(常值),两相位同号,状态正比于 |0⟩+|1⟩ = |+⟩
  • 若 f(0)≠f(1)(平衡),两相位反号,状态正比于 |0⟩−|1⟩ = |−⟩

最后再对数据比特施加一个 Hadamard:它把 |+⟩ 映回 |0⟩、把 |−⟩ 映回 |1⟩。因此测量结果是确定的——读到 0 就是常值,读到 1 就是平衡。

核心机制

步骤作用
制备 |−⟩ 辅助比特把谕示的输出"异或"转化为一个可回踢的相位,而非真正翻转辅助比特。
数据比特叠加令谕示在 |0⟩|1⟩ 上"同时"作用,把 f 的两个取值并入同一状态。
相位回踢把 (−1)f(x) 写进数据比特各分量的相对相位。
末端 Hadamard 干涉将相位差转译为可读的 0/1,让常值与平衡彼此干涉到不同的测量基矢上。
谕示并不泄露 f 本身
我们从未读出 f(0) 或 f(1) 中任何一个具体值。算法只提取了二者的奇偶这一全局关系。这正是它能用更少查询取胜的原因:它问的问题"更聪明",而非"看得更多"。

它能说明什么 又不能说明什么

  • 它是一个玩具,但意义真实。Deutsch 算法本身没有实用价值,但它是第一个干净地证明"量子能用更少查询解决问题"的范例——优势体现在查询复杂度,而非运行时间或内存。
  • 优势是确定性的。这里没有概率取舍:经典确定性算法需要 2 次、量子只需 1 次,每次都对。
  • 它会推广。把它扩展到 n 比特函数(保证常值或平衡),就得到 Deutsch–Jozsa 算法:经典最坏需 2n−1+1 次查询,量子仍只需 1 次——从指数到常数。(此处对照的是确定性/精确经典算法;若允许有界误差的随机经典算法,则经典亦仅需常数次查询。)
  • 它不"破解"任何东西。相位回踢这套手法才是真正的遗产——Bernstein–Vazirani、Simon、乃至 Grover 都在复用它。

算法逐步拆解

  1. 把辅助比特预备为 |−⟩(先 x 翻转、再 h)。
  2. 对数据比特施加 h,制备 |+⟩ 叠加。
  3. 调用谕示;通过相位回踢,奇偶 f(0)⊕f(1) 被写入数据比特的相对相位。
  4. 对数据比特再施加 h,把相位差转为计算基上的 0 或 1。
  5. 测量:0 ⇒ 常值,1 ⇒ 平衡。

对照代码理解

请逐行对照上文原理来读:x(q[1])h(q[1]) 把辅助比特制成 |−⟩h(q[0]) 给数据比特制备叠加;当传入 oracle_balanced=True 时,x.ctrl(q[0], q[1]) 这条 CNOT 就是平衡谕示 f(x)=x,正是它触发了相位回踢;末端的 h(q[0]) 完成干涉,使 mz(q[0]) 的结果确定地报告函数类别。

示例代码只演示了常值函数 f(x)=0 与平衡函数 f(x)=x。若要实现 f(x)=1,可在 oracle 中对辅助比特加一次 x(q[1]);若要实现 f(x)=1⊕x,可在 CNOT 基础上加入一次辅助比特翻转。无论选择哪一个常值或平衡 oracle,最终测量结果仍分别稳定为 0 或 1。

import qalgora

@qalgora.kernel
def deutsch(oracle_balanced: bool):
    q = qalgora.qvector(2)
    x(q[1])
    h(q[0]); h(q[1])
    if oracle_balanced:          # f(x) = x  ->  CNOT oracle
        x.ctrl(q[0], q[1])
    h(q[0])
    mz(q[0])                     # 0 => constant, 1 => balanced

print(qalgora.sample(deutsch, True))    # balanced -> always 1
print(qalgora.sample(deutsch, False))   # constant -> always 0
动手试试
把谕示换成另一个平衡函数 f(x)=1⊕x(在 CNOT 后对 q[1] 多加一个 x),确认结果仍稳定为 1。再试两个常值谕示——你会发现量子比特的计数始终聚成单一确定峰,这正是干涉确定性的直接体现。

参考文献

  • D. Deutsch, "Quantum theory, the Church-Turing principle and the universal quantum computer," Proc. R. Soc. Lond. A 400, 97-117 (1985). doi:10.1098/rspa.1985.0070