当前位置: 首页 > news >正文

TSP问题1 NEURAL COMBINATORIAL OPTIMIZATION WITH REINFORCEMENT LEARNING

        本文提出了一种结合神经网络与强化学习来解决组合优化问题的框架。以旅行商问题(TSP)为研究对象,训练一个循环神经网络(RNN),使其在输入一组城市坐标后,能够预测出不同城市排列的概率分布。以负路径长度作为奖励信号,使用策略梯度方法优化循环神经网络的参数。比较了在训练图集上学习网络参数与在单个测试图上学习参数的效果。尽管计算成本较高,但在无需大量工程设计和启发式规则的前提下,神经组合优化方法在包含多达100个节点的二维欧几里得图上取得了接近最优的结果。将该方法应用于另一个NP难问题——背包问题(KnapSack),同样能在多达200个物品的实例中获得最优解。

1 Introduction

组合优化是计算机科学中的一个基本问题。一个典型的例子是旅行商问题(TSP):给定一个图,需要在所有节点的排列空间中搜索,找到一个具有最小总边权值(即路径长度)的最优节点序列。TSP 及其变体在规划、制造、遗传学等众多领域中都有广泛应用。

即使在二维欧几里得情况下(即节点是二维平面上的点,边权是点之间的欧几里得距离),寻找 TSP 的最优解也是 NP-hard 的。在实际应用中,TSP 求解器通常依赖于手工设计的启发式规则,以高效地搜索出有竞争力的路径。尽管这些启发式方法在 TSP 上表现良好,但一旦问题形式稍有变化,它们就需要重新设计。

相比之下,机器学习方法有潜力在多个优化任务中通用,因为它们可以基于训练数据自动发现启发式策略,从而减少对特定任务的手工设计依赖。然而,大多数成功的机器学习技术属于监督学习,即学习从输入到输出的映射关系。但对于大多数组合优化问题,监督学习并不适用,因为我们通常无法获得最优解的标签。

不过,可以使用验证器来比较一组解的质量,并为学习算法提供奖励反馈。因此,我们采用强化学习(RL)的范式来解决组合优化问题。实验表明,即使使用最优解作为标签来训练一个监督学习模型,其泛化能力也远不如一个通过探索不同路径并观察相应奖励的强化学习智能体。

本文提出了神经组合优化(Neural Combinatorial Optimization),这是一个结合强化学习与神经网络来解决组合优化问题的框架。本文考虑了两种基于策略梯度的方法:

  1. RL预训练(RL pretraining):使用一个训练集来优化一个循环神经网络(RNN),该网络参数化了一个关于解的随机策略,并以期望奖励为目标函数。在测试阶段,策略被固定,并通过贪婪解码或采样进行推理。

  2. 主动搜索(active search):不进行预训练,而是从一个随机策略开始,在单个测试实例上迭代优化 RNN 的参数,同样以期望奖励为目标,并在搜索过程中记录最优解。

本文发现,将 RL 预训练与主动搜索结合使用,在实践中效果最佳。

在最多包含 100 个节点的二维欧几里得图上,神经组合优化显著优于用于 TSP 的监督学习方法,并且在允许更多计算时间的情况下,能够获得接近最优的结果。我们还通过在背包问题(KnapSack)上测试该方法,展示了其灵活性,并在最多包含 200 个物品的实例中获得了最优解。这些结果表明,神经网络可以作为一种通用工具,用于解决那些难以设计启发式规则的组合优化问题。

2 Previous Work

旅行商问题(TSP)是一个被广泛研究的组合优化问题,针对欧几里得图和非欧几里得图,已有许多精确或近似算法被提出。Christofides提出了一种启发式算法,通过计算最小生成树和最小权完美匹配来构造解。该算法具有多项式时间复杂度,并保证在度量空间下的 TSP 实例中,解的质量不超过最优解的 1.5 倍。

