【运筹优化】元启发式算法详解:变邻域搜索算法(Variable Neighborhood Search,VNS)+ 案例讲解代码实现

news2024/11/29 6:39:08

文章目录

  • 一、介绍
  • 二、基本方案
  • 三、一些扩展
  • 四、在VNS内改变配方
    • 4.1 基于变邻域的公式空间搜索
    • 4.2 变公式搜索
  • 五、原始对偶VNS
  • 六、求解混合整数线性规划的VNS
  • 七、连续全局优化的可变邻域搜索
  • 八、可变邻域编程(VNP):自动编程的VNS
  • 九、Discovery Science
  • 十、总结
  • 十一、案例讲解&代码实战


一、介绍

可变邻域搜索(VNS)是一种元启发式算法,该算法基于邻域系统变化的思想,在下降阶段寻找局部最优解,在扰动阶段走出相应的谷值。

最初设计用于组合优化问题的近似解,它被扩展到处理混合整数规划、非线性规划,以及最近的混合整数非线性规划。

此外,VNS已被用作自动化或计算机辅助图论的工具。这导致了该领域超过1500个猜想的发现,并自动证明了其中的一半以上。这与许多不同的数学家对大约400个这样的猜想所做的独立的证明形成了对比。

本博客组织如下

  • 第二节中,我们将介绍VNS的基本方案,即可变邻域下降(VND)、简化VNS (RVNS)、基本VNS (BVNS)和广义VNS (GVNS)

  • 两个重要的扩展出现在第三节:偏斜VNS和可变邻域分解搜索(VNDS)。

  • 第四节讨论了最近进一步的发展,称为公式空间搜索(FSS)。本文的其余部分描述了VNS在几类大规模和复杂优化问题中的应用,这些应用已被证明是特别成功的。

  • 第五节专门介绍原始双VNS (PD-VNS)及其在定位和聚类问题中的应用。

  • 寻找具有VNS的大型混合整数线性规划的可行解将在第六节中讨论。

  • 第七节介绍了在连续全局优化中应用VNS的方法。

  • 用VNS求解混合整数非线性规划的更困难的情况将在八节中考虑。

  • 将VNS应用于图论本身(而不仅仅是图上定义的特定优化问题)将在第九节中讨论。

  • 第十节给出了简短的结论。


二、基本方案

确定性优化问题可以表述为:

在这里插入图片描述

N k ( k = 1 , . . . , k m a x ) N_k(k=1,...,k_{max}) Nk(k=1,...,kmax) 是一个预先定义好的有限数量的邻域结构集合。 N k ( x ) N_k(x) Nk(x) 是解 x x x 的第 k k k 个邻域解集合。

大多数的局部搜索启发式算法仅仅使用一个邻域结构,即 k m a x = 1 k_{max}=1 kmax=1

令最优解 x o p t x_{opt} xopt (或全局最小值)是达到最小值的可行解。

如果 x ∈ N k ( x ′ ) x∈N_k(x') xNk(x) 不存在令 f ( x ) < f ( x ′ ) f(x) < f(x') f(x)<f(x) 的解,则称 x ′ ∈ X x'∈X xX 是关于 N k N_k Nk ( 3.1 ) (3.1) (3.1) 的局部最小值。

元启发式(基于局部搜索过程)在找到第一个局部最小值后,尝试通过其他方式继续搜索。

VNS则基于三个简单的事实:

  • 事实1:一个邻域结构的局部最小解 x ′ x' x,对另一个邻域结构不一定如此;
  • 事实2:全局最小值是所有可能邻域结构的局部最小值;
  • 事实3:在许多问题中,不同邻域结构的局部极小值与局部极小值之间的距离相对较近

最后这一点是经验性的,它意味着局部最优常常提供一些关于全局最优的信息。

例如,在两个解决方案中可能有几个变量共享相同的值。由于这些变量通常不能提前确定,因此应该对局部最优的邻域进行有组织的研究,直到找到更好的解决方案。

为了通过使用多个邻域来解决(3.1),事实1 - 3可以以三种不同的方式使用:(1)确定性;(2)随机;(3)既有确定性又有随机性。

我们首先在算法1中检查将在VNS框架中使用的解移动和邻域变化函数。

