更多精彩尽在微信公众号【程序猿声】

变邻域搜索算法(Variable Neighborhood Search,VNS)一看就懂的解析

00 目录

  • 局部搜索再次科普
  • 变邻域搜索
  • 造轮子写代码

01 局部搜索科普三连

虽然之前做的很多篇启发式的算法都有跟大家提过局部搜索这个概念,为了加深大家的印象,在变邻域主角登场之前还是给大家科普一下相关概念。热热身嘛~

1.1 局部搜索是什么玩意儿?

官方一点:局部搜索是解决最优化问题的一种启发式算法。对于某些计算起来非常复杂的最优化问题,比如各种NP完全问题,要找到最优解需要的时间随问题规模呈指数增长,因此诞生了各种启发式算法来退而求其次寻找次优解,是一种近似算法(Approximate algorithms),以时间换精度的思想。局部搜索就是其中的一种方法。

通俗一点:局部搜索算法是对一类算法的统称,符合其框架的算法很多,比如之前公众号推文中介绍的爬山法、模拟退火法和禁忌搜索算法都属于局部搜索算法。尽管各个算法在优化过程中的细节存在差异,但在优化流程上呈现出很大的共性。

它的基本原理是在临近解中迭代,使目标函数逐步优化,直至不能再优化为止。

1.2 局部搜索的过程

我们可以将局部搜索算法的统一框架描述为:

  1. 算法从一个或若干个初始解出发。
  2. 在算法参数控制下由当前状态的邻域中产生若干个候选解。
  3. 以某种策略在候选解中确定新的当前解。
  4. 伴随控制参数的调节,重复执行上述搜索过程,直至满足算法终止准则。
  5. 结束搜索过程并输出优化结果。

1.3 局部搜索的几大要素

局部搜索算法主要包含五大要素:

  1. 目标函数:用来判断解的优劣。
  2. 邻域的定义:根据不同问题,有着不同的邻域定义。
  3. 初始解的产生规则
  4. 新解的产生和接受规则
  5. 算法终止准则

其中前两个要素的定义和算法要解决的特定问题有关,而且不同的人对同一问题可能有完全不同的定义。后三个要素定义的不同则会产生各种不同的局部搜索算法,而它们的效率和最终解的质量也会有很大的差异。

02 变邻域搜索算法

2.1 什么是VNS?

对上面的局部搜索有一定的印象以后,理解变邻域搜索也不难了。其实说白了,变邻域搜索算法(VNS)就是一种改进型的局部搜索算法。它利用不同的动作构成的邻域结构进行交替搜索,在集中性和疏散性之间达到很好的平衡。其思想可以概括为“变则通”。

变邻域搜索依赖于以下事实:

  • 一个邻域结构的局部最优解不一定是另一个邻域结构的局部最优解。
  • 全局最优解是所有可能邻域的局部最优解。

它由主要由以下两个部分组成:

  • variable neighborhood descent (VND)
  • shaking procedure

大家别急,下面我们将会对这两个部分进行分析。然后,before that……

2.2 你们一定想知道邻域是什么?

官方一点:所谓邻域,简单的说即是给定点附近其他点的集合。在距离空间中,邻域一般被定义为以给定点为圆心的一个圆;而在组合优化问题中,邻域一般定义为由给定转化规则对给定的问题域上每结点进行转化所得到的问题域上结点的集合。

通俗一点:邻域就是指对当前解进行一个操作(这个操作可以称之为邻域动作)可以得到的所有解的集合。那么邻域的本质区别就在于邻域动作的不同了。

2.3 还是要说说邻域动作

邻域动作是一个函数,通过这个函数,对当前解s,产生其相应的邻居解集合。例如:对于一个bool型问题,其当前解为:s = 1001,当将邻域动作定义为翻转其中一个bit时,得到的邻居解的集合N(s)={0001,1101,1011,1000},其中N(s) ∈ S。同理,当将邻域动作定义为互换相邻bit时,得到的邻居解的集合N(s)={0101,1001,1010}。

2.4 variable neighborhood descent (VND)

VND其实就是一个算法框架,它的过程描述如下:

  1. 初始解S,定义M个邻域,记为Nk(k = 1, 2, 3......m),i = 1。
  2. 使用邻域结构Ni进行搜索,直到陷入局部最优解S′ 。
  3. 如果S′ 优于S,令S=S′,i=1; 否则,i++。
  4. 如果i≤m ,转步骤2。
  5. 输出最优解S。

我知道没图你们是不会点进来的……

VND的图解如下:

只说两点,再问自杀:

  • 当在本邻域搜索找不出一个比当前解更优的解的时候,我们就跳到下一个邻域继续进行搜索。如图中虚黑线所示。
  • 当在本邻域搜索找到了一个比当前解更优的解的时候,我们就跳回第一个邻域重新开始搜索。如图中红线所示。

之前我们把局部搜索比喻作爬山的过程,那么每变换一次邻域,也可以理解为切换了搜索的地形(landscape)。效果如下 :

每一次跳跃,得到都是一个新的世界……

伪代码描述如下:

2.5 shaking procedure

其实呀,这玩意儿。说白了就是一个扰动算子,类似于邻域动作的这么一个东西。通过这个算子,可以产生不同的邻居解。虽然名词很多看起来很高大上,扰动、抖动、邻域动作这几个本质上还是没有什么区别的。都是通过一定的规则,将一个解变换到另一个解而已。这里读者还是抓其本质,不要被表象所迷惑了就好。

2.6 VNS过程

