变领域搜索算法


作者福建农林大学在读计算机科学与技术研究生,研究方向智能计算与机器学习。微信公众号 小平讲算法

由于最近项目中需要用到变邻域搜索算法,但是网上关于 VNS 的介绍太少,所以我打算自己写一个关于变领域搜素算法(VNS)的博客.

1. 什么是变邻域搜索算法(VNS)

VNS是局部搜索算法的一种,局部搜索算法可以用来求解一些函数的极小值,但不一定能求到该函数的最小值。那为什么我们要用局部搜索算法呢,因为有些函数它的计算量可能很大,是维数灾难型 的,即在涉及到向量的计算的问题中,随着维数的增加,计算量呈指数倍增长的一种现象。而局部算法目的就是在尽可能短的时间内求一个近似最优解的极小值。话不多说,接下来介绍文章中的正角。
Markdown编辑器

2. VNS的结构

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

  1. 变邻域下降(variable neighborhood descent (VND))
  2. 邻域扰动(shaking procedure)产生新的邻域结构

2.1 VND

这个VND和VNS到底有什么区别,我搞了好久才弄明白,它的算法框架是这样的:

  1. 定义初始解s,定义邻域范围(即邻域解个数M),记作Nk(k=1,2,3,…,M);
  2. 用初始解(当前解)开始搜索,直到陷入局部最优解N1(或Nk);
  3. 如果N1优于s(或者Nk优于s),令s=N1(或s=Nk)。否则k++;
  4. 如果k<M,转步骤2;
  5. 输出最优解。

借用网上的图
没有表述

2.2 shaking procedure

就是用一个扰动算子进行扰动操作,产生不同的领域解结构,其实和VND中的第二步一样。VND其实可以理解成一个爬山算法操作,我是这样理解的。

比如有一个s领域结构(1,2,3,4)你要进行爬山算法,只能在该序列基础上进行两两交换则有6种情况 (2,1,3,4),(3,2,1,4),(4,2,3,1),(1,3,2,4),(1,4,3,2),(1,2,3,4) 。然后你可以对s领域结构产生一个扰动,比如(2,3,1,4),接着你在用爬山算法。这个爬山算法可以理解为那个VND操作。

2.3 VNS

在前面讲述了VDN和shaking procedure过程之后,VNS可以描述为以下步骤:

  1. 产生初始解S;
  2. 对初始解进行shaking procedure,得到邻域解S1
  3. 对S1进行VND操作,得到邻域解S2
  4. 如果达到停止条件,则结束算法,否则跳回第二步。

伪代码在这里插入图片描述

3. 小结

对于闭环设施布局,h,v可以当作当作VDN的领域个数,然后针对每个h,v的排列采用爬山算法,就是一个VDN算法了

  • 6
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
对于领域搜索算法,有很多种不同的方法和实现。其中一种常见的领域搜索算法是启发式搜索算法,比如A*算法。下面是一个简单的用Python实现A*算法的示例代码: ```python import heapq def heuristic(node, goal): # 计算启发式估计值 return abs(node[0] - goal[0]) + abs(node[1] - goal[1]) def astar_search(start, goal, graph): # 初始化open列表和closed集合 open_list = [] closed_set = set() # 将初始节点加入open列表 heapq.heappush(open_list, (0, start)) # 初始化节点到达起点的代价(g值)字典 g_values = {start: 0} while open_list: # 从open列表中取出代价最小的节点 current_cost, current_node = heapq.heappop(open_list) # 如果当前节点是目标节点,则搜索完成,返回路径 if current_node == goal: path = [] while current_node in graph: path.append(current_node) current_node = graph[current_node] return path[::-1] # 将当前节点加入closed集合 closed_set.add(current_node) # 遍历当前节点的邻居节点 for neighbor in graph[current_node]: # 计算邻居节点到起点的代价(g值) new_cost = g_values[current_node] + graph[current_node][neighbor] if neighbor not in g_values or new_cost < g_values[neighbor]: # 更新邻居节点到起点的代价(g值) g_values[neighbor] = new_cost # 计算邻居节点的优先级(f值) priority = new_cost + heuristic(neighbor, goal) # 将邻居节点加入open列表 heapq.heappush(open_list, (priority, neighbor)) # 更新邻居节点的父节点 graph[neighbor] = current_node # 如果open列表为空,说明无法找到路径 return None # 测试代码 graph = { 'A': {'B': 5, 'C': 10}, 'B': {'D': 3, 'E': 2}, 'C': {'F': 6}, 'D': {'G': 8}, 'E': {'G': 7}, 'F': {'G': 4}, 'G': {} } start = 'A' goal = 'G' path = astar_search(start, goal, graph) if path: print("找到路径:", path) else: print("无法找到路径") ``` 这段代码实现了一个简单的A*算法,用于在给定的图中寻找从起点到目标点的最短路径。你可以根据自己的需求调整图的表示方式和启发式函数。希望能对你有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值