N e i g h b o r h o o d C h a n g e ( x , x ′ , k ) NeighborhoodChange(x,x',k) NeighborhoodChange(x,x,k) 将在位值 f ( x ) f(x) f(x) 与从第 k k k 个邻域(行1)获得的新值 f ( x ′ ) f(x') f(x) 进行比较。如果获得改进,则更新在位值(行2),并将 k k k 返回到初始值(行3)。否则,考虑下一个邻域(行4)。

在这里插入图片描述
下面我们讨论变邻域下降和简化变邻域搜索,然后在此基础上构建基本和一般变邻域搜索的框架:

(i) 可变邻域下降(Variable Neighborhood Descent,VND)方法(算法2)以确定性的方式进行邻域的改变。这些邻域记为 N k ( k = 1 , … , k m a x ) N_k( k = 1,…, k_{max}) Nk(k=1,,kmax)

在这里插入图片描述
大多数局部搜索启发式算法使用一个或两个邻域来改进当前解决方案,但是最终解决方案应该是所有邻域的局部最小值解,因此,与单个邻域结构相比,采用更多的邻域更有可能达到全局最优解。

(ii) 从 N k ( x ) N_k(x) Nk(x) 中随机选择一个点,而不尝试从该点下降,得到 RVNS (Reduced VNS) 方法。相反,将新点的目标值与现有点的目标值进行比较,并在改进的情况下进行更新。我们还假设已经选择了一个停止条件,例如允许的最大CPU时间 t m a x t_{max} tmax,或者两个改进之间的最大迭代次数。为了简化算法的描述,我们在下面总是使用 t m a x t_{max} tmax 。因此,RVNS(算法3)使用两个参数: t m a x t_{max} tmax k m a x k_{max} kmax

在这里插入图片描述

第4行中的 S h a k e ( x , k ) Shake(x,k) Shake(x,k) 函数从 x x x 的第 k k k 个邻域随机生成一个点 x ′ x' x ,即 x ′ ∈ N k ( x ) x'∈N_k(x) xNk(x) 。在算法4中给出,其中假设 N k ( x ) N_k(x) Nk(x) 中的点编号为 { x 1 , . . . , x ∣ N k ( x ) ∣ } \{x^1,..., x^{|N_k(x)|}\} {x1,...,xNk(x)}请注意,震动操作中的邻域结构使用了不同的符号,因为这些通常与VND中使用的符号不同

在这里插入图片描述
RVNS对于局部搜索成本很高的大型实例非常有用。它也可以用于在分解之前找到大型问题的初始解决方案。

据观察,参数 k m a x k_{max} kmax 的最佳值通常是 2 2 2 3 3 3 。此外,两次改进之间的最大迭代次数通常用作停止条件。RVNS类似于蒙特卡罗方法,但更具系统性。

(iii) 基本VNS (Basic VNS, BVNS)方法结合了邻域的确定性和随机变化。确定性部分用局部搜索启发式表示。它包括:

  • (1) 选择一个初始解 x x x
  • (2) 找到一个从 x x x 下降的方向(在一个邻域 N ( x ) N(x) N(x) 内)
  • (3) 沿着这个方向移动到 N ( x ) N(x) N(x) f ( x ) f(x) f(x) 的最小值。如果没有下降方向,则启发式停止;否则迭代

通常使用最陡下降方向,也称为最佳改进方向。另请参阅算法2,其中在VND的每个邻域中使用最佳改进。这在算法5中进行了总结,其中我们假设给出了初始解 x x x 。输出由局部最小值(也用 x x x 表示)及其值组成。

在这里插入图片描述

由于最陡下降法可能很耗时,所以另一种方法是使用首次下降法(或首次改进法)。然后系统地枚举点 x i ∈ N ( x ) x^i∈N(x) xiN(x) ,一旦找到下降方向就进行移动。算法6对此进行了总结。

在这里插入图片描述
BVNS的随机相位(见算法7)由从震动操作的第 k k k 邻域随机选择点 x ′ x' x 表示。请注意,在步骤5中随机生成点 x ′ x' x,以避免在确定性规则中可能发生的循环。

在这里插入图片描述

(iv) 一般VNS(General VNS)。请注意,局部搜索步骤(BVNS算法7中的第6行)也可以被VND(算法2)所取代。这种通用VNS (VNS/VND)方法已经导致了文献中报道的一些最成功的应用。一般VNS (GVNS)概述在下面的算法8中。注意邻域 { N 1 , . . . , N l m a x } \{N_1,...,N_{l_{max}}\} {N1,...,Nlmax} 用于 VND 步骤,而不同的邻域序列 { N 1 , . . . , N k m a x } \{N_1,...,N_{k_{max}}\} {N1,...,Nkmax} 适用于震动步骤。

