之前笔者曾经简要介绍过模拟退火算法求解 TSP 问题的代码示例:
模拟退火算法求解 TSP 问题的代码示例

本文以 TSP 问题为例,通过具体代码,说明禁忌搜索算法的迭代过程。

禁忌搜索算法流程图

TSP 问题的代码示例

关于 TSP 问题的介绍从略,算法模块的代码(algorithm.py)如下,注释中已说明算法的迭代过程:

from datetime import datetime
from typing import Tuple, List, Set
import randomimport pandas as pdclass TabuSearch(object):"""禁忌搜索"""def __init__(self, num_point: int, mat_dist: List[List[float]],num_iter: int = 100, len_tabu: int = 10, size_neighbour: int = 50):"""禁忌搜索,数据初始化:param num_point:  TSP 节点数量:param mat_dist:  距离矩阵:param num_iter:  迭代次数:param len_tabu:  禁忌表长度:param size_neighbour:  邻域搜索的次数"""# 问题参数self.num_point = num_pointself.mat_dist = mat_dist# 算法参数self.num_iter = num_iterself.len_tabu = len_tabuself.size_neighbour = size_neighbour# 结果self.route_opt, self.distance_opt = [], None  # 最优路径、最优路径距离self.route_res, self.distance_res = [], None  # 结果路径、结果路径距离def run(self):"""算法运行:return: 无"""dts = datetime.now()random.seed(1024)# 初始解route = self._init_solution()obj = self._get_distance(route=route)self.route_opt, self.distance_opt = route, objprint("初始解: {}".format(self.route_opt))print("初始解的路径距离: {}".format(self.distance_opt), '\n')# 禁忌表list_tabu = []# loop 1: 迭代次数 NGfor i in range(self.num_iter):print("当前迭代次数: {}".format(i + 1), '\n')# loop 2: 邻域搜索 Sdf_neighbour = pd.DataFrame(columns=["route", "change", "distance"])for _ in range(self.size_neighbour):route_, set_change = self._create_new_solution(route=route)distance = self._get_distance(route=route_)tmp_df = pd.DataFrame({"route": [route_], "change": [set_change], "distance": [distance]})df_neighbour = df_neighbour.append(tmp_df)df_neighbour = df_neighbour.sort_values(by="distance", ascending=True)df_neighbour.reset_index(drop=True, inplace=True)# 更新解for _, df in df_neighbour.iterrows():# case 1: 当前邻域最优解可优化全局最优解if df["distance"] < self.distance_opt:route = df["route"]self.route_opt, self.distance_opt = route, df["distance"]print("发现可优化全局最优解的新解: {}".format(self.route_opt))print("变化节点: {0},  路径距离: {1}".format(df["change"], self.distance_opt), '\n')list_tabu.append(df["change"])  # 更新禁忌表break# case 2: 当前邻域最优解被禁忌elif df["change"] in list_tabu:print("当前邻域最优解被禁忌,节点变化: {}".format(df["change"]), '\n')continue# case 3: 接收劣解else:route = df["route"]print("接收劣解: {}".format(route))print("变化节点: {0},  路径距离: {1}".format(df["change"], df["distance"]), '\n')list_tabu.append(df["change"])  # 更新禁忌表break# 禁忌表长度if len(list_tabu) > self.len_tabu:print("禁忌表长度过大,释放元素: {}".format(list_tabu[: len(list_tabu) - self.len_tabu]), '\n')list_tabu = list_tabu[-self.len_tabu:]# 运行结果self.route_res = route.copy()self.distance_res = objprint("结果路径: {}".format(self.route_res))print("结果路径距离: {}".format(self.distance_res), '\n')print("最优路径: {}".format(self.route_opt))print("最优路径距离: {}".format(self.distance_opt), '\n')dte = datetime.now()tm = round((dte - dts).seconds + (dte - dts).microseconds / (10 ** 6), 3)print("算法运行时间: {} s".format(tm), '\n')def _init_solution(self):"""初始解:return: route:  初始路径"""route = [i for i in range(self.num_point)]return routedef _get_distance(self, route: List[int]) -> float:"""计算路径距离:param route:  路径:return:  距离"""distance = sum(self.mat_dist[route[i]][route[i + 1]] for i in range(len(route) - 1))return distancedef _create_new_solution(self, route: List[int]) -> Tuple[List[int], Set]:"""产生一个新解:param route:  当前解:return: route_:  生成的新解:return: set_change:  交换位置的节点"""route_ = route.copy()# 通过随机交换两个位置的方式产生新解pos1, pos2 = random.randint(0, self.num_point - 1), random.randint(0, self.num_point - 1)while pos1 == pos2:pos1, pos2 = random.randint(0, self.num_point - 1), random.randint(0, self.num_point - 1)tmp, route_[pos1] = route_[pos1], route_[pos2]route_[pos2] = tmp# 交换位置的节点set_change = {route_[pos1], route_[pos2]}return route_, set_change

