量子搜索算法(Grover Algorithm)

量子搜索算法(Grover Algorithm)GroverAlgori 一 背景介绍二 具体内涵一 背景介绍遍历搜寻问题的任务是从一个海量元素的无序集合中 找到满足某种要求的元素 要验证给定元素是否满足要求很容易 但反过来查找这些合乎要求的元素则很费事 因为这些元素并没有按要求进行有序的排列 并且数量又很大 在经典算法中 只能按逐个元素试下去 这也正是 遍历搜寻 这一名称的由来 量子计算机比传统计算机具有的众多优势之一是其优越的速度搜索数据库 Grover 的算法证明了这种能力 该算法可以二次加速非结构化搜索问题 但其用途远不止于

一 . 背景介绍

遍历搜寻问题的任务是从一个海量元素的无序集合中,找到满足某种要求的元素。要验证给定元素是否满足要求很容易,但反过来查找这些合乎要求的元素则很费事,因为这些元素并没有按要求进行有序的排列,并且数量又很大。在经典算法中,只能按逐个元素试下去,这也正是“遍历搜寻”这一名称的由来!

量子计算机比传统计算机具有的众多优势之一是其优越的速度搜索数据库。Grover的算法证明了这种能力。该算法可以二次加速非结构化搜索问题,但其用途远不止于此。它可以用作一般技巧或子例程,以获得各种其他算法的二次运行时间改进。这称为幅度放大技巧!

什么是非结构化搜索?

在这里插入图片描述
在上述大量排成一行的数据中,我们希望找到类似于图中紫色框代表的数据,当然,也有可能不止一个,要使用经典计算找到紫色框(标记项),则平均要检查 N 2 \frac{N}{2} 2N这些框,最坏的情况是检查所有 N − 1 N-1 N1 个元素。 但是,在量子计算机上,我们可以使用Grover的幅度放大技巧以大约 N \sqrt{N} N
的步长找到标记的项目。 二次加速确实是节省长列表中标记项目的大量时间。 另外,该算法不使用列表的内部结构,这使其具有通用性。 这就是为什么它立即为许多经典问题提供了二次量子加速的原因!

二 . 算法推导与实现

1. 构造叠加态

假设被查找的集合为: { ∣ i ⟩ } = { ∣ 0 ⟩ , ∣ 1 ⟩ , ⋯ ∣ N − 1 ⟩ } \{|i\rangle\}=\{|\boldsymbol{0}\rangle,|\mathbf{1}\rangle, \cdots|N-\mathbf{1}\rangle\} {
i}=
{
0,1,N
1}
,在开始查找之前,要对系统进行初始化,即对每一个 q u b i t qubit qubit 初态进行 H a d a m a r d Hadamard Hadamard 变换,使之处于 ∣ φ 0 ⟩ = 1 N ∑ i = 0 N − 1 ∣ i ⟩ \left|\varphi_{0}\right\rangle=\frac{1}{\sqrt{N}} \sum_{i=0}^{N-1}|i\rangle φ0=N
1
i=0N1i

牢记这个式子,后面都需要用上它!

这里我们可以通过一个小例子来理解:假设有一个映射 0 , 1 , 2 , … , N ↦ { 0 , 1 } 0,1,2, \ldots, N \mapsto\{0,1\} 0,1,2,,N{
0,1}
,意思就是该映射函数为: f ( x ) ↦ { 0 , 1 } f(x) \mapsto\{0,1\} f(x){
0,1}