在这里插入图片描述


三、一些扩展

(i) 倾斜 VNS (Skewed VNS,SVNS)方法解决了探索远离现有解决方案的山谷的问题。事实上,一旦在一个大地区找到了最佳解决方案,就必须走很远的路才能得到一个改进的解决方案。在遥远的邻域中随机抽取的解可能与现有的解有很大的不同,然后VNS可能在某种程度上退化为多起点启发式(其中从随机生成的解迭代下降,这是低效的)。因此,必须对与现任者的距离进行补偿,为此提出了一种称为倾斜VNS (SVNS)的方案。其步骤在算法9、10和11中给出。SVNS中的 K e e p B e s t ( x , x ′ ) KeepBest(x, x') KeepBest(x,x) 函数(算法9)仅保留最佳解决方案 x x x x ′ x' x N e i g h b o r h o o d C h a n g e S NeighborhoodChangeS NeighborhoodChangeS 函数(算法10)执行SVNS的移动和邻居更改。

在这里插入图片描述

SVNS利用函数 ρ ( x , x ′ ′ ) ρ(x, x'') ρ(x,x′′) 来测量当前解 x x x 和局部最优解 x ′ ′ x'' x′′ 之间的距离。用于定义 N k N_k Nk 的距离函数也可用于此目的。当 f ( x ′ ′ ) f(x'') f(x′′) 大于 f ( x ) f(x) f(x) 但不能太大(否则总是会离开 x x x )时,必须选择参数 α α α 以允许向远离 x x x 的谷移动。在每种情况下,实验都可以找到 α α α 的良好值。此外,为了避免从 x x x 到接近解的频繁移动,当 ρ ( x , x ′ ′ ) ρ(x, x'') ρ(x,x′′) 很小时,可以取较小的 α α α 值。更复杂的 α ρ ( x , x ′ ′ ) αρ(x, x'') αρ(x,x′′) 函数的选择可以通过一些学习过程(机器学习)来完成。

在这里插入图片描述

(ii) 变量邻域分解搜索(Variable neighborhood decomposition search, VNDS)方法在对问题进行分解的基础上,将基本VNS扩展为两级VNS方案。它在算法12中给出,其中 t d t_d td 是一个附加参数,表示Basic VNS(第5行)解决分解(较小规模)问题所允许的运行时间。

在这里插入图片描述
为了便于表示,但又不失一般性,我们假设解 x x x 表示一组属性。在步骤4中,我们用 y y y 表示在 x ′ x' x 中存在但不存在于 x ( 即 y = x ′ \ x ) x (即y = x' \backslash x) x(y=x\x) 中的 k k k 个解属性的集合。在步骤5中,我们在 y y y 空间中找到局部最优 y ′ y' y ;然后用 x ′ ′ x'' x′′ 表示整个空间 x ( x ′ ′ = ( x ′ \ y ) ∪ y ′ ) x (x''= (x' \backslash y)∪y') x(x′′=(x\y)y) 的对应解。我们注意到在新解中利用一些边界效应可以显著提高解的质量。这就是为什么在步骤6中,使用 x ′ ′ x'' x′′ 作为初始解在整个空间 x x x 中找到局部最优 x ′ ′ x'' x′′ 的原因。如果这很耗时,那么至少应该执行一些局部搜索迭代。

VNDS可以被看作是在VNS框架中嵌入经典的逐次逼近方案(至少从60年代开始就被用于组合优化)。


四、在VNS内改变配方

解决优化问题的传统方法是考虑给定的公式,并以某种方式通过其可行集 x x x 进行搜索。鉴于相同的问题通常可以用不同的方式进行表述,因此可以扩展搜索范例,以包括从一个公式到另一个公式的跳转。

每个公式都应该适合一些传统的搜索方法,它的“局部搜索”完全在这个公式中工作,并从某个初始解开始产生最终解。在一种公式中找到的任何解都应该很容易地转化为它在任何其他公式中的等效解。

然后,我们可以通过使用由前者的局部搜索得到的解作为后者的局部搜索的初始解,从一个公式移动到另一个公式。当然,这种策略只有在不同形式的本地搜索表现不同时才有用。这里我们讨论两种这样的可能性。