目前已知的最优精确动态规划算法的时间复杂度为 Θ(2ⁿ·n²),这使得其难以扩展到大规模实例(例如 40 个城市以上)。然而,得益于精心设计的启发式规则,现代最先进的 TSP 求解器能够高效地搜索可行解空间,从而求解包含数千个节点的对称 TSP 实例。Concorde被广泛认为是最优秀的精确 TSP 求解器之一,它采用了切割平面算法,通过迭代求解 TSP 的线性规划松弛,并结合分支定界法来剪枝那些不可能包含最优解的搜索空间。类似地,Lin-Kernighan-Helsgaun 启发式算法受 Lin-Kernighan 启发式启发,是当前最先进的对称 TSP 近似搜索算法之一,已被证明能在数百个节点的实例中找到最优解。

更通用的求解器,例如 Google 的车辆路径问题求解器,处理的是 TSP 的超集问题,通常依赖于局部搜索算法元启发式算法的结合。局部搜索算法通过一组预定义的局部操作对候选解进行变换,从而在解空间中移动;而元启发式算法则用于提出“上坡”移动,帮助算法跳出局部最优。一个常用的元启发式是引导局部搜索,它通过对某些“不应出现在优质解中”的解特征进行惩罚,从而逃离局部极小值。

将现有搜索启发式应用于新问题(甚至是相似问题的新实例)所面临的困难,是众所周知的挑战。这一挑战源于**“没有免费午餐”定理**:在所有问题上的平均性能相同,因此必须根据问题的先验知识选择合适的搜索算法才能保证性能。这一挑战促使研究者提升优化系统的通用性,并推动了超启发式(hyper-heuristics)的发展。超启发式被定义为“用于选择或生成启发式以解决计算搜索问题的搜索方法或学习机制”,其目标是通过部分抽象化启发式选择过程,降低对领域知识的依赖,并已在多个任务中成功组合人类定义的启发式。然而,超启发式操作的是启发式空间而非解空间,因此仍然依赖于人类初始设计的启发式。

神经网络在组合优化中的应用历史悠久,其中大多数研究集中于 TSP。最早的尝试之一是使用Hopfield 网络求解 TSP。作者通过修改网络的能量函数,使其等价于 TSP 的目标函数,并使用拉格朗日乘子对违反约束的行为进行惩罚。然而,该方法对超参数和参数初始化非常敏感。后续工作主要致力于克服这一缺陷。

与 Hopfield 网络并行发展的还有可变形模板模型(deformable template models),其中最具代表性的是**弹性网络(Elastic Nets)自组织映射(SOM)**在 TSP 中的应用。后续研究也致力于解决这些模型的局限性。尽管这些神经网络具有许多吸引人的特性,但在实际 benchmark 中,它们的表现仍不如传统算法。或许是受这些负面结果影响,自 21 世纪初以来,这一研究方向逐渐被忽视。

近年来,随着序列到序列学习的发展,神经网络再次成为优化问题(包括离散优化)的研究热点。特别是,Pointer Networks的提出重新点燃了对 TSP 的研究兴趣。该方法使用带有非参数 softmax 的循环网络,在监督学习的方式下训练,以预测访问城市的顺序。尽管架构有所改进,但其训练信号仍来自一个近似求解器提供的监督标签。

3 NEURAL NETWORK ARCHITECTURE FOR TSP

本文聚焦于二维欧几里得TSP问题。给定一个输入图,表示为二维空间中的n个城市序列 s = {xᵢ}ⁿᵢ₌₁,其中每个 xᵢ ∈ ℝ²,目标是找到一个点的排列 π(称为一条“路径”),使得每个城市被访问一次,并且总路径长度最短。

定义由排列 π 所确定的路径长度为:

在这里插入图片描述
其中 ‖·‖₂ 表示 ℓ₂ 范数(即欧几里得距离)。

本文的目标是学习一个随机策略的参数,使得该策略 p(π|s) 在输入点集 s 的情况下,能为较短路径分配较高概率,为较长路径分配较低概率。