在综合了前面这么多的知识以后,VNS的过程其实非常简单。可以描述为以下几步:

  1. 产生初始解s1。
  2. shaking s1,得到解s2。
  3. 对解s2进行VND,得到解s3。
  4. 如果达到边界条件,结束程序,输出最优解。否则跳回第二步。

结合伪代码,一目了然:

03 变邻域搜索代码应用举例

分别举两个应用实例。

  • 变邻域算法解决TSP问题
  • 变邻域算法解决01背包问题

C++代码。

欲获取代码,请关注我们的微信公众号【程序猿声】,在后台回复:VNS代码。即可获取。

【算法】变邻域搜索算法(Variable Neighborhood Search,VNS)超详细一看就懂的解析的更多相关文章

  1. 【智能算法】变邻域搜索算法(Variable Neighborhood Search,VNS)超详细解析和TSP代码实例以及01背包代码实例

    喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 00 目录 局部搜索再次科普 变邻域搜索 造轮子写代码 01 局部搜索科普三连 虽然之前做的很多篇启发式的算法都有跟大家提过局部 ...

  2. 变邻域搜索(Variable neighborhood search)

    变邻域搜索(Variable neighborhood search)VNS是Hansen等提出的一种元启发近似算法,它通过在不同的邻域结构内跳转搜索, 能够避免陷入局部最优解. 算法主要分为两部分: ...

  3. MIP启发式算法:Variable neighborhood search

    *本文主要记录和分享学习到的知识,算不上原创. *参考文章见链接. 本文主要讲述启发式算法中的变邻域搜索(Variable neighborhood search).变邻域搜索的特色在于邻域结构的可变 ...

  4. 【优化算法】变邻域搜索算法(VNS)求解TSP(附C++详细代码及注释)

    00 前言 上次变邻域搜索的推文发出来以后,看过的小伙伴纷纷叫好.小编大受鼓舞,连夜赶工,总算是完成了手头上的一份关于变邻域搜索算法解TSP问题的代码.今天,就在此给大家双手奉上啦,希望大家能ENJO ...

  5. 【优化算法】变邻域搜索算法解决0-1背包问题(Knapsack Problem)代码实例 已

    01 前言 经过小编这几天冒着挂科的风险,日日修炼,终于赶在考试周中又给大家更新了一篇干货文章.关于用变邻域搜索解决0-1背包问题的代码.怎样,大家有没有很感动? 02 什么是0-1背包问题? 0-1 ...

  6. 干货 | 自适应大邻域搜索(Adaptive Large Neighborhood Search)入门到精通超详细解析-概念篇

    01 首先来区分几个概念 关于neighborhood serach,这里有好多种衍生和变种出来的胡里花俏的算法.大家在上网搜索的过程中可能看到什么Large Neighborhood Serach, ...

  7. 【高级算法】禁忌搜索算法解决3SAT问题(C++实现)

    转载请注明出处:http://blog.csdn.net/zhoubin1992/article/details/46440389 近期梳理,翻出了当年高级算法课程做的题目.禁忌搜索算法解决3SAT问 ...

  8. 【优化算法】Greedy Randomized Adaptive Search算法 超详细解析,附代码实现TSP问题求解

    01 概述 Greedy Randomized Adaptive Search,贪婪随机自适应搜索(GRAS),是组合优化问题中的多起点元启发式算法,在算法的每次迭代中,主要由两个阶段组成:构造(co ...

  9. 数据挖掘领域十大经典算法之—C4.5算法(超详细附代码)

    https://blog.csdn.net/fuqiuai/article/details/79456971 相关文章: 数据挖掘领域十大经典算法之—K-Means算法(超详细附代码)        ...

随机推荐

  1. vue的安装配置与项目创建

    1,安装vue必须先安装node.js.  --------去官网安装node.js 因为npm依赖node.js环境,使用npm的时候需要安装node.js.安装node.js的时候npm会默认安装 ...

  2. Java基础IO类之打印流

    package IODemo; import java.io.*; /* 打印流 : 很方便的进行输出 字节打印流 增强输出功能 字符打印流 */ public class PrintStreamDe ...

  3. AS3.0 位图翻转、旋转

    /* * * *-------------------------* * | *** 位图翻转.旋转 *** | * *-------------------------* * * 作 者:fengz ...

  4. DataSource配置

    一.JDBC Jar依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifac ...

  5. 笔记 - C#从头开始构建编译器 - 1

    视频与PR:https://github.com/terrajobst/minsk/blob/master/docs/episode-01.md 作者是 Immo Landwerth(https:// ...

  6. iOS退出APP

    强制退出有四种: exit(); abort(); assert(); 主动制造一个崩溃: exit() 1.附加了关闭打开文件与返回状态码给执行环境,并调用你用atexit注册的返回函数: 2.警告 ...

  7. 使用SAP Cloud Platform Leonardo机器学习提取图片的特征向量

    选中一个需要进行测试的Leonardo机器学习服务,点击Configure Environments: 因为我不想使用sandbox环境,所以我选择了eu10这个region: 维护clientid和 ...

  8. kubeadm init初始化报错解决,亲测

    [preflight] You can also perform this action in beforehand using 'kubeadm config images pull' error ...

  9. Linux proc filesystem (procfs)

    参考:/proc /proc简介 本文着重关注/proc目录,查看其中文件并熟悉它. /proc目录存在于所有Linux系统上,无论什么发行版或体系结构.首先,必须澄清一个误解: 就文件系统这一术语而 ...

  10. Python_if语句

    1.if语句: color='红色' if color=='蓝色': print('我是蓝色') elif color=='红色': print('我是红色') else : print('未知') ...