4.1 基于变邻域的公式空间搜索

在这里插入图片描述

4.2 变公式搜索


五、原始对偶VNS

对于大多数现代试探法,最优解和获得的近似解之间的差值并不精确。如果可以找到目标的下限函数值。为此,标准的方法是根据问题的数学规划公式,放松原始变量的完整性条件。

然而,当问题的维度很大时,即使是宽松的问题也不可能被标准的商业解决者精确地解决。因此,启发式地解决对偶松弛问题似乎也是一个好主意。以这种方式,我们得到了原始启发式性能的保证界限。

如果我们想在分支定界框架内得到精确解,下一个困难就出现了,因为拥有松弛对偶的近似值不允许我们以简单的方式分支,例如通过利用互补松弛条件。因此,对偶的精确值是必要的。于是学者们提出了一种获得保证界和精确解的一般方法,称为原始对偶VNS (PD-VNS)。它在算法16中给出。

在这里插入图片描述
在第一阶段,一个基于VNS的启发式程序被用来获得一个接近最优的解决方案。

在第二阶段,目标是找到松弛对偶问题的精确解。求解松弛对偶分三个阶段完成:
(1)使用原始启发式解和补充松弛条件找到初始对偶解(通常不可行)
(2)通过将VNS应用于对偶的无约束非线性形式来寻找可行解
(3)使用在对偶变量上应用“窗口”的定制“滑动单纯形”算法,从找到的初始可行解开始精确地求解对偶,从而大大减小了问题的大小。在所有测试的问题上,包括比文献中以前报道的大得多的例子,该程序能够在合理的计算时间内找到精确的对偶解。

在第三和最后阶段,分别从第一阶段的启发式原始解和第二阶段的精确对偶解获得严格的上界和下界,应用标准分支定界算法来寻找原始问题的最优解。

每当在分支树的节点处获得新的整数解时,用对偶滑动单纯形法更新下界,并更新上界。通过这种方式,对于统一的固定成本,有可能精确地解决规模高达7000个设施×7000个用户的问题实例,甚至15000个设施×15000个用户的问题实例。


六、求解混合整数线性规划的VNS


七、连续全局优化的可变邻域搜索


八、可变邻域编程(VNP):自动编程的VNS


九、Discovery Science


十、总结

提出并讨论了变邻域搜索的一般方案。为了评估与VNS相关的研究进展,我们需要一个元启发式的可取属性列表。

  1. 简单性:元启发式应该基于一个简单明了的原则,这个原则应该广泛适用
  2. 严谨:元启发式的步骤应该用严谨的数学术语来表述,独立于可能是灵感最初来源的物理或生物类比
  3. 连贯性:为解决特定问题而开发的所有启发式步骤都应该自然地遵循元启发式原则
  4. 有效性:对特定问题的启发应该为所有已知的或至少是最现实的情况提供最优或接近最优的解决方案。最好是,他们应该为大多数已知解决方案的基准问题找到最优解决方案
  5. 效率:针对特定问题的启发式算法应该花费适度的计算时间来提供最优或接近最优的解决方案,或者比最先进的解决方案更好的解决方案
  6. 鲁棒性:元启发式算法的性能应该在各种情况下都是一致的,也就是说,不仅仅是对一些训练集进行微调,而在其他地方并不那么好
  7. 用户友好性:元启发式应该表达清楚,易于理解,最重要的是,易于使用。这意味着它应该有尽可能少的参数,最好没有
  8. 创新:元启发法的原理或由此衍生的启发法的效率和有效性应该导致新类型的应用
  9. 一般性:元启发式应该对各种各样的问题产生好的结果
  10. 交互性:元启发式应该允许用户结合他的知识来改进解决过程
  11. 多重性:元启发式应该能够产生几个接近最优的解决方案,用户可以从中进行选择

我们试图在这里表明,VNS在很大程度上拥有所有上述性质。这个框架导致了启发式,这是解决许多问题的最佳方法之一。人们对VNS的兴趣正在迅速增长。每年发表的关于这一主题的论文越来越多就证明了这一点。20年前,只有几个;15年前,大概十几个;10年前50篇左右,2016年250多篇。

图3.8显示了关于VNS和其他最著名的元试探法的论文数量的平行增长。数据是通过使用Scopus搜索工具获得的,查找术语“可变邻域搜索”(VNS)和“元启发式搜索”(MH)。图3.8显示了这些术语在该数据库的论文摘要中出现的次数。使用的年份是从2000年到2017年,但2017年只包括前6个月(从1月到6月)。为了便于比较,用MH的论文数除以4。