本文使用链式法则将路径的概率分解为:
在这里插入图片描述

然后使用独立的 softmax 模块 来表示右侧的每一项。

这一思路受到先前研究的启发,该研究同样使用链式法则来分解概率,以解决机器翻译等序列到序列问题。理论上,可以用一个标准的序列到序列模型来解决TSP,其中输出词汇表为 {1, 2, …, n}。然而,这种做法存在两个主要问题:

  1. 训练出的网络无法泛化到城市数量超过 n 的新实例;
  2. 优化参数需要依赖真实的输出排列(即监督信号),而这类标签通常不可得。

本文提出的方法解决了这两个问题。

为了实现对不同规模图结构的泛化,采用了 Vinyals 等人(2015b) 提出的方法,使用一组非参数的 softmax 模块,类似于 Bahdanau 等人(2015) 提出的注意力机制。这种方法称为 Pointer Network(指针网络),它允许模型指向输入序列中的某个位置,而不是从一个固定大小的词汇表中预测一个索引值。

使用指针网络架构(如图1所示)作为策略模型,用于参数化 p(π|s)

在这里插入图片描述

3.1 Architecture Details

本文的指针网络由两个循环神经网络(RNN)模块组成:编码器(encoder)解码器(decoder),两者都使用 LSTM(长短期记忆)单元(Hochreiter & Schmidhuber, 1997)。

  • 编码器网络逐个城市地读取输入序列 s,并将其转换为一组隐状态记忆
    {encᵢ}ⁿᵢ₌₁,其中 encᵢ ∈ ℝᵈ
    编码器在第 i 步的输入是一个 d 维嵌入向量,它通过对二维坐标 xᵢ 进行线性变换得到,该变换在所有输入时间步之间共享参数

  • 解码器网络也维护其隐状态记忆 {decᵢ}ⁿᵢ₌₁,其中 decᵢ ∈ ℝᵈ
    在每一步 i,解码器使用一个指针机制(pointing mechanism),生成一个关于“下一个要访问的城市”的概率分布。
    一旦选定了下一个城市,它就作为输入传递给下一步的解码器。
    第一步解码器的输入(图1中表示为 hₑ)是一个 d 维向量,被视为模型的可训练参数

