基于MindSpore Quantum的Grover搜索算法和龙算法

如果你听过量子计算,那么你一定听说过Grover搜索算法。1996年,Lov Grover [1] 提出了Grover搜索算法,它是一种利用量子状态的叠加性进行并行计算并实现加速的算法。Grover搜索算法被公认为是继Shor算法后的第二大量子算法,也是第一个被完整的实验实现的量子算法,它解决的是无序数据库搜索问题。1997年,Bennett [2] 等人证明,对于非结构化的量子搜索问题,至少需要Ω(N−−√)Ω(𝑁)​次量子查询,因此Grover搜索算法对于该问题是渐进意义下的最优算法。

无序数据库搜索问题(Unordered Database Search problem)就是从一个海量元素的无序数据库中,找到某些满足要求的元素。由于数据库中元素的数量是巨大的且这些元素是无序排列的,所以,要验证给定的元素是否满足要求很容易,但反过来,要找到这些元素却不是一件容易的事。

求解无序数据库搜索问题(不妨假设只有一个目标搜索数据),经典算法所需的时间复杂度为O(N)𝑂(𝑁),而Grover搜索算法所需的时间复杂度仅为O(N−−√)𝑂(𝑁),相比经典算法具有平方加速,展示了量子计算的强大性能。此外,Grover搜索算法中用到的振幅扩大技巧,对许多启发式的经典搜索算法可以实现加速,因而具有广泛的应用。

本文档将会介绍Grover搜索算法的基本原理,以及通过两个具体的小例子来展示如何利用MindSpore Quantum实现该算法。

问题描述

我们需要在一组无序的N𝑁元素集合(数据库)中进行搜索。将数据库中的元素与索引(从00到N−1𝑁−1之间的整数)建立一一对应,我们关注于搜索这些元素的索引。考虑将该搜索问题表示为一个关于输入x𝑥的函数f(x)𝑓(𝑥),其中x𝑥为00到N−1𝑁−1之间的整数。那么,函数f𝑓定义为:

