ALNS算法(自适应大领域搜索算法)

一、ALNS算法与流程

	自适应大领域搜索算法本质上是一种搜索算法,它的精髓在于用摧毁算子和修复算子对队列进行
摧毁和修复,从而进行启发式的搜索,
	自适应表现在算子的竞争性选择上面。
	算法的大体流程分为这么几步:
	1)生成初始解:初始解的生成可以随机生成,也可以将当前节点的编号按照顺序存储作为初始
解,初始解会影响算法收敛的速度。
	2)重复以下步骤进行迭代直到停止准则
		a.根据算子权重选择破坏与修复算子,并更新算子使用次数
		b.破坏算子和修复算子依次对当前解操作得到新解
		c.更新当前解
		d.更新最优解
		e.更新算子分数
		f.更新算子权重
	3)返回最优解

二、算子选择

	轮盘赌算法是一种归一化的随机选择算法,具体是分配给每个算子一个权重,轮盘赌先求出总的
权重和,之后将每个算子的权重进行归一化处理,之后产生一个随机值,这个随机值落在哪个算子的
权重区间内就选择哪个算子。在具体实现时,也可以不对权重进行归一化,而直接用权重作为区间进
行选择。

三、算子分数更新

	算子分数分为多种情况:
	1)产生的解比最优解优秀,那么加1.52)如果比当前解优秀,那么说明该算子能产生较优解,所以加1.23)如果不比当前解优秀,但是在1%概率内接受了,那么加0.84)如果不比当前解优秀拒接了,那么加0.6分。
	算子分数的更新多少是自己设定的,接受概率也是自己设定的,这几项参数并不绝对。

四、算子权重更新

在这里插入图片描述

	新产生的权重等于上面公式的计算结果。
	其中,ρ是权重更新快慢的参数,w为当前的权重,m为算子的分数,t为算子的使用次数,可以看
出,初始权重较大、且单位使用次数得分较高的算子被选中的概率较高。

五、摧毁算子

	摧毁算子是用来对队列进行摧毁的一类函数,在这里提供三种摧毁思路:
	1、随机摧毁:随机摧毁是ALNS算法不可少的一个摧毁算子,这个算子可以摧毁任意位置的节点。
具体实现为,随机产生N个不重复的节点摧毁位置,对队列进行摧毁。
	2、最大N点摧毁:当前解队列是一个有向的路径,那么对于路径中的任意一个点,都会有唯一的
一个前驱和唯一的一个后继(除首尾节点),所以对每个节点的来和去两条路径的消耗进行统计作为
当前点的消耗,选择最大的N个点移除。
	3、连续递增N节点移除:这个算子会维护一个变量K,每一次都从这个变量开始,选择N个连续的
节点进行摧毁,如果K后面不够N个点,则返回第一个点开始进行补足,每次摧毁后K=(K+1)%num,num
为节点的个数。

六、修复算子

	修复算子是用来对摧毁后的队列进行修复的一类函数,在这里提供两种思路
	1、随机修复:这个算子是必不可少的修复函数,表现为,任意选择N个不重复的插入的节点,将
摧毁算子摧毁后的节点插入到对应的位置。
	2、最小N点插入:对于每一个摧毁节点,对摧毁队列的每一个位置进行试插入,统计每个位置的
消耗,选择插入使得总增加的消耗最小的位置进行插入。下一个节点要在前一个节点已经插入的基础
上进行消耗的判别。

七、C++代码实现参考框架

在这里插入图片描述

	其中,Data类包含存储和操作数据的所有数据和操作,Operator包含算子和算子分数更新等一
系列的算子相关的资源,control层用于实现ALNS算法的流程,view可以根据需要,选择前后端分离
的实现方式,比如用vc6.0写后端数据处理,用qt写前端显示页面等。
	
	Data类设计:
	
	属性设计:
	1)最优解队列:用于保存最优解队列的节点编号
	2)当前解队列:用于保存当前解队列的节点编号
	3)摧毁队列:用于保存去除了摧毁节点的剩下的队列
	4)摧毁节点队列:用于保存被去除的节点的队列
	5)消耗矩阵:用来保存任意两点的消耗(可优化)
	操作设计:
	1)路径消耗函数:用于统计任意一个队列的路径的消耗
	2)更新当前解函数:用来根据算子分数更新的几种情况来更新当前解,并返回更新种类
	3)更新最优解函数:用来评估当前解和最优解消耗,更新最优解
	4)摧毁函数:传入下标队列,对当前解队列进行摧毁
	5)修复函数:传入下标队列,用于将摧毁节点队列中的节点加入摧毁队列
	
	Operator类设计:
	
	算子类采用继承的方式,算子的使用次数更新、分数更新、权重更新、以及轮盘赌选择算子这几
个函数都写在Operator类(基类)里面,摧毁算子(OperatorDes)和修复算子(OperatorFix)各
一个类,继承于这个基类,下面详细介绍修复算子的设计,摧毁算子和修复算子设计相同。
	
	OperatorFix:
	
	属性设计:
	1)权重更新系数
	2)算子分数队列
	3)算子权重队列
	4)算子使用次数队列
	操作设计:
	1)两个修复算子函数:产生N个节点的修复下标队列,真正的摧毁在Data类中进行。
	接口设计:
	1)Fix(n,data):这是一个函数,供外部调用,在里面根据传入的算子编号n,选择对应的
修复算子,对data进行操作,这样外部只需要通过OperatorFix继承于Operator的轮盘赌选择算子
选择出对应的算子,传入即可进行对应的修复,而不需要知道具体的修复的细节。
	
	Control类设计:
	属性设计:
	1)Data数据类的实例
	2)OperatorFix类的实例
	3)OperatorDes类的实例
	操作设计:
	1)运行函数:按照文章最一开始提到的流程,调用对应的函数,需要注意的是参数的传递。

	界面显示设计:前面提到了前后端分离,这里提供三种前后端分离的实现方式:
	1)文件传输数据
	2)socket网络编程传输套接字
	3)c++利用管道、信号量等技术实现通信
  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
这段引用提到了ALNS算法的使用方法和一些相关的操作符,但并没有直接回答您的问题。不过,我可以为您提供一些关于ALNS算法的基本介绍和使用方法。 ALNS(Adaptive Large Neighborhood Search)算法是一种启发式算法,用于解决组合优化问题。它通过在每次迭代中随机选择一组邻域操作来搜索解空间,并根据当前问题实例的特征自适应地调整邻域操作的选择概率。ALNS算法已经在许多领域得到了广泛的应用,例如路线规划、生产调度、旅行商问题等。 要使用ALNS算法,您需要安装ALNS库。您可以使用以下命令在终端中安装ALNS库: ``` pip install alns ``` 安装完成后,您可以使用以下代码导入ALNS库: ```python from alns import ALNS ``` 接下来,您可以根据您的问题实例化ALNS对象,并添加适当的操作符。例如,您可以使用以下代码创建一个ALNS对象,并添加一些操作符: ```python from alns import ALNS from alns.operators import random_removal, path_removal, worst_removal, greedy_repair alns = ALNS(random_state) alns.add_destroy_operator(random_removal) alns.add_destroy_operator(path_removal) alns.add_destroy_operator(worst_removal) alns.add_repair_operator(greedy_repair) ``` 这里,我们使用了random_removal、path_removal和worst_removal三个销毁操作符,以及greedy_repair一个修复操作符。这些操作符将在每次迭代中随机选择,并用于搜索解空间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值