本文的注意力函数(接收一个查询向量 q = decᵢ ∈ ℝᵈ 和一组参考向量 ref = {enc₁, …, encₖ},并预测一个关于 k 个参考项的概率分布 A(ref, q)。这个分布表示模型在查询 q 的条件下,指向参考项 rᵢ 的程度。

Vinyals 等人(2015a)还建议引入额外的计算步骤,称为 glimpses(瞥见),用于聚合输入序列中不同部分的贡献,类似于 Bahdanau 等人(2015)的注意力机制。本文在附录 A.1 中详细讨论了这一机制。实验中发现,在指针机制中使用 1 个 glimpse 可以在几乎不增加延迟的情况下带来性能提升。

4 OPTIMIZATION WITH POLICY GRADIENTS

Vinyals 等人(2015b)提出使用监督损失函数来训练指针网络,该损失函数由条件对数似然构成,具体形式为网络输出概率与 TSP 求解器提供的目标之间的交叉熵。然而,对于 NP-hard 问题而言,这种基于示例的学习方式并不理想,原因如下:

  1. 模型的性能受限于监督标签的质量;
  2. 获取高质量标注数据代价高昂,对于新问题甚至可能不可行;
  3. 我们更关心的是找到一个有竞争力的解,而不是复制另一个算法的结果。

相比之下,本文认为强化学习(RL)为训练神经网络求解组合优化问题提供了更合适的范式,尤其是因为这些问题通常具有简单的奖励机制,甚至可以在测试时使用。因此,我们提出使用无模型、基于策略的强化学习来优化指针网络的参数,记为 θ

我们的训练目标是期望路径长度,给定输入图 s,定义为:
在这里插入图片描述

在训练过程中,图 s 是从某个分布 S 中采样得到的,因此总训练目标为:

在这里插入图片描述

我们采用策略梯度方法随机梯度下降来优化参数。公式 (3) 的梯度通过经典的 REINFORCE 算法(Williams, 1992)计算:
在这里插入图片描述

其中,b(s) 是一个基线函数,不依赖于 π,用于估计期望路径长度,从而降低梯度的方差

通过采样 B 个独立同分布的图 ( s_1, s_2, …, s_B \sim S ),并为每个图采样一条路径 ( π_i \sim p_θ(·|s_i) ),使用蒙特卡洛采样近似梯度:

在这里插入图片描述

一个简单且常用的基线选择是指数移动平均奖励,用于反映策略随训练过程逐渐提升的事实。尽管这种基线在实验中足以超越 Christofides 算法,但它存在一个缺陷:无法区分不同输入图之间的难度差异。例如,对于某个复杂图 s,即使其最优路径 π* 已经很好,但如果其长度 L(π|s)* 仍大于基线值 b,则该路径仍会被错误地“惩罚”。

为此,引入一个参数化基线模型,称为 critic(评判家),由参数 θ_v 表示,用于估计当前策略 p_θ 在给定输入图 s 下的期望路径长度。该 critic 通过最小化其预测值 b_{θ_v}(s) 与实际采样路径长度之间的均方误差进行训练:
在这里插入图片描述

Critic 的架构(针对 TSP)

本文的 critic 将输入序列 s 映射为一个标量基线预测 b_{θ_v}(s),其结构包括三个模块:

  1. LSTM 编码器:与指针网络的编码器结构相同,将输入序列编码为一组隐状态和一个隐藏状态 h
  2. LSTM 处理块:执行 P 步计算,每一步通过“glimpse”机制(见附录 A.1)更新隐藏状态;
  3. 2 层 ReLU 全连接解码器:将最终隐藏状态映射为一个标量基线预测。

在这里插入图片描述
本文的训练算法(见算法 1)与 A3C(异步优势演员-评判家)(Mnih 等,2016)密切相关,因为采样路径长度与 critic 预测值之间的差异是优势函数的无偏估计。我们在多个 worker 之间异步更新参数,每个 worker 也处理一个小批量的图以获得更稳定的梯度估计。

4.1 Search Strategies

由于评估一条路径的开销很低,本文的 TSP 智能体可以在推理阶段模拟搜索过程:为每个图采样多个候选解,并选择最短的一条。这种推理过程类似于传统求解器在可行解空间中的搜索。

本文考虑了以下两种搜索策略:

1. Sampling

最简单的方法是:从策略 p_θ(·|s) 中采样多条路径,并选择最短的一条。与启发式求解器不同,我们不强制的路径多样性,但可以通过调节温度超参数控制采样多样性(详见附录 A.2)。实验表明,这种采样策略显著优于贪婪解码(总是选择概率最大的城市)。本文也尝试过在指针机制中加入随机噪声再进行贪婪解码(类似 Cho, 2016),但效果不如采样。

2. Active Search

与其用固定模型采样并忽略采样结果的奖励信息,不如在推理阶段继续优化策略参数 θ,以最小化当前图 s 的期望路径长度。这种方法特别适用于:从一个已预训练模型开始,在测试图上进行微调;甚至从零开始也能获得不错的解。我们称这两种方式为:

  • RL 预训练 + 主动搜索(RL pretraining-Active Search)
  • 纯主动搜索(Active Search)

主动搜索同样使用策略梯度(类似算法 1),但只针对单个测试图采样多条路径 π₁, …, π_B,并使用指数移动平均基线(而非 critic,因为无需区分不同输入)。

在这里插入图片描述
本文在算法 2 中给出了主动搜索的训练流程。值得注意的是:

  • RL 训练虽然无需监督标签,但仍依赖训练数据分布;
  • 而主动搜索完全不依赖训练数据分布,具有更强的分布外泛化能力
  • 此外,我们将城市集合作为序列输入,并在输入前随机打乱顺序,以增加采样过程的随机性,从而显著提升主动搜索的效果。

5 EXPERIMENTS

本文进行实验以研究所提出的神经组合优化(Neural Combinatorial Optimization)方法的行为。考虑了三个基准任务:欧几里得 TSP20、TSP50 和 TSP100,每个任务生成了 1000 个测试图。图中点是从单位正方形 [0, 1]² 中均匀随机采样的。

5.1 EXPERIMENTAL DETAILS

在这里插入图片描述
在所有实验中,使用:

  • 小批量大小:128 个序列
  • LSTM 隐藏单元数:128
  • 每个点的二维坐标被嵌入到 128 维空间中

使用 Adam 优化器(Kingma & Ba, 2014)进行训练,初始学习率为:

  • TSP20 和 TSP50:10⁻³
  • TSP100:10⁻⁴
    每 5000 步衰减一次,衰减因子为 0.96

参数初始化范围为 [-0.08, 0.08],梯度 L2 范数裁剪为 1.0。本文最多使用 1 个 attention glimpse。在搜索阶段,小批量由测试序列或其排列组成。Active Search 中的基线衰减系数 α = 0.99

方法变体

方法名称描述
Supervised Learning使用指针网络,以 100 万条最优路径为监督数据训练。效果不如 RL。
RL Pretraining-Greedy用 RL 预训练后,贪心解码(每步选概率最大的城市)。
RL Pretraining-Greedy@16用 16 个预训练模型分别贪心解码,选最短路径。
RL Pretraining-Sampling从预训练模型中采样 1,280,000 条路径,选最短。温度参数 T* 经网格搜索调优。
RL Pretraining-Active Search从预训练模型开始,在测试图上继续训练 10,000 步,采样 1,280,000 条路径。
Active Search(从零开始)无预训练,直接在测试图上训练:TSP20/50 训练 10 万步,TSP100 训练 20 万步。

5.2 RESULTS AND ANALYSES

本文将提出的方法与三个性能与复杂度依次提升的基线进行比较:

  1. Christofides 算法:多项式时间可得,理论保证不超过最优解的 1.5 倍。
  2. Google OR-Tools 的车辆路径求解器:在 Christofides 解的基础上用 2-opt、Lin-Kernighan 等局部算子改进,并可搭配模拟退火、禁忌搜索、引导局部搜索等元启发式以逃离劣质局部极小。
  3. 最优解:由 Concorde(精确)与 LK-H(启发式,但在我们的测试集上经验最优)给出。

在这里插入图片描述

表 2 列出了各方法在 TSP20、TSP50、TSP100 上的平均路径长度。关键观察:

  • 采用 RL 训练显著优于监督学习(Vinyals 等, 2015b)。
  • 所有提出的方法均明显优于 Christofides,包括不依赖任何搜索的 RL pretraining-Greedy。

表 3 对比了贪心解码方法的运行时间:

  • 我们的模型在单张 Nvidia Tesla K80 GPU 上运行;
  • Concorde 与 LK-H 在 Intel Xeon E5-1650 v3 3.50 GHz CPU 上运行;
  • OR-Tools 在 Intel Haswell CPU 上运行。

结果显示,两种贪心方法均非常高效,仅比最优解差几个百分点。
在这里插入图片描述
推理时搜索对进一步逼近最优解至关重要,但代价是运行时间增加。好在 RL pretraining-Sampling 与 RL pretraining-Active Search 均可提前终止,性能损失很小(见表 4)。

多数 RL 预训练方法优于 OR-Tools 的局部搜索,其中 RL pretraining-Greedy@16 与 OR-Tools 速度相近却效果更好。附录表 6 给出了 OR-Tools 搭配不同元启发式时随采样数增加的性能与耗时。

与元启发式比较

  • Neural Combinatorial 明显优于模拟退火;

  • 略逊于禁忌搜索;

  • 与引导局部搜索仍有较大差距。
    在这里插入图片描述
    图 2 按“与最优解的比值”对所有配置排序。可见:

  • RL pretraining-Sampling 与 RL pretraining-Active Search 是最具竞争力的神经方法;

  • 在大量测试实例中恢复到了最优解

小解空间(如 TSP20):

  • 经温度调优的 RL pretraining-Sampling 更强;
  • RL pretraining-Active Search 偶尔会把搜索引向次优区域(见表 4 与图 2 TSP50 结果)。

大解空间(如 TSP100):

  • RL pretraining-Active Search 在相同采样数或相同运行时间下均更优;
  • 且可继续提升。

纯 Active Search(从零开始)也能给出有竞争力的路径,但耗时极长:

  • TSP50 约 7 小时/实例;
  • TSP100 约 25 小时/实例。

图 3 展示了若干由本文的方法得到的随机示例路径。
在这里插入图片描述

6 GENERALIZATION TO OTHER PROBLEMS

Neural Combinatorial Optimization(NCO)的模型架构与具体组合优化问题紧密相关。

  • 若输出是“输入的排列 / 截断排列 / 子集”,可用 Pointer Network
  • 若输出为其他结构化对象,可用经典 seq2seq
  • 若需同时“指向”和“打标签”(如图着色),可在解码时混合 pointer + softmax模块。

只要模型能把问题实例编码成向量序列,并通过反复解码构造解,就可以把第4节的强化学习流程搬过来,只需把奖励函数换成对应问题的目标即可。

可行性处理
对某些问题,可在解码阶段直接给不可行分支赋零概率(如同TSP里禁止重复访问)。
但对很多约束复杂的问题(带时间窗的TSP等),早期分支是否可行需搜索子树才能知道,代价与直接寻优相当。

与其硬编码可行性,不如让模型自己学约束。一种简单思路——留待实验验证——是在奖励里加罚项,对违反约束的解进行惩罚(类似约束优化里的罚函数法)。采样阶段若抽到不可行解,直接丢弃并重新采样即可(对RL pretraining-Sampling和Active Search都适用)。也可“软硬结合”:容易识别的不可行分支直接屏蔽,其余等解建完后再罚。

6.1 KNAPSACK EXAMPLE

为展示NCO的灵活性,我们在另一个经典NP-hard问题——0-1背包上做实验。

问题定义
给定n件物品,每件有重量wᵢ与价值vᵢ,以及容量W。选子集S⊆{1,…,n}使
在这里插入图片描述

问题已呈NP-hard。

经典贪心:按价值/重量比降序装,直到超重。

NCO建模

  • 用指针网络;
  • 把每个物品编码成2维向量(wᵢ, vᵢ);
  • 解码时依次“指向”要装入的物品;
  • 当累计重量首次超过W时立即停止,当前解即为可行解。

数据
生成三个数据集KNAP50/100/200,各1000例。权重与价值在[0,1]均匀采样。容量分别设为12.5(KNAP50)或25(KNAP100/200)。

结果
在这里插入图片描述

  • RL pretraining-Greedy:平均解价值距最优仅约1%;
  • Active Search(5000步)所有实例均达到最优
  • 两基线(价值/重量贪心 + 同等采样数的随机搜索)均被显著超越。

该实验证实,不经手工启发式设计,仅用同样一套RL框架,就能把指针网络搬到背包问题并取得近优甚至最优结果。

7 CONCLUSION

本文提出神经组合优化(Neural Combinatorial Optimization)框架,用强化学习与神经网络求解组合优化问题。以旅行商问题(TSP)为核心,我们对框架的每一种变体进行了系统实验。结果表明,在多达100个节点的二维欧几里得图上,该方法无需复杂工程与手工启发式,即可取得接近最优的解。

A 附录

A.1 POINTING AND ATTENDING

指向机制(Pointing)

计算由两个注意力矩阵 W_ref, W_q ∈ ℝ^{d×d} 和向量 v ∈ ℝ^d 参数化:

对第 i 个参考向量 r_i 和查询向量 q 先算 logits,若城市 i 已在部分 tour 中出现过,则置 u_i = −∞。
在这里插入图片描述
经 softmax 得概率
在这里插入图片描述
解码第 j 步时
在这里插入图片描述
通过把已访问城市的 logits 设为 −∞,保证输出合法 TSP 路径。

注视机制(Glimpse)

glimpse 函数 G(ref, q) 与 A 输入相同,额外参数 W^g_ref, W^g_q, v^g:
1、先拿一次注意力权重
在这里插入图片描述
2、对参考向量加权求和
在这里插入图片描述
可迭代多次:
在这里插入图片描述
最终 g^L 再喂给指向函数 A 产生指针概率。
实验上 L>1 反而难训练且收益极小,故默认只用 1 次 glimpse。

A.2 IMPROVING EXPLORATION

Softmax 温度
推理时加温度 T:
在这里插入图片描述
T>1 使分布更平坦,防止模型过度自信,利于采样多样性。
Logit 裁剪
另一种做法:
在这里插入图片描述
超参 C 控制 logits 幅值,从而直接限制概率熵,同样可减轻过度确定性。

A.3 OR TOOL’S METAHEURISTICS BASELINES FOR TSP

表 6 给出 OR-Tools 在 Intel Haswell 单 CPU 上,各元启发式随采样数增加时的平均路径长度与耗时(秒)。

模拟退火(Simulated Annealing)
禁忌搜索(Tabu Search)
引导局部搜索(Guided Local Search)
在这里插入图片描述
三种方法均从同一初始解出发,逐步扩展候选池。结果显示:
采样/运行时间越大,越逼近最优;
引导局部搜索 > 禁忌搜索 > 模拟退火;
相同采样预算下,Neural Combinatorial Sampling/Active Search 可优于前两者,但仍逊于引导局部搜索。

http://www.dtcms.com/a/466263.html

相关文章:

  • 代码随想录Day46|647. 回文子串、516.最长回文子序列
  • 钦州 网站建设全屋定制十大名牌口碑
  • 【MySQL】认识数据库以及MySQL安装
  • 网站建设网站软件有哪些内容金华网站建设seo
  • 做素描的网站鲜花网站建设文档
  • 从 PE 安装 Windows 系统全流程教程(适合U盘重装)
  • 自动下载ICLR论文
  • 导诊机器人如何提升三甲医院服务效能?
  • 北京网站模板下载品牌定位的三要素
  • 做游戏都需要什么网站微网站开发需要多少钱
  • 存储RAM/ROM硬件笔试真题解析
  • React.lazy 和 suspense 如何使用?
  • 深圳购物网站建设价格引流推广app
  • 【React】useMemo 和 useEffect 的用法
  • 网站建设微盘下载营销型网站建设范文
  • 3.1.4. Shell 函数的知识与实践
  • 双目测距-初识
  • C++开发基础之日期处理的全面指南:从C库到Chrono
  • 北京网站维护公司直通车优化推广
  • 大厂MongoDB开发运维规范
  • 公司网站可以自己做吗wex5可以做网站吗
  • 在浏览器上播放摄像头rtsp视频流的实现方案
  • LeetCode算法日记 - Day 67: 不同路径、最长递增子序列
  • 2024ICPC区域赛香港站
  • 公司网站备案怎么做运营管理培训
  • 基于STM32的智能衣柜系统/智能衣帽间/wifi衣柜/wifi衣帽间/智能家居系统
  • access 网站后台seo引擎
  • 打字训练文章大全:哪吒打字1000篇打字文章素材
  • 使用 minimind
  • MinerU与Docling:智能文档处理框架对比