f ( 1 ) = 0 f ( 2 ) = 1 f ( 3 ) = 0 f ( 4 ) = 1 \begin{array}{l} f(1)=0 \\ f(2)=1 \\ f(3)=0 \\ f(4)=1 \end{array} f(1)=0f(2)=1f(3)=0f(4)=1现在我们需要做的就是找到 f ( x ) = 1 f(x)=1 f(x)=1 的解,当然,我们这里是理想化模型,数据搞得少一点也是为了通俗易懂,那么显然,当 x = 2 , 4 x=2,4 x=24的时候,是我们需要的解,回过头来,第一步就是创建叠加态,根据这个例子,创建好的叠加态如下:
∣ ψ ⟩ = 1 2 ( ∣ 00 ⟩ + ∣ 01 ⟩ + ∣ 10 ⟩ + ∣ 11 ⟩ ) |\psi\rangle=\frac{1}{2}(|00\rangle+|01\rangle+|10\rangle+|11\rangle) ψ=21(00+01+10+11)
这里因为输入的数据数量相对来说是比较多的,我们用多体量子态来表示,位数也自然和我们整个输入的数据多少直接相关了!


接下来的一步非常重要,是该算法的第一个关键点所在!

2. 构造 O r a c l e Oracle Oracle

为了将我们需要寻找的数据和其他的数据分开,此时需要一个 O r a c l e Oracle Oracle,,那么分开的标识是什么呢?其实最简单的方法就是将目标值变换相位,也就是增加一个负号,即:
O ω ∣ x ⟩ = { ∣ x ⟩  if  x ≠ ω − ∣ x ⟩  if  x = ω O_{\omega}|x\rangle=\left\{\begin{aligned} |x\rangle & \text { if } x \neq \omega \\ -|x\rangle & \text { if } x=\omega \end{aligned}\right. Oωx={
xx if x=ω if x=ω

非常的简单,当遍历不是我们需要的值就不动,反之当找到 x = ω x=\omega x=ω时变号,这个就有点难,因为不仅需要我们构造类似于一个单位阵一样的算符,且能在指定位置变号! I n In In f a c t fact fact, i t ′ s it’s its v e r y very very s i m p l e simple simple:
O ^ = 1 − 2 ∣ x ⟩ ⟨ x ∣ \hat{O}=1-2|x\rangle\langle x| O^=12xx
也阔以写成矩阵的形式,如果是双量子比特的话, L i k e Like Like t h i s : this: this:
在这里插入图片描述


显然,这里我们需要找的是 ∣ 10 ⟩ |10\rangle 10,我们发现构成该矩阵的行和列都是对应的向量,那么,如果是三量子比特的话, O O O算符又是啥样的呢?

在这里插入图片描述
感兴趣的小可耐们可以自己动手操作一下!

到这一步,我们似乎能简单的理解了 G r o v e r Grover Grover 搜索算法的强大之处在于它将问题简单化了,也就是根据量子固有的特性将我们需要查找的值与其余值分开了,从另一个角度来说,我们都知道往往去寻找解决问题的答案是非常困难的,而验证解决方案的正确与否相对来说会简单很多,这便是 G r o v e r Grover Grover算法的思想精髓!

好,上述我们已经成功的得到了置关重要的 O r a c l e Oracle Oracle,进一步,可以得到:

O ω ∣ x ⟩ = ( − 1 ) f ( x ) ∣ x ⟩ O_{\omega}|x\rangle=(-1)^{f(x)}|x\rangle Oωx=(1)f(x)x
道理是一样的,即 f ( x ) = 1 f(x)=1 f(x)=1时变号,等于0时不变,同样的矩阵表示为:
O ω = [ ( − 1 ) f ( 0 ) 0 ⋯ 0 0 ( − 1 ) f ( 1 ) ⋯ 0 ⋮ 0 ⋱ ⋮ 0 0 ⋯ ( − 1 ) f ( 2 n ) ] O_{\omega}=\left[\begin{array}{cccc} (-1)^{f(0)} & 0 & \cdots & 0 \\ 0 & (-1)^{f(1)} & \cdots & 0 \\ \vdots & 0 & \ddots & \vdots \\ 0 & 0 & \cdots & (-1)^{f\left(2^{n}\right)} \end{array}\right] Oω=(1)f(0)000(1)f(1)0000(1)f(2n)

3. 构造 G G G 算子

其实算法的主要过程只有两个步骤,第一步刚刚已经顺利实现,而接下来的第二步才是灵魂!

我们接下里需要构建 G G G算子:

G = ( 2 ∣ ψ ⟩ ⟨ ψ ∣ − I ) O G=(2|\psi\rangle\langle\psi|-I) O G=(2ψψI)O

其中, O O O就是上面说的 O r a c l e Oracle Oracle算符, I I I为单位算符,现把算符 G G G反复作用在 ∣ φ 0 ⟩ |\varphi_{0}\rangle φ0上,并称一次作用为一次“迭代”,根据情况的不同,通过多次次数不同的“迭代”,最终就能找到我们需要的 ω \omega ω了,具体的操作又是怎样的呢?

稍微变形一下可以得到: ∣ β ⟩ = 1 M ∑ x ∣ x ⟩ ∣ α ⟩ = 1 N − M ∑ x ∣ x ⟩ \begin{array}{c} |\beta\rangle=\frac{1}{\sqrt{M}} \sum_{x}|x\rangle \\ |\alpha\rangle=\frac{1}{\sqrt{N-M}} \sum_{x}|x\rangle \end{array} β=M
1
xx
α=NM
1
xx

其中,我们应当知道 N = 2 n N = 2^{n} N=2n,最终的得到: ∣ ψ ⟩ = N − M N ∣ α ⟩ + M N ∣ β ⟩ |\psi\rangle=\sqrt{\frac{N-M}{N}}|\alpha\rangle+\sqrt{\frac{M}{N}}|\beta\rangle ψ=NNM
α+
NM
β

可以结合我们博客开头举得小例子强化理解:

∣ 00 ⟩ → 0 ∣ 01 ⟩ → 1 ∣ 10 ⟩ → 0 ∣ 11 ⟩ → 1 ∣ α ⟩ = 1 2 ( ∣ 00 ⟩ + ∣ 10 ⟩ ) ∣ β ⟩ = 1 2 ( ∣ 01 ⟩ + ∣ 11 ⟩ ) \begin{array}{l} |00\rangle \rightarrow 0 \\ |01\rangle \rightarrow 1 \\ |10\rangle \rightarrow 0 \\ |11\rangle \rightarrow 1 \\ |\alpha\rangle=\frac{1}{\sqrt{2}}(|00\rangle+|10\rangle) \\ |\beta\rangle=\frac{1}{\sqrt{2}}(|01\rangle+|11\rangle) \end{array} 000011100111α=2
1
(00+10)
β=2
1
(01+11)

4. G G G 的应用

先将 O O O算符作用在初始量子叠加态上以实现我们分开的目的,系数分别用 a , b a,b ab来表示:
O ( a ∣ α ⟩ + b ∣ β ⟩ ) = a ∣ α ⟩ − b ∣ β ⟩ O(a|\alpha\rangle+b|\beta\rangle)=a|\alpha\rangle-b|\beta\rangle O(aα+bβ)=aαbβ
我们通常状况下可以假设: a = cos ⁡ ( θ / 2 ) = ( N − M ) / N , b = sin ⁡ ( θ / 2 ) = M / N a=\cos (\theta / 2)=\sqrt{(N-M) / N}, b=\sin (\theta / 2)=\sqrt{M / N} a=cos(θ/2)=(NM)/N
,b=
sin(θ/2)=M/N


问题来了,我们这要做的目的到底是什么?为啥要单独将原始叠加态分开呢,仔细观察不难发现,在未使用 O O O 算符之前,我们可以将 ∣ ψ ⟩ |\psi\rangle ψ 看成一个二维矢量,而分开得到的 ∣ α ⟩ , ∣ β ⟩ |\alpha\rangle ,|\beta\rangle α,β是组成它的二个基矢!看图说话:
在这里插入图片描述
我们从图中可以非常清晰的看到, O O O 算子作用到 ∣ ψ ⟩ |\psi\rangle ψ 上变相之后关于 ∣ α ⟩ |\alpha\rangle α 对称之后得到 O ∣ ψ ⟩ O|\psi\rangle Oψ,再关于原来的 ∣ ψ ⟩ |\psi\rangle ψ对称得到 G ∣ ψ ⟩ G|\psi\rangle Gψ,这两步相当于我们用准备好的 G G G算子进行一次迭代作用,得到的新矢量为:
G ∣ ψ ⟩ = cos ⁡ ( 3 θ 2 ) ∣ α ⟩ + sin ⁡ ( 3 θ 2 ) ∣ β ⟩ G|\psi\rangle=\cos \left(\frac{3 \theta}{2}\right)|\alpha\rangle+\sin \left(\frac{3 \theta}{2}\right)|\beta\rangle Gψ=cos(23θ)α+sin(23θ)β


这是第一次的迭代结果,当次数增多时,数学表达为:

G k ∣ ψ ⟩ = cos ⁡ ( 2 k + 1 2 θ ) ∣ α ⟩ + sin ⁡ ( 2 k + 1 2 θ ) ∣ β ⟩ G^{k}|\psi\rangle=\cos \left(\frac{2 k+1}{2} \theta\right)|\alpha\rangle+\sin \left(\frac{2 k+1}{2} \theta\right)|\beta\rangle Gkψ=cos(22k+1θ)α+sin(22k+1θ)β

这样多次迭代的目的也是显而易见的,就是让我们的 ∣ ψ ⟩ |\psi\rangle ψ 能够不断的向 ∣ β ⟩ |\beta\rangle β 靠近,最终就能得到我们想要的 ∣ β ⟩ |\beta\rangle β 了。

我们还可以从振幅的角度来理解这个算法的核心,并且搭配二维坐标系的翻转过程,配合食用,效果更佳哦(这里的 U U U就是 O O O算符):
在这里插入图片描述
其中虚线代表振幅的平均值,使用 O O O 算符作用之后,我们得到的结果为:
在这里插入图片描述
相位变换以后,显然,振幅的平均值下降了一些,接下来:
在这里插入图片描述
上一步我们根据各个基态的振幅值计算出平均值之后,根据均值的镜像翻转各个基态的振幅值就会得到上面的图片!





5. 临界条件

我们完全有理由认为如果迭代次数过多,会导致 ∣ ψ ⟩ |\psi\rangle ψ 翻转到 ∣ β ⟩ |\beta\rangle β 的右边,增加误差,除此之外,我们还应当想到的就是这个翻转角度 θ \theta θ ,过大的话也会导致误差过大。

现在回过头来看这个式子: ∣ ψ ⟩ = N − M N ∣ α ⟩ + M N ∣ β ⟩ |\psi\rangle=\sqrt{\frac{N-M}{N}}|\alpha\rangle+\sqrt{\frac{M}{N}}|\beta\rangle ψ=NNM
α+
NM
β
,其中 N N N 是我们早已确定的,不能更改, 关键就在于这个 M M M,先假设我们已经知道有 M M M i i i 使得 f ( i ) = 1 f(i) = 1 f(i)=1,根据 a = cos ⁡ ( θ / 2 ) = ( N − M ) / N , b = sin ⁡ ( θ / 2 ) = M / N a=\cos (\theta / 2)=\sqrt{(N-M) / N}, b=\sin (\theta / 2)=\sqrt{M / N} a=cos(θ/2)=(NM)/N
,b=
sin(θ/2)=M/N
,就能直接得到 θ \theta θ 的大小!

我们可以根据, M , N , θ M,N,\theta M,Nθ 的值算出需要迭代的次数:
sin ⁡ ( θ ) = 2 M ( N − M ) N → R = C I ( arccos ⁡ ( M / N ) θ ) \sin (\theta)=\frac{2 \sqrt{M(N-M)}}{N} \rightarrow R=C I\left(\frac{\arccos (\sqrt{M / N})}{\theta}\right) sin(θ)=N2M(NM)
R=CI(θarccos(M/N
)
)

其中 R R R 就是我们需要迭代的次数,例如: C I ( 4.5 ) = 4 C I(4.5)=4 CI(4.5)=4

除此之外,隐藏条件 θ < π 2 \theta<\frac{\pi}{2} θ<2π 也是需要知道的,而且当 θ \theta θ 越小时,我们得到的搜索结果越准确!

如果当我们需要搜所的值个数 M M M 非常少的话,即 M ≪ N → θ ≈ sin ⁡ ( θ ) ≈ 2 M / N M \ll N \rightarrow \theta \approx \sin (\theta) \approx 2 \sqrt{M / N} MNθsin(θ)2M/N
,那么测量的误差角度最大为 θ / 2 ≈ M / N \theta / 2 \approx \sqrt{M / N} θ/2M/N
!

再结合 θ < π 2 \theta<\frac{\pi}{2} θ<2π 可得:
R ⩽ ⌈ π 4 N M ⌉ R \leqslant\left\lceil\frac{\pi}{4} \sqrt{\frac{N}{M}}\right\rceil R4πMN

注意,这里是上天花板函数符号,舍弃小数点后的数字!

最后我们用一张图简单的总结一下量子 G r o v e r Grover Grover 算法的整个流程:

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/220745.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午7:45
下一篇 2026年3月17日 下午7:45


相关推荐

  • 什么是前端架构?[通俗易懂]

    什么是前端架构?[通俗易懂]什么是前端架构

    2025年6月15日
    5
  • 那些长短不一的PCI-E插槽都有什么不一样?

    那些长短不一的PCI-E插槽都有什么不一样?https://www.ednchina.com/news/20171121-PCI-E.html时间:2017-11-21目前PCI-E插槽已经成为了主板上的主力扩展插槽,除了显卡会用到PCI-E插槽外,诸如独立声卡、独立网卡、USB3.0/3.1接口扩展卡以及SSD等硬件都可以使用PCI-E插槽。主板上的扩展插槽曾经是多种多样的,例如曾经非常流行…

    2022年5月30日
    53
  • iframe自适应高度_iframe根据内容自适应高度

    iframe自适应高度_iframe根据内容自适应高度1、iframe自适应页面高度   首先需要给iframe设置一个id,不需要滚动条则加上scrolling=”no”   然后加上一个onload事件functioniFrameHeight(iframe){ varifm=document.getElementById(iframe.id); varsubWeb=document.frames

    2022年10月12日
    5
  • cockpit二次开发_laravel api

    cockpit二次开发_laravel api背景:最近公司要基于cockpit,来定制自己的一个服务器管理web应用。嗯。。cockpit是啥?能干嘛?我要拿它干嘛?如你所见,我此刻是懵逼的。cockpit了解我熟练的打开了百度又打开了bing哦吼,二度懵逼。经过几番了解,大概是知道了LinuxCockpit是一个基于Web界面的应用,它提供了对系统的图形化管理。因为功能集成,对服务器管理来说,可以称得上是神器,深受linux开发者的喜爱。(呵呵。。)最后我大概是知道了,公司就是想让我在人..

    2025年7月27日
    6
  • 别人还在入门,你已经精通!Claude Code进阶必备14招

    别人还在入门,你已经精通!Claude Code进阶必备14招

    2026年3月15日
    2
  • 人工智能 – 五子棋人机对战

    人工智能 – 五子棋人机对战人工智能 – 五子棋人机对战作者:jig    阅读人次:6635    文章来源:本站原创    发布时间:2007-7-12    网友评论(8)条 
    原帖及讨论:http://bbs.bccn.net/thread-154777-1-1.html
    */————————————————————————————–
    */出自:编程中国  http://www.

    2022年6月17日
    38

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号