生成随机算例,并调用算法模块进行求解的主程序代码(main.py)如下:

from datetime import datetime
import math
import randomfrom algorithm import TabuSearchdts = datetime.now()""" 参数 """# 地点数量
num_point = 20# 坐标范围、边界宽度
ran_coo = (0, 100)
edge = 1# 坐标列表、距离矩阵
random.seed(1024)
list_coo = [(random.randint(ran_coo[0] + edge, ran_coo[1] - edge),random.randint(ran_coo[0] + edge, ran_coo[1] - edge)) for _ in range(num_point)]
mat_dist = [[math.sqrt((list_coo[i][0] - list_coo[j][0]) ** 2 + (list_coo[i][1] - list_coo[j][1]) ** 2)for j in range(num_point)] for i in range(num_point)]""" 算法 """num_iter, len_tabu, size_neighbour = 1000, 10, 50
tabu_search = TabuSearch(num_point=num_point, mat_dist=mat_dist,num_iter=num_iter, len_tabu=len_tabu, size_neighbour=size_neighbour)
tabu_search.run()dte = datetime.now()
tm = round((dte - dts).seconds + (dte - dts).microseconds / (10 ** 6), 3)
print("程序运行总时间: {} s".format(tm), '\n')

参考资料

汪定伟《智能优化方法》