在这里插入图片描述

图3.9显示了关于VNS和其他最著名的元试探法的论文数量的平行增长。再次从Scopus搜索工具收集数据,以查找术语可变邻域搜索(VNS)、禁忌搜索(TS)、遗传算法(GA)和模拟退火(SA)。为了更好地说明,TS、GA和SA的出现次数分别除以3、50和10。

在这里插入图片描述

从上图可以很容易地看出,VNS论文数量的相对增长大于其他主要元启发式方法,尤其是在最近5年。


十一、案例讲解&代码实战

【运筹优化】VNS变邻域搜索算法求解TSP问题 + Java代码实现

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

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

相关文章

如何视频转语音?想知道视频转语音工具怎么用?

在教育、培训等领域中&#xff0c;有时候需要将讲解视频转化为文字来提供给学生反复阅读学习。那么&#xff0c;小伙伴们&#xff0c;你们知道怎样视频转语音吗&#xff1f;其实我们可以借助一些视频转语音的软件帮助我们实现视频转语音操作。这篇文章就给大家分享几个非常好用…

PHP学习笔记第二天

前言 作者简介&#xff1a;不知名白帽&#xff0c;网络安全学习者。 博客主页&#xff1a;不知名白帽的博客_CSDN博客-网络安全,CTF,内网渗透领域博主 网络安全交流社区&#xff1a;https://bbs.csdn.net/forums/angluoanquan 目录 PHP类型比较 和 PHP中比较0、false、null …

基于SSM的酒店管理系统代码数据库文件和LW

框架&#xff1a;SSM 数据库&#xff1a;MySQL 语言&#xff1a;Java 下载链接&#xff1a; https://download.csdn.net/download/yw1990128/87853243 B站演示链接&#xff1a; 基于SSM框架的酒店管理系统_哔哩哔哩_bilibili 1.1 课题研究背景及意义 随着我国改革开放的不…

hutool文件导出

hutool文件导出 需求&#xff1a;管理员设置会议&#xff0c;参加会议会根据管理员设置的会议要求&#xff0c;用户参加会议填写相关数据&#xff0c;并且生成一个动态的excel数据并导出 示例&#xff1a; 每场都可以自定义报名字段 根据需求与前端约定 字段名称&#xff08;n…

通用读写仲裁模块(FPGA实现)

当涉及多个模块向同一个模块进行读写操作、向一个半双工模块请求读写&#xff0c;甚至综合一下&#xff0c;多个模块向一个半双工模块发起读写请求&#xff0c;那就要涉及读写仲裁。因为最近做的项目中涉及的读写仲裁太多了&#xff0c;所以就想还是要写一个通用的读写仲裁模块…

网络协议系统学习

网络为什么要分层&#xff1f; 因为是个复杂的程序就要分层 可以把网络包想象成一个buffer或者一块内存&#xff0c;是有格式的。同时&#xff0c;想象自己是一个处理网络包的程序&#xff0c;而且这个程序可以跑在电脑/服务器/路由器/交换机上&#xff0c;自己有很多网口&am…

抖音seo优化源码搭建/搜索排名系统,技术理论分析搭建中。

抖音seo系统源码SaaS&#xff0b;源码私有化部署搭建&#xff0c;抖音seo源码&#xff0c;抖音seo系统源码&#xff0c;抖音seo系统搭建部署&#xff0c;抖音已经成为了当今最为流行的短视频平台之一&#xff0c;拥有着庞大的用户群体和海量的视频资源。对于一些商家或者运营者…

26岁,几乎零基础,想从基础学习渗透测试该如何进行?

要成为一名渗透测试员&#xff0c;想从基础学习需要先掌握下面这3块&#xff08;文末有相关自学资源推荐&#xff09;&#xff1a;1、学习硬件和网络 渗透测试主要涉及网络和部分涉及硬件。 2、操作系统和系统架构 操作系统和系统架构在渗透测试中起着关键作用。系统操作涉及x…

笔试强训6

作者&#xff1a;爱塔居 专栏&#xff1a;笔试强训 作者简介&#xff1a;大三学生&#xff0c;希望和大家一起进步&#xff01; 1.下列关于ThreadLocal的描述中&#xff0c;错误的是&#xff08;&#xff09; A.ThreadLocal采用线程隔离的方式存放数据&#xff0c;可以避免多线…