f(x)=⎧⎩⎨0,x≠xtarget1,x=xtarget.𝑓(𝑥)={0,𝑥≠𝑥𝑡𝑎𝑟𝑔𝑒𝑡1,𝑥=𝑥𝑡𝑎𝑟𝑔𝑒𝑡.

不失一般性,假设N=2n𝑁=2𝑛​,那么在量子系统中,索引以量子态|0〉,|1〉,...,|N−1〉|0〉,|1〉,...,|𝑁−1〉​(或|00...0〉,|00...1〉,...,|11...1〉|00...0〉,|00...1〉,...,|11...1〉​)表示,也即我们可以使用n𝑛​个量子比特存储这些索引。

同时假设搜索问题只有一个目标态|ω〉|𝜔〉。Grover搜索算法的目标就是以极大的概率将|ω〉|𝜔〉搜索出来。

Grover搜索算法的基本原理

Grover搜索算法的基本原理:首先通过 Hadamard 门产生均匀叠加态,然后反复调用Grover迭代(或称为G𝐺算子),以放大目标项的概率振幅同时抑制非目标项的概率振幅(该方法称之为振幅放大),最后对末态进行测量,那么就能以极大的概率得到目标态|ω〉|𝜔〉​​。

下面介绍Grover算法的主要步骤。

Step 1:数据库初始化

对|0〉⊗n|0〉⊗𝑛​​​​执行H⊗n𝐻⊗𝑛​​​​​操作,使得数据库被初始为一个均匀叠加态,即

|ψ0〉=H⊗n|0〉⊗n=1N−−√∑i=0N−1|i〉.|𝜓0〉=𝐻⊗𝑛|0〉⊗𝑛=1𝑁∑𝑖=0𝑁−1|𝑖〉.

Step 2:Grover迭代

Grover迭代又可以分解为四步:

子步骤一

执行Oracle算子Uω𝑈𝜔​,翻转目标态|ω〉|𝜔〉​​​​​的相位。

为了将需要寻找的数据和其它的数据区别开,最简单的方法就是翻转目标态的相位(增加一个负号),此时我们需要构造一个Oracle算子Uω𝑈𝜔,其作用如下:

Uω|x〉=⎧⎩⎨−|x〉,x≠ω|x〉,x=ω.𝑈𝜔|𝑥〉={|𝑥〉,𝑥≠𝜔−|𝑥〉,𝑥=𝜔.

由于当x=ω𝑥=𝜔​时,f(ω)=1𝑓(𝜔)=1​,那么Uω𝑈𝜔​​的作用还可以表示成:

Uω|x〉=(−1)f(x)|x〉,𝑈𝜔|𝑥〉=(−1)𝑓(𝑥)|𝑥〉,

其矩阵表达式为

Uω=⎡⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢(−1)f(0)0⋮00(−1)f(1)⋮0……⋱…00⋮(−1)f(N−1)⎤⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥.𝑈𝜔=[(−1)𝑓(0)0…00(−1)𝑓(1)…0⋮⋮⋱⋮00…(−1)𝑓(𝑁−1)].

子步骤二

执行H⊗n𝐻⊗𝑛操作。

对n𝑛位量子比特执行H⊗n𝐻⊗𝑛操作。

子步骤三

执行条件相移算子P𝑃。

条件相移算子P𝑃能使|0〉|0〉​态以外的每个态的相位都翻转,其作用如下:

P|x〉=⎧⎩⎨−|0〉,x=0|x〉,x≠0.𝑃|𝑥〉={|0〉,𝑥=0−|𝑥〉,𝑥≠0.

其矩阵表达式为

P=2(|0〉〈0|)⊗n−In=⎡⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢10⋮00−1⋮0……⋱…00⋮−1⎤⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥.𝑃=2(|0〉〈0|)⊗𝑛−𝐼𝑛=[10…00−1…0⋮⋮⋱⋮00…−1].

子步骤四

再次执行H⊗n𝐻⊗𝑛操作。

至此,完整的G𝐺算子可以表示为

G=H⊗n[2(|0〉〈0|)⊗n−In]H⊗nUω.𝐺=𝐻⊗𝑛[2(|0〉〈0|)⊗𝑛−𝐼𝑛]𝐻⊗𝑛𝑈𝜔.

注意:G𝐺算子需要迭代的次数为

r=[π4NM−−−√]∼O(N−−√),𝑟=[𝜋4𝑁𝑀]∼𝑂(𝑁),

其中,M表示目标态的个数。

Step 3:测量

对末态进行|0〉,|1〉|0〉,|1〉基测量,就能以极大的概率得到目标态|ω〉|𝜔〉。

Grover搜索算法的完整量子线路模型如下所示:

grover algorithm circuit

构造翻转量子比特相位的酉算子

通过上述介绍,我们发现,Grover搜索算法中最关键的部分就是存在可以翻转量子比特相位的酉算子,Oracle算子Uω𝑈𝜔可以翻转目标态的相位,条件相移算子P𝑃可以翻转|0〉|0〉态以外的每个态的相位。

接下来,我们将构造可以翻转某一位量子比特相位的酉算子,定义如下:

from mindquantum.core.circuit import Circuit
from mindquantum.core.gates import Zdef bitphaseflip_operator(phase_inversion_qubit, n_qubits):   # 定义可以翻转某一位量子比特相位的函数s = [1 for i in range(1 << n_qubits)]for i in phase_inversion_qubit:s[i] = -1if s[0] == -1:for i in range(len(s)):s[i] = -1 * s[i]circuit = Circuit()length = len(s)cz = []for i in range(length):if s[i] == -1:cz.append([])current = it = 0while current != 0:if (current & 1) == 1:cz[-1].append(t)t += 1current = current >> 1for j in range(i + 1, length):if i & j == i:s[j] = -1 * s[j]for i in cz:if i:if len(i) > 1:circuit += Z.on(i[-1], i[:-1])else:circuit += Z.on(i[0])return circuit

现在, bitphaseflip_operator() 函数就可以实现翻转某一位量子比特的相位,只需要输入需要翻转相位的目标量子态和量子比特总数即可。

举个例子,我们现在生成3​​量子比特的均匀叠加态,运行如下代码:

# pylint: disable=W0104
from mindquantum.core.circuit import UN
from mindquantum.core.gates import H
from mindquantum.simulator import Simulatorn_qubits = 3                                 # 设定量子比特数为3
sim = Simulator('mqvector', n_qubits)        # 使用mqvector模拟器,命名为simcircuit = Circuit()                          # 初始化量子线路,命名为circuit
circuit += UN(H, n_qubits)                   # 每位量子比特上执行H门操作sim.apply_circuit(circuit)                   # 通过模拟器sim运行搭建好的量子线路circuitcircuit.svg()                                # 打印此时的量子线路circuit

q0:q1:q2:HHH

print(sim.get_qs(True))                      # 打印模拟器sim中运行量子线路circuit后的末态
√2/4¦000〉
√2/4¦001〉
√2/4¦010〉
√2/4¦011〉
√2/4¦100〉
√2/4¦101〉
√2/4¦110〉
√2/4¦111〉

从运行的结果看到此时的量子线路,以及我们成功生成了3量子比特的均匀叠加态。

假设我们需要翻转|4〉|4〉态的相位,只需调用我们定义好的bitphaseflip_operator()函数即可,运行如下代码:

# pylint: disable=W0104
sim.reset()                                                      # 重置模拟器sim维护好的量子态,使得初始化的量子态为|000>phase_inversion_qubit = [4]                                      # 翻转|4>态的相位
operator = bitphaseflip_operator(phase_inversion_qubit, n_qubits)# 调用我们定义好的bitphaseflip_operator()函数circuit += operator                                              # 在量子线路circuit中添加翻转|4>态的相位所需的量子门sim.apply_circuit(circuit)                                       # 通过模拟器sim再次运行搭建好的量子线路circuitcircuit.svg()                                                    # 打印此时的量子线路circuit

q0:q1:q2:HHHZZZZ

print(sim.get_qs(True))                                          # 打印模拟器sim中运行量子线路circuit后的末态
√2/4¦000〉
√2/4¦001〉
√2/4¦010〉
√2/4¦011〉
-√2/4¦100〉
√2/4¦101〉
√2/4¦110〉
√2/4¦111〉

从运行的结果看到此时的量子线路,以及|100〉|100〉​​的相位翻转为-1,运行如下代码:

print(int('100', 2))
4

从运行的结果看到,发生相位翻转的|100〉|100〉态即为我们希望相位翻转的|4〉|4〉态。

假设我们需要翻转除|0〉|0〉态以外的每个态的相位,运行如下代码:

# pylint: disable=W0104
n_qubits = 3                                                     # 设定量子比特数为3
sim1 = Simulator('mqvector', n_qubits)                           # 使用mqvector模拟器,命名为sim1operator1 = bitphaseflip_operator([i for i in range(1, pow(2, n_qubits))], n_qubits) # 调用我们定义好的bitphaseflip_operator()函数,翻转除|0>态以外的每个态的相位,命名为operator1circuit1 = Circuit()                                             # 初始化量子线路,命名为circuit1
circuit1 += UN(H, n_qubits)                                      # 每位量子比特上执行H门操作
circuit1 += operator1                                            # 在量子线路circuit1中添加翻转除|0>态以外的每个态的相位所需的量子门sim1.apply_circuit(circuit1)                                     # 通过模拟器sim1运行搭建好的量子线路circuit1circuit1.svg()                                                         # 打印此时的量子线路circuit1

q0:q1:q2:HHHZZZZZZZ

print(sim1.get_qs(True))                                         # 打印模拟器sim1中运行量子线路circuit1后的末态
√2/4¦000〉
-√2/4¦001〉
-√2/4¦010〉
-√2/4¦011〉
-√2/4¦100〉
-√2/4¦101〉
-√2/4¦110〉
-√2/4¦111〉

从运行的结果看到此时的量子线路,以及我们成功翻转除|0〉|0〉态以外的每个态的相位。

也就是说,我们定义的函数bitphaseflip_operator()可以实现Grover搜素算法中的Oracle算子Uω𝑈𝜔和条件相移算子P𝑃。

利用MindSpore Quantum实现Grover搜素算法实例

实例1:n=3𝑛=3​,|ω〉=|2〉|𝜔〉=|2〉(单目标)

首先,我们需要定义G𝐺算子,运行如下代码:

def G(phase_inversion_qubit, n_qubits):           # 定义Grover搜索算法中的G算子operator = bitphaseflip_operator(phase_inversion_qubit, n_qubits)operator += UN(H, n_qubits)operator += bitphaseflip_operator([i for i in range(1, pow(2, n_qubits))], n_qubits)operator += UN(H, n_qubits)return operator

然后,我们根据Grover搜索算法的量子线路模型在MindSpore Quantum中搭建对应的量子线路:

# pylint: disable=W0104
from numpy import pi, sqrtn_qubits = 3                                      # 设定量子比特数为3
phase_inversion_qubit = [2]                       # 设定需要翻转相位的目标态,在这里翻转|2>态的相位N = 2 ** (n_qubits)                               # 计算出数据库中元素的总个数
M = len(phase_inversion_qubit)                    # 计算出目标态的总个数r = int(pi / 4 * sqrt(N / M))                     # 设定G算子迭代次数为rsim2 = Simulator('mqvector', n_qubits)            # 使用mqvector模拟器,命名为sim2circuit2 = Circuit()                              # 初始化量子线路,命名为circuit2
circuit2 += UN(H, n_qubits)                       # 每位量子比特上执行H门操作for i in range(r):                                # 循环执行G算子r次circuit2 += G(phase_inversion_qubit, n_qubits)sim2.apply_circuit(circuit2)                      # 通过模拟器sim2运行搭建好的量子线路circuit2circuit2.svg()                                    # 打印此时的量子线路circuit2

q0:q1:q2:HHHZZZZHHHZZZZZZZHHHZZZZHHHZZZZZZZHHH

print(sim2.get_qs(True))                          # 打印模拟器sim2中运行量子线路circuit2后的末态
-√2/16¦000〉
-√2/16¦001〉
0.9722718241315036¦010〉
-√2/16¦011〉
-√2/16¦100〉
-√2/16¦101〉
-√2/16¦110〉
-√2/16¦111〉

从运行的结果看到,|010〉|010〉态的振幅为0.9722718241315036,相比于其它的量子态,这是极大的振幅,也就是说,若我们测量此时的状态,将会以极大的概率得到目标态|010〉|010〉​,运行如下代码进行测量:

# pylint: disable=W0104
from mindquantum.core.gates import Measuresim2.reset()                                      # 重置模拟器sim2维护好的量子态,使得初始化的量子态为|000>circuit2 += UN(Measure(), circuit2.n_qubits)      # 对量子线路circuit2中的每一位量子比特添加测量门result = sim2.sampling(circuit2, shots=1000)      # 通过模拟器sim2对量子线路circuit2进行1000次的采样
result.svg()                                      # 打印采样结果

Shots: 1000Keys: q2 q1 q00.00.1850.3690.5540.7380.923000130017010923011710014101131101011113probability

从运行的结果看到,1000次采样中有923次的采样结果为010(由于具有随机性,每次运行有略微差距),将其转化为10进制数,运行如下代码:

print(int('010', 2))
2

从运行的结果看到,我们成功地搜索出|2〉|2〉态。

实例2:n=5𝑛=5,|ω〉=|5〉|𝜔〉=|5〉和|11〉|11〉(多目标)

实例1中实现的是单目标搜索,现在我们尝试实现多目标搜索。首先,G𝐺算子已经定义好了,我们只需设定量子比特数和需要翻转相位的目标态,然后搭建对应的量子线路即可,运行如下代码:

# pylint: disable=W0104
n_qubits = 5                                      # 设定量子比特数为5
phase_inversion_qubit = [5, 11]                   # 设定需要翻转相位的目标态,在这里翻转|5>态和|11>态的相位N = 2 ** (n_qubits)                               # 计算出数据库中元素的总个数
M = len(phase_inversion_qubit)                    # 计算出目标态的总个数r = int(pi / 4 * sqrt(N / M))                     # 设定G算子迭代次数为rsim3 = Simulator('mqvector', n_qubits)            # 使用mqvector模拟器,命名为sim3circuit3 = Circuit()                              # 初始化量子线路,命名为circuit3
circuit3 += UN(H, n_qubits)                       # 每位量子比特上执行H门操作for i in range(r):                                # 循环执行G算子r次circuit3 += G(phase_inversion_qubit, n_qubits)sim3.apply_circuit(circuit3)                      # 通过模拟器sim3运行搭建好的量子线路circuit3circuit3.svg()                                          # 打印此时的量子线路circuit3

q0:q1:q2:q3:q4:HHHHHZZZZZZZZHHHHHZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZHHHHHZZZZZZZZHHHHHZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZHHHHHZZZZZZZZHHHHHZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZHHHHH

print(sim3.get_qs(True))                          # 打印模拟器sim3中运行量子线路circuit3后的末态
-0.035907766232129455¦00000〉
-0.035907766232129365¦00001〉
-0.03590776623212947¦00010〉
-0.035907766232129254¦00011〉
-0.03590776623212947¦00100〉
0.6932961018664989¦00101〉
-0.035907766232129455¦00110〉
-0.035907766232129365¦00111〉
-0.035907766232129455¦01000〉
-0.035907766232129365¦01001〉
-0.03590776623212947¦01010〉
0.6932961018664989¦01011〉
-0.03590776623212947¦01100〉
-0.035907766232129254¦01101〉
-0.035907766232129455¦01110〉
-0.035907766232129365¦01111〉
-0.0359077662321294¦10000〉
-0.03590776623212939¦10001〉
-0.03590776623212936¦10010〉
-0.03590776623212949¦10011〉
-0.03590776623212936¦10100〉
-0.03590776623212949¦10101〉
-0.0359077662321294¦10110〉
-0.03590776623212939¦10111〉
-0.0359077662321294¦11000〉
-0.03590776623212939¦11001〉
-0.03590776623212936¦11010〉
-0.03590776623212949¦11011〉
-0.03590776623212936¦11100〉
-0.03590776623212949¦11101〉
-0.0359077662321294¦11110〉
-0.03590776623212939¦11111〉

从运行的结果看到,|00101〉|00101〉​​和|01011〉|01011〉​​态的振幅均为0.6932961018664989,相比于其它的量子态,这是极大的振幅,也就是说,若我们测量此时的状态,将会以极大的概率得到目标态|00101〉|00101〉​​和|01011〉|01011〉​​态,运行如下代码进行测量:

# pylint: disable=W0104
sim3.reset()                                      # 重置模拟器sim3维护好的量子态,使得初始化的量子态为|00000>circuit3 += UN(Measure(), circuit3.n_qubits)      # 对量子线路circuit3中的每一位量子比特添加测量门result1 = sim3.sampling(circuit3, shots=1000)     # 通过模拟器sim3对量子线路circuit3进行1000次的采样
result1.svg()                                     # 打印采样结果

Shots: 1000Keys: q4 q3 q2 q1 q00.00.0970.1950.2920.390.4870000020001020001110010148700110101010301011478011013011102011111100002100012100101100111101003101011101101101111110011111001111011111102111113probability

从运行的结果看到,1000次采样中有487次的采样结果为00101和478次的采样结果为01011(由于具有随机性,每次运行会略有不同),将其转化为10进制数,运行如下代码:

print(int('00101', 2))
print(int('01011', 2))
5
11

从运行的结果看到,我们成功地搜索出|5〉|5〉​​和|11〉|11〉​​​​​态。

至此,我们介绍了Grover搜索算法的基本原理,以及通过两个具体的小例子来展示如何利用MindSpore Quantum实现该算法!赶紧动手体验一下量子编程的乐趣吧!

龙算法

除了在规模为4的数据库中找1个数据的场景,Grover算法不能够精确的搜索出所标记态。清华大学龙桂鲁教授在Grover算法基础之上提出量子精确搜索算法龙算法[3],能够以准确率为1的概率在所有场景中搜索出目标态。其主要思想是将Grover算子改写为如下的算子,

L=−H⊗nR0H⊗nRτ𝐿=−𝐻⊗𝑛𝑅0𝐻⊗𝑛𝑅𝜏

其中:R0=(I+(eiθ−1)|0〉〈0|)𝑅0=(𝐼+(𝑒𝑖𝜃−1)|0〉〈0|),Rτ=(I+(eiθ−1)|τ〉〈τ|)𝑅𝜏=(𝐼+(𝑒𝑖𝜃−1)|𝜏〉〈𝜏|)。在满足相位匹配条件时,

θ=2arcsin(sinβsin(π4Js+6))𝜃=2arcsin⁡(sin⁡𝛽sin⁡(𝜋4𝐽𝑠+6))

我们只需作用Js+1𝐽𝑠+1次龙算子,就可以以概率1找到目标态,这里β=arcsinM/N−−−−−√𝛽=arcsin⁡𝑀/𝑁,M𝑀为标记态个数,N𝑁为数据库大小,Js>=[((π/2)−β)/β]𝐽𝑠>=[((𝜋/2)−𝛽)/𝛽]。下面我们用MindSpore Quantum来实现。

一般角度相位转动线路

借助于辅助比特,我们搭建某个计算基矢一般角度相位转动线路。

from mindquantum.core.gates import X, PhaseShift
from mindquantum.core.circuit import Circuit
def change_phase_with_anclia(which, n_qubits, phase):c = Circuit()which_bit = bin(which)[2:].zfill(n_qubits)[::-1]polarity_circ = Circuit()for idx, bit in enumerate(which_bit):if bit == "0":polarity_circ += X.on(idx)c += polarity_circc += PhaseShift(phase).on(n_qubits, list(range(n_qubits)))c += polarity_circreturn c

搭建龙算子

from mindquantum.core.gates import BARRIER, Zdef L(which, n_qubits, theta, phi):U = UN(H, n_qubits)R0 = change_phase_with_anclia(0, n_qubits, theta)R_t = change_phase_with_anclia(which, n_qubits, phi)g_ops = R_t + BARRIER + U + BARRIER + R0 + BARRIER + U + BARRIERg_ops += Z.on(n_qubits)return g_ops

完成量子精确搜索算法:龙算法

这里我们以3比特数据库中搜索|2〉|2〉态为例,完成龙算法。

import numpy as np
from mindquantum.core.gates import H
from mindquantum.core.circuit import UN
n_qubits = 3
will_find = 2
beta = np.arcsin(np.sqrt(1 / 2**n_qubits))
Js = int((np.pi / 2 - beta) / 2 / beta)
theta = 2 * np.arcsin(np.sin(np.pi / (4 * Js + 6)) / np.sin(beta))
phi = thetag = L(will_find, n_qubits, theta, phi)            # 构建用于精确搜索的龙算子circ = UN(H, n_qubits) + X.on(n_qubits)
for i in range(Js + 1):circ += g
circ.svg()

q0:q1:q2:q3:HHHXXXPS2.1269XXHHHXXXPS2.1269XXXHHHZXXPS2.1269XXHHHXXXPS2.1269XXXHHHZ

接下来,我们计算线路的量子态。

print(circ.get_qs(ket=True))
(0.048708136684586345-0.9988130542902997j)¦1010〉

发现,除去相位,我们可以精确的得到目标态。通过采样,我们也可以得到如下类似的结果。

from mindquantum.simulator import Simulator
from mindquantum.core.gates import Measuresim = Simulator('mqvector', circ.n_qubits)
res = sim.sampling(circ + UN(Measure(), circ.n_qubits), shots=100)
res.svg()

Shots: 100Keys: q3 q2 q1 q00.00.20.40.60.81.01010100probability

from mindquantum.utils.show_info import InfoTableInfoTable('mindquantum', 'scipy', 'numpy')
SoftwareVersion
mindquantum0.9.11
scipy1.10.1
numpy1.23.5
SystemInfo
Python3.9.16
OSLinux x86_64
Memory8.3 GB
CPU Max Thread8
DateSat Dec 30 00:07:45 2023

参考文献:

[1] L. K. Grover, A fast quantum mechanical algorithm for database search[C]// Proceedings of the twenty-eighth annual ACM symposium on Theory of computing. ACM, 1996: 212-219.

[2] G. Brassard, P. Hoyer, M. Mosca, et al. Quantum amplitude amplification and estimation[J]. Contemporary Mathematics, 2002, 305: 53-74.

[3] Long G L. Grover algorithm with zero theoretical failure rate. Physical Rev A, 2001, 64: 022307.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/36913.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解码数智升级良方:中国一拖、中原传媒、神火股份等企业数字化实践分析

大模型、AI等技术的成熟以及政策法规的细化&#xff0c;数据资源的权属论证、合规确权、资产论证等环节逐渐走向实用性、价值化。 而伴随着“业财税数融”综合性数字化成为企业数字化转型的主流选择&#xff0c;财务部门的纽带属性被放大&#xff0c;财务数据的融合能力成为企业…

查普曼大学团队使用惯性动捕系统制作动画短片

道奇电影和媒体艺术学院是查普曼大学的知名学院&#xff0c;同时也是美国首屈一指的电影学院之一&#xff0c;拥有一流电影制作工作室。 最近&#xff0c;道奇学院的一个学生制作团队接手了一个项目&#xff0c;该项目要求使用真人动作、视觉效果以及真人演员和CG角色之间的互动…

Reflexion:通过语言反馈增强的智能体

Reflexion: Language Agents with Verbal Reinforcement Learning Reflexion: language agents with verbal reinforcement learninghttps://proceedings.neurips.cc/paper_files/paper/2023/hash/1b44b878bb782e6954cd888628510e90-Abstract-Conference.html 1.概述 最近,Re…

ubuntu下后台启动程序

1.启动 $ nohup python detect_mq.py > output.out 2>&1 & 这个命令是用来在后台运行一个 Python 脚本 detect_mq.py&#xff0c;并将脚本的输出重定向到文件 output.out。下面是这个命令的详细解释&#xff1a; nohup&#xff1a;这是一个命令&#xff0c;它告…

【知识学习】阐述Unity3D中MaterialTexture的概念及使用方法示例

在Unity3D中&#xff0c;Material和Texture是渲染过程中非常重要的两个概念&#xff0c;它们共同工作以实现丰富的视觉效果。 Material Material是Unity中的一个组件&#xff0c;用于定义物体表面的视觉属性。一个Material可以包含多种属性&#xff0c;如颜色、纹理、反射率等…

C# 在WPF .net8.0框架中使用FontAwesome 6和IconFont图标字体

文章目录 一、在WPF中使用FontAwesome 6图标字体1.1 下载FontAwesome1.2 在WPF中配置引用1.2.1 引用FontAwesome字体文件1.2.2 将字体文件已资源的形式生成 1.3 在项目中应用1.3.1 使用方式一&#xff1a;局部引用1.3.2 使用方式二&#xff1a;单个文件中全局引用1.3.3 使用方式…

黑马点评项目总结1-使用Session发送验证码和登录login和 使用Redis存储验证码和Redis的token登录

黑马先是总结了从session实现登录&#xff0c;然后是因为如果使用了集群方式的服务器的话&#xff0c;存在集群共享session互相拷贝效率低下的问题&#xff0c;接着引出了速度更快的内存型的kv数据库Redis&#xff0c; 使用Session发送验证码和登录login 举个例子&#xff1a…

免费分享:2015-2020年中国区域温度植被干旱指数(TVDI)月数据(附下载方法)

温度植被干旱指数(Temperature Vegetation Dryness Index&#xff0c;TVDI)是一种基于归一化植被指数(NDVI)与地表温度(LST)的土壤水分反演模型&#xff0c;能较好的进行干旱监测&#xff0c;尤其是监测特定年内某一时期整个区域的相对干旱程度&#xff0c;并可用于研究干旱程度…

【鸿蒙学习笔记】页面和自定义组件生命周期

官方文档&#xff1a;页面和自定义组件生命周期 目录标题 [Q&A] 都谁有生命周期&#xff1f; [Q&A] 什么是组件生命周期&#xff1f; [Q&A] 什么是组件&#xff1f;组件生命周期 [Q&A] 什么是页面生命周期&#xff1f; [Q&A] 什么是页面&#xff1f;页面生…

现如今软考通过率真的很低吗?

刚开始机考&#xff0c;10个人中有3个人表示想要尝试考试&#xff0c;这样通过率能高吗&#xff1f;就拿PMP证书来说吧&#xff0c;一下子就得花费三千多块&#xff0c;有几个人会轻易去尝试呢&#xff1f; 说到底&#xff0c;考试的难度是一个方面&#xff0c;考试的成本低是…

Linux登录界面

Linux登录界面 1. 起因2. 脚本3. 效果 1. 起因 某次刷抖音看到一个博主展示了一个登录页面,觉得蛮好看的.于是自己动手也写一个 2. 脚本 编写脚本/usr/local/bin/login.sh #!/bin/bash Current_timedate %Y-%m-%d %H:%M:%S Versioncat /etc/redhat-release Kernel_Version…

认识 Adobe XD:一款专业的UI/UX设计解决方案

Adobe XD 是什么&#xff1f;简单来说是Adobe 专门针对 UI 设计开发的设计工具&#xff0c;希望能有一个产品能够和 Sketch “对抗”&#xff0c;毕竟当时 Sketch 在 UI 设计领域分走了不少蛋糕。如今 Adobe XD 也按照预期成为了不少 UI 设计师的必备工具。 1.Adobe XD 主要做…

数据库调优厂商 OtterTune 宣布停止运营

昨天刷到消息&#xff0c;得知数据库优化厂商 OtterTune 停止了运营。OtterTune 的成员主要来自 CMU Andy Pavlo 教授领导的数据库实验室。公司正式成立于 2021 年 5 月&#xff0c;融资了 1450 万美金。 按照 Andy 教授的说法&#xff0c;公司是被一个收购 offer 搞砸了。同时…

【红帽战报】6月RHCE考试喜报!

往期战报回顾&#xff1a; 点击查看【战报】5月RHCE考试喜报&#xff01;通过率100% 点击查看【战报】4月份红帽考试战报&#xff01; 点击查看【战报】PASS&#xff01;PASS&#xff01;2023年终来一波RHCE考试 微思网络-红帽官方授权合作伙伴&#xff01;面向全国招生&…

Animate源文件修改要注意什么?

最近经常有同学提问&#xff0c;如何对Animate源文件&#xff0c;也就是fla格式文件进行修改&#xff0c;这里简单说一下要注意的内容。 首先是要使用Animate软件打开源文件&#xff0c;要尽量使用完整版本的软件&#xff0c;以免无法正常运行代码。接下来就是要注意的几点&…

操作系统期末复习 | 批处理程序 | PV实现同步互斥 | 调度算法 | 页面置换算法 | 磁盘调度算法

操作系统引论 批处理程序 单道批处理&#xff1a;引入脱机输入/输出技术&#xff0c;并由监督程序负责控制作业的输入、输出。主要优点是缓解了一定程度的人机速度矛盾&#xff0c;资源利用率有所提升。主要缺点是内存中仅能有一道程序运行&#xff0c;只有该程序运行结束之后…

2024全国青少年信息素养大赛图形化编程复赛评分标准及比赛大纲

一、 参赛技术要求 &#xff08;1&#xff09;竞赛平台 参赛选手使用官方竞赛平台进行比赛。 &#xff08;2&#xff09;网络环境 在能满足竞赛需求的联网环境下进行。 &#xff08;3&#xff09;浏览器 建议使用谷歌 Chrome 浏览器&#xff0c;版本号 100 及以上。 可以…

JVM专题四:JVM的类加载机制

Java中类的加载阶段 类加载 Java中的类加载机制是Java运行时环境的一部分&#xff0c;确保Java类可以被JVM&#xff08;Java虚拟机&#xff09;正确地加载和执行。类加载机制主要分为以下几个阶段&#xff1a; 加载&#xff08;Loading&#xff09;&#xff1a;这个阶段&#x…

聊一聊 C# 弱引用 底层是怎么玩的

一&#xff1a;背景 1. 讲故事 最近在分析dump时&#xff0c;发现有程序的卡死和WeakReference有关&#xff0c;在以前只知道怎么用&#xff0c;但不清楚底层逻辑走向是什么样的&#xff0c;借着这个dump的契机来简单研究下。 二&#xff1a;弱引用的玩法 1. 一些基础概念 …

如何判断一个Repo是否是Private还是Internal?

Github的Repository分为三种类型&#xff0c;主要是用于决定谁可以访问、查看和克隆该仓库。GitHub 提供了几种不同的可见性选项&#xff0c;包括 Private、Public 和 Internal。 Private 只有仓库的拥有者和被明确邀请为协作者&#xff08;Collaborator&#xff09;的用户才能…