禁忌搜索算法求解 TSP 问题的代码示例相关推荐

  1. 禁忌搜索算法求解TSP旅行商问题Matlab实现

    一. 禁忌搜索算法 禁忌搜索算法是一种全局性邻域搜索算法,模拟人类具有记忆功能的寻优特征.它通过局部邻域搜索机制和相应的禁忌准则来避免迂回搜索,并通过破禁水平来释放一些被禁忌的优良状态,进而保证多样化 ...

  2. 遗传-粒子群算法遗传-禁忌搜索算法求解TSP问题

    1. 前言 上一篇博文[五种常见启发式算法求解TSP问题-总结篇]中,总结了五种常见启发式算法在求解TSP问题上的效果,其中遗传算法的求解质量最差,而粒子群算法和禁忌搜索算法的求解效果最佳,因此本文计 ...

  3. 实验10 禁忌搜索算法求解tsp问题

    传送门(所有的实验都使用python实现) 实验1 BP神经网络实验 实验2 som网实验 实验3 hopfield实现八皇后问题 实验4 模糊搜索算法预测薄冰厚度 实验5 遗传算法求解tsp问题 实 ...

  4. 基于改进禁忌搜索算法求解TSP问题(Matlab代码实现)

    目录 1 概述 2 改进禁忌搜索算法 3 运行结果 4 参考文献 5 Matlab代码实现 1 概述 当城市数量较少时,理论上可以通过穷举法来列举出最优方案,然而当城市数量较多时,所有路线之和将呈指数 ...

  5. 禁忌搜索算法求解TSP旅行商问题C++(2020.11.19)

    TS算法求解TSP问题C++ 1.禁忌搜索算法 1.1 基本思想及主要特点 1.2 基本概念 1.3 算法流程 2. TS求解TSP问题的C++实现 2.1 输入数据文件:bayg29.tsp 2.2 ...

  6. 【优化布局】matlab基于禁忌搜索算法求解基站选址问题代码

    1 简介 物流配送中心选址问题在物流网络规划中占有非常重要的地位,选址的合理与否直接关系到配送中心未来的发展.针对企业选址的一般要求,以配送中心总成本最小为目标,构造了一种物流配送中心选址模型.该模型 ...

  7. 【背包问题】基于禁忌搜索算法求解背包问题附Matlab代码

    1 内容介绍 设计了一种基于禁忌搜索的遗传算法,利用遗传算法提供的并行搜索主框架,结合禁忌算法的个体串行搜索方式,能扩大搜索空间,快速实现全局优化.把基于禁忌搜索的遗传算法与启发式方法相结合用来求解背 ...

  8. 领域搜索算法java_使用JAVA实现算法——禁忌搜索算法解决TSP问题

    packageBasePart;importjava.io.BufferedReader;importjava.io.FileInputStream;importjava.io.IOException ...

  9. 【TS TSP】基于matlab禁忌搜索算法求解31城市旅行商问题【含Matlab源码 1143期】

    一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[TSP]基于matlab禁忌搜索算法求解31城市旅行商问题[含Matlab源码 1143期] 点击上面蓝色字体,直接付费下载,即可. 获取 ...

  10. 惩罚函数外点matlab,禁忌搜索算法求解带时间窗的车辆路径问题(惩罚函数版 附MATLAB代码)...

    本周应小伙伴要求继续学习TS求VRPTW,不过这次通过使用惩罚约束的形式允许解违反时间窗约束和容量约束,不过要给违反约束的解加以惩罚. 这次我们的目标函数就不单单只有车辆总行驶距离了,还要包括当前解中 ...

最新文章

  1. faster rcnn第二阶段loss出现nan_利用Faster_Rcnn训练模型时出现的问题
  2. 基于深度学习的病毒检测技术无需沙箱环境,直接将样本文件转换为二维图片,进而应用改造后的卷积神经网络 Inception V4 进行训练和检测...
  3. 计算机主机核心通常包括,计算机一级考试题库选择题
  4. IPC--进程间通信六(消息队列)
  5. 从代码到部署微服务实战
  6. 奥巴马吐槽川普“笨蛋”的视频火了,这又得“归功”于AI
  7. 【贪心】牛客网:把数组排成最小的数
  8. 程序员代码面试指南:IT名企算法与数据结构题目 PDF 版
  9. 工程经济有何难,思维导图来助阵
  10. 东师奥鹏计算机应用基础19春,东师计算机应用基础19春在线作业1【参考答案】...
  11. [转载]Office文档在线编辑的实现之二
  12. Beyond Compare 4.2.10 zhuce
  13. java学习阶段小结
  14. C语言88案例,经典案例带你绝对入门C编程!
  15. Tomcat8源码解析
  16. 计算机网络驱动坏了怎么解决办法,电脑网卡驱动坏了怎么办
  17. 在AWS EKS部署ALB
  18. 暗组工具箱 荐!!!
  19. 李宁老师:新开公司合伙人股权如何合理安排分配
  20. 2021年初级会计实务会计要素及其确认与计量

热门文章

  1. SQLServer 2008 r2 安装图解
  2. 数据库索引的概念和分类
  3. Flutter安装依赖包
  4. linux下的经典软件总结
  5. 硬件设计漫谈1 —模组设计
  6. 使用MobileTerminal修改越狱后的root密码
  7. RecSys2020推荐系统论文Recommending the Video to Watch Next: An Offline and Online Evaluation at YOUTV.de
  8. 大数据开源舆情分析系统-数据采集技术架构浅析
  9. 三线表里加小短线_快速搞定学术论文中的三线表
  10. html(jsp)登录页面