社区网格化管理系统

在传统的城市管理过程中存在的问题&#xff1a; 1、问题发现不及时&#xff0c;被管理对象不清楚。 2、管理部门职责不清&#xff0c;协调成本高。 3、城市管理整体情况缺乏数据支撑。 4、基层力量薄弱。 凡尔码搭建社区网格化管理系统依托统一的城市管理以及数字化的平台&…

Codeforces Round 875 (Div. 2)(A—D)

文章目录 A. Twin Permutations1、分析2、代码 B. Array merging1、分析2、代码 C. Copil Copac Draws Trees1、分析2、代码 D. The BOSS Can Count Pairs1、分析2、代码 A. Twin Permutations A. Twin Permutations 1、分析 作者这里的构造方法是让最终的数组满足&#xff…

linux安装jdk8

1.下载jdk8 https://www.oracle.com/java/technologies/downloads/#java8 2.上传jdk &#xff08;1&#xff09;将jdk源码包&#xff0c;上传到/usr/local &#xff08;2&#xff09;进入上传jar包目录 [rootiZ2ze7vthdl3oh0n0hzlu7Z ~]# cd / [rootiZ2ze7vthdl3oh0n0hzlu…

C语言之字符串,内存操作函数详解(一)

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:C语言学习分享⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多C语言知识   &#x1f51d;&#x1f51d; 字符串函数 1. 前言&#x1f6a9;2…

电池管理系统 (BMS)

现今的电子设备&#xff0c;小至TWS耳机和可穿戴设备&#xff0c;大至电动汽车&#xff0c;都离不开锂离子或聚合物电池的供电。依据电子设备所需电力的大小&#xff0c;电池组可能由多个电池单元(电芯)排列而成。电池组的充电和放电、输入/输出电压和电流等状态都需要精密监控…

2023年6月DAMA-CDGP数据治理专家认证,你考了吗?

DAMA认证为数据管理专业人士提供职业目标晋升规划&#xff0c;彰显了职业发展里程碑及发展阶梯定义&#xff0c;帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力&#xff0c;促进开展工作实践应用及实际问题解决&#xff0c;形成企业所需的新数字经济下的核心职业…

小白系统地学习it技术--python的心得体会

我对我所学习的IT技术的理解 一、it技术介绍——python二、我学习python前的准备工作三、学习时的具体操作1. 在pycharm练习python&#xff0c;唯手熟尔&#xff01;&#xff01;2. 在bilibili看python学习视频3. 报错了&#xff0c;CSDN是你的不二选择&#xff01;4.找代码&am…

【开发日志】2023.05 ZENO----PrimitiveCurvature----曲率分析工具(几何体、图像、点云)

Screen Space Ambient Occlusion - TDA362/DIT223 - Computer Graphics Labs (chalmers.se)https://www.cse.chalmers.se/edu/course/TDA362/tutorials/ssao.html GAMES102在线课程-刘利刚 (ustc.edu.cn)http://staff.ustc.edu.cn/~lgliu/Courses/GAMES102_2020/default.html …

我给自己搭建的前端导航网站,你们都别用

欢迎关注我&#x1f970;&#x1f970;&#x1f970; 主页传送门&#xff0c;持续产出有思考的文档&#xff5e; &#x1f4a5; 想法来源 前段时间在工作的时候&#xff0c;因为遇到了一些之前没了解过的知识&#xff0c;所以化身百度cv工程师&#xff0c;上网冲浪寻找灵感&am…

第六十一天学习记录:C语言进阶:C语言预处理1

程序的翻译环境和执行环境 在ANSI C的任何一种实现中&#xff0c;存在两个不同的环境。 第一种是翻译环境&#xff0c;在这个环境中源代码被转换为可执行的机器指令。第2种是执行环境&#xff0c;它用于实际执行代码。 详解编译链接 翻译环境 ![在这里插入图片描述](https:/…

实战:单点登录的两种实现方式,附源码

最近工作有点忙&#xff0c;好久没更新文章了&#xff0c;正好这两天在整理单点登陆相关的文档&#xff0c;今天趁着小孩睡着了&#x1f92b;&#xff0c;赶紧码一篇实战文交差。 概念 单点登录&#xff08;Single Sign-On&#xff0c;SSO&#xff09;是一种身份验证服务&…