文章目录

  • 禁忌搜索
    • 一、局部领域搜索
    • 二、TS算法
      • 2.1 **通过针对爬山法的分析,提出了TS搜索算法:**
      • 2.2 **TS算法的特点:**
      • 2.3 **TS算法构成要素:**
      • 2.3 禁忌搜索特点
  • 三、TS算法举例
  • TS解TSP问题

禁忌搜索

适用于离散化变量求解。

一、局部领域搜索

又称爬山启发式算法,从当前的节点开始,和周围的邻居节点的值进行比较。如果当前节点是最大的,那么返回当前节点,作为最大值(即山峰最高点);反之就用最高的邻居节点替换当前节点,从而实现向山峰的高处攀爬的目的。它是禁忌搜索的基础,TS算法是在其上改进而来。

优点:

  • 容易理解,容易实现,具有较强的通用性;

  • 局部开发能力强,收敛速度很快。

缺点:

  • 全局开发能力弱,只能搜索到局部最优解;

  • 搜索结果完全依赖于初始解和邻域的映射关系。

    二、TS算法

    2.1 通过针对爬山法的分析,提出了TS搜索算法:

    算法的基本思想:采用邻域选优的搜索方法,为了逃离局部最优解,算法必须能够接受劣解,也就是每一次得到的解不一定优于原来的解。但是,一旦接受了劣解,算法迭代即可能陷入循环。为了避免循环,算法将最近接受的一些移动放在禁忌表中,在以后的迭代中加以禁止。即只有不在禁忌表中的较好解(可能比当前解差)才能接受作为下一代迭代的初始解。随着迭代的进行,禁忌表不断更新,经过一定的迭代次数后,最早进入禁忌表的移动就从禁忌表中解禁退出。

    • 改进1:接受劣解。

    • 改进2:引入禁忌表。

    • 改进3:引入长期表和中期表。

    2.2 TS算法的特点:

    • 1、基本思想——避免在搜索过程中的循环
    • 2、只进不退的原则,通过禁忌表实现
    • 3、不以局部最优作为停止准则
    • 4、邻域选优的规则模拟了人类的记忆功能

    2.3 TS算法构成要素:

    (1)编码方式

    将不相同的n件物品分为m组,可以用的编码:

    a、带分隔符的顺序编码
    以自然数1~n分别代表n件物品,n个数加上

    m-1个分割符号混编在一起,随机排列。如:1-3-4-0-2-6-7-5-0-8-9
    

    b、自然数编码
    编码的每一位分别代表一件物品,而每一位的值代表该物品所在的分组。

    如:1-2-1-1-2-2-2-3-3
    

    (2)初始解的获取

    可以随机给出初始解,也可以事先使用其他启发式等算法给出一个较好的初始解。

    (3)移动邻域

    移动是从当前解产生新解的途径,例如上述问题中用移动s产生新解s(x)。
    从当前解可以进行的所有移动构成邻域,也可以理解为从当前解经过“一步”可以到达的区域。

    (4)禁忌表
    禁忌表的作用:防止搜索出现死循环

    • 记录前若干步走过的点、方向或目标值,禁止返回

    • 表是动态更新的

    • 表的长度称为Tabu-Size

      禁忌表的主要指标(两项指标)

    • **禁忌对象:**禁忌表中被禁的那些变化元素

    • **禁忌长度:**对象的禁忌在多少次迭代后失效。

      • 禁忌长度:可以是一个固定的常数(T=c),也可以是动态变化的,可按照某种规则或公式在区间内变化

        • 禁忌长度过短,一旦陷入局部最优点,出现循环无法跳出;
        • 禁忌长度过长,候选解全部被禁忌,造成计算时间较大,也可能造成计算无法继续下去。
      • 禁忌对象(三种变化)

        • 以状态本身或者状态的变化作为禁忌对象
        • 以状态分量以及分量的变化作为禁忌对象
        • 采用类似的等高线做法,以目标值变化作为禁忌对象

    (5)渴望水平函数

    A(x,s)一般为历史上曾经达到的最好目标值,若有C(s(x))<A(x,s)则S(x)是不受T表限制。即使s(x)∈T,仍可取x=s(x)。A(x,s)称为渴望水平函数。

    (6)停止准则
    (1)给定最大迭代步数(最常用 )
    (2)设定某个对象的最大禁忌频率。
    (3)设定适配值的偏离阈值。

    TS算法流程图:

    2.3 禁忌搜索特点

    • 禁忌搜索适用于离散优化,不适合实优化
    • 局部邻域搜索:贪婪、持续在当前的邻域中搜索,直至领域中没有更好的解

    三、TS算法举例

    由7层不同的绝缘材料构成的一种绝缘体,应如何排列顺序,可获得最好的绝缘性能。

    • 编码方式:顺序编码

    • 初始编码:2-5-7-3-4-6-1

    • 目标值:极大化目标值。

    • 邻域移动:两两交换

    • 禁忌表长度(TabuSize):3

    • 迭代次数(NG):5

    注意:左边的表为候选表,右边的表为禁忌表,若任意两两交换的次数过多可能计算缓慢,因此可以规定候选表的长度,每次随机选择两个交换,直到候选表被填满。

TS解TSP问题

TS算法受禁忌表长度、邻域选择方式、以及初始值的影响比较 严重,且经检验极易陷入局部最优值(不知道是不是参数设置原因),且耗时较长。

用python给出TS解TSP问题的代码

# -*- coding: utf-8 -*-
# @Time : 2022/2/17 15:01
# @Author : Orange
# @File : ts1.py.py
import copy, random, datetime
import matplotlib.pyplot as plt
import timecity_list = [[1, (1150.0, 1760.0)], [2, (630.0, 1660.0)], [3, (40.0, 2090.0)], [4, (750.0, 1100.0)],[5, (750.0, 2030.0)], [6, (1030.0, 2070.0)], [7, (1650.0, 650.0)], [8, (1490.0, 1630.0)],[9, (790.0, 2260.0)], [10, (710.0, 1310.0)], [11, (840.0, 550.0)], [12, (1170.0, 2300.0)],[13, (970.0, 1340.0)], [14, (510.0, 700.0)], [15, (750.0, 900.0)], [16, (1280.0, 1200.0)],[17, (230.0, 590.0)], [18, (460.0, 860.0)], [19, (1040.0, 950.0)], [20, (590.0, 1390.0)],[21, (830.0, 1770.0)], [22, (490.0, 500.0)], [23, (1840.0, 1240.0)], [24, (1260.0, 1500.0)],[25, (1280.0, 790.0)], [26, (490.0, 2130.0)], [27, (1460.0, 1420.0)], [28, (1260.0, 1910.0)],[29, (360.0, 1980.0)]]class Taboo_search:def __init__(self, city_list, candidate_count, taboo_list_length, iteration_count, is_random=True):self.city_list = city_list  # 城市列表self.candidate_count = candidate_count  # 候选集合长度self.taboo_list_length = taboo_list_length  # 禁忌长度self.iteration_count = iteration_count  # 迭代次数self.min_route, self.min_cost = self.random_first_full_road() if is_random else self.greedy_first_full_road()  # 最小解;最小目标值self.taboo_list = []  # 禁忌表# 计算两城市间的距离def city_distance(self, city1, city2):distance = ((float(city1[1][0] - city2[1][0])) ** 2 + (float(city1[1][1] - city2[1][1])) ** 2) ** 0.5return distance# 获取当前城市邻居城市中距离最短的一个def next_shotest_road(self, city1, other_cities):tmp_min = 999999tmp_next = Nonefor i in range(0, len(other_cities)):distance = self.city_distance(city1, other_cities[i])# print(distance)if distance < tmp_min:tmp_min = distancetmp_next = other_cities[i]return tmp_next, tmp_min# 随机生成初始线路def random_first_full_road(self):cities = copy.deepcopy(self.city_list)cities.remove(cities[0])route = copy.deepcopy(cities)random.shuffle(route)# route = [[6, (1030.0, 2070.0)], [5, (750.0, 2030.0)], [29, (360.0, 1980.0)], [3, (40.0, 2090.0)],#          [26, (490.0, 2130.0)], [9, (790.0, 2260.0)], [12, (1170.0, 2300.0)], [28, (1260.0, 1910.0)],#          [8, (1490.0, 1630.0)], [27, (1460.0, 1420.0)], [24, (1260.0, 1500.0)], [13, (970.0, 1340.0)],#          [16, (1280.0, 1200.0)], [23, (1840.0, 1240.0)], [7, (1650.0, 650.0)], [25, (1280.0, 790.0)],#          [19, (1040.0, 950.0)], [11, (840.0, 550.0)], [22, (490.0, 500.0)], [17, (230.0, 590.0)],#          [14, (510.0, 700.0)], [18, (460.0, 860.0)], [15, (750.0, 900.0)], [4, (750.0, 1100.0)],#          [10, (710.0, 1310.0)], [20, (590.0, 1390.0)], [2, (630.0, 1660.0)],#          [21, (830.0, 1770.0)]]  # 将初始值设置为遗传算法的最优值cost = self.route_cost(route)return route, cost# 根据贪婪算法获取初始线路def greedy_first_full_road(self):remain_city = copy.deepcopy(self.city_list)current_city = remain_city[0]road_list = []remain_city.remove(current_city)all_distance = 0while len(remain_city) > 0:next_city, distance = self.next_shotest_road(current_city, remain_city)all_distance += distanceroad_list.append(next_city)remain_city.remove(next_city)current_city = next_cityall_distance += self.city_distance(self.city_list[0], road_list[-1])return road_list, round(all_distance, 2)# 随机交换2个城市位置def random_swap_2_city(self, route):# print(route)road_list = copy.deepcopy(route)two_rand_city = random.sample(road_list, 2)# print(two_rand_city)index_a = road_list.index(two_rand_city[0])index_b = road_list.index(two_rand_city[1])road_list[index_a] = two_rand_city[1]road_list[index_b] = two_rand_city[0]return road_list, sorted(two_rand_city)# 计算线路路径长度def route_cost(self, route):road_list = copy.deepcopy(route)current_city = self.city_list[0]while current_city in road_list:road_list.remove(current_city)all_distance = 0while len(road_list) > 0:distance = self.city_distance(current_city, road_list[0])all_distance += distancecurrent_city = road_list[0]road_list.remove(current_city)all_distance += self.city_distance(current_city, self.city_list[0])return round(all_distance, 2)# 获取下一条线路def single_search(self, route):# 生成候选集合列表和其对应的移动列表candidate_list = []candidate_move_list = []while len(candidate_list) < self.candidate_count: # 在候选集合里放candidate_count条不重复路径tmp_route, tmp_move = self.random_swap_2_city(route)# print("tmp_route:",tmp_route)if tmp_route not in candidate_list:candidate_list.append(tmp_route)candidate_move_list.append(tmp_move)# 计算候选集合各路径的长度candidate_cost_list = []for candidate in candidate_list:candidate_cost_list.append(self.route_cost(candidate))# print(candidate_list)min_candidate_cost = min(candidate_cost_list)  # 候选集合中最短路径min_candidate_index = candidate_cost_list.index(min_candidate_cost)min_candidate = candidate_list[min_candidate_index]  # 候选集合中最短路径对应的线路move_city = candidate_move_list[min_candidate_index]if min_candidate_cost < self.min_cost:# 若满足这个条件不管禁忌对象是否在禁忌表内,都直接更新禁忌表self.min_cost = min_candidate_costself.min_route = min_candidateif move_city in self.taboo_list:  # 破禁法则,当此移动导致的值更优,则无视该禁忌列表self.taboo_list.remove(move_city)if len(self.taboo_list) >= self.taboo_list_length:  # 判断该禁忌列表长度是否以达到限制,是的话移除最初始的moveself.taboo_list.remove(self.taboo_list[0])self.taboo_list.append(move_city)  # 将该move加入到禁忌列表return min_candidateelse:# 当未找到更优路径时,选择次优路线,如果该次优路线在禁忌表里,则更次一层,依次类推,找到一条次优路线if move_city in self.taboo_list:tmp_min_candidate = min_candidatetmp_move_city = move_citywhile move_city in self.taboo_list:  # 若候选最优禁忌对象已经在T表,寻找次优禁忌对象,若已在T表,.....candidate_list.remove(min_candidate)candidate_cost_list.remove(min_candidate_cost)candidate_move_list.remove(move_city)min_candidate_cost = min(candidate_cost_list)  # 候选集合中次优路径min_candidate_index = candidate_cost_list.index(min_candidate_cost)min_candidate = candidate_list[min_candidate_index]  # 候选集合中最短路径对应的线路move_city = candidate_move_list[min_candidate_index]if len(candidate_list) < 10:  # 防止陷入死循环,在候选集个数小于10的时候跳出min_candidate = tmp_min_candidatemove_city = tmp_move_cityif len(self.taboo_list) >= self.taboo_list_length:  # 判断该禁忌列表长度是否以达到限制,是的话移除最初始的moveself.taboo_list.remove(self.taboo_list[0])self.taboo_list.append(move_city)return min_candidate# 进行taboo_search直到达到终止条件:循环100次def taboo_search(self):route = copy.deepcopy(self.min_route)for i in range(self.iteration_count):route = self.single_search(route)new_route = [self.city_list[0]]new_route.extend(self.min_route)new_route.append(self.city_list[0])  # 前后插入首个城市信息return new_route, self.min_cost# 画线路图
def draw_line_pic(route, cost, duration, desc):x = []y = []for item in route:x.append(item[1][0])y.append(item[1][1])x_org = []y_org = []point_org = []for item in city_list:x_org.append(item[1][0])y_org.append(item[1][1])point_org.append(item[0])x0 = [x[0], ]y0 = [y[0], ]plt.plot(x, y)plt.scatter(x_org, y_org, marker="o", c='g')plt.scatter(x0, y0, marker="o", c="r")for i in range(len(city_list)):plt.text(x_org[i], y_org[i], point_org[i], ha='center', va='bottom', fontsize=10)plt.title("Taboo_Search(" + desc + ": " + str(cost) + ")")plt.show()if __name__ == "__main__":ts_random = Taboo_search(city_list=city_list, candidate_count=40, taboo_list_length=3, iteration_count=4000)ts_greedy = Taboo_search(city_list, candidate_count=40, taboo_list_length=3, iteration_count=4000,is_random=False)start_time1 = datetime.datetime.now()route_random, cost_random = ts_random.taboo_search()end_time1 = datetime.datetime.now()duration1 = (end_time1 - start_time1).secondsroute_greedy, cost_greedy = ts_greedy.taboo_search()end_time2 = datetime.datetime.now()duration2 = (end_time2 - end_time1).secondsdraw_line_pic(route_random, cost_random, duration1, "random")print("最优路径:", route_random)print("最短距离:", cost_random)print("随机TS耗时:",end_time1-start_time1)draw_line_pic(route_greedy, cost_greedy, duration2, "greedy")


参考:【1】禁忌搜索

禁忌搜索算法及TS解TSP问题相关推荐

  1. 【改进篇】Python实现VRP常见求解算法——禁忌搜索算法(TS)

    基于python语言,实现经典禁忌搜索算法(TS)对车辆路径规划问题(CVRP)进行求解, 优化代码结构,改进Split函数 目录 往期优质资源 1. 适用场景 2. 改进效果对比 3. 求解结果 4 ...

  2. 禁忌搜索算法(tabu search)解决TSP及其Matlab代码

    1.算法简介 禁忌搜索算法TS(Tabu search),顾名思义核心在于"禁忌",简单来说就是在某一个过程中把一些不太好的操作给禁止了,直到搜索到一个"最优秀" ...

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

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

  4. 禁忌搜索算法TS求解TSP问题

    目录 一.局部邻域搜索 二.禁忌搜索 三.禁忌搜索算法流程 四.算法求解例题 一.局部邻域搜索 局部邻域搜索是基于贪婪准则持续地在当前的邻域中进行搜索,虽然算法通用,易于实现,且容易理解,但其搜索性能 ...

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

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

  6. 【算法】禁忌搜索算法(Tabu Search,TS)超详细通俗解析附C++代码实例

    01 什么是禁忌搜索算法? 1.1 先从爬山算法说起 爬山算法从当前的节点开始,和周围的邻居节点的值进行比较. 如果当前节点是最大的,那么返回当前节点,作为最大值 (既山峰最高点):反之就用最高的邻居 ...

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

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

  8. 【MATLAB】禁忌算法(TS)求解TSP问题

    目录 1.TS概述 1.1 TS介绍 1.2 TS流程 1.3 TS流程特点 2.基于TS求解TSP问题 2.1 tsp.m 2.2 CalDist.m 2.3 drawTSP.m 2.4 tabu_ ...

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

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

  10. 禁忌搜索算法求解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 ...

最新文章

  1. java 双调旅行商 hamiltonian,双调欧几里得旅行商问题(TSP)
  2. 浅谈Struts2和Sturts1的区别
  3. [微信开发] - 用户获取推广二维码
  4. Hadoop处于风雨飘摇中
  5. 介绍ASP.NET控件ID
  6. 毕业了,就忘掉导师吧
  7. QT之 Hello World
  8. Altium AD20批量修改丝印大小、更改丝印字体、丝印显示中文、更改位号丝印 相对元件的位置
  9. bzoj 1609: [Usaco2008 Feb]Eating Together麻烦的聚餐(DP)
  10. ARM9学习笔记之——SDRAM实验
  11. pr cpu100%_PR插件Beauty Box安装教程
  12. 酷派android4.4.4到5.0,酷派大神F1电信版升级安卓5.0刷机教程[多图]
  13. ROS路由器ethernet接口:
  14. matlab gui制作,MATLAB GUI制作教程
  15. html5获取经纬度页面,html5获取经纬度
  16. 163邮箱注册登录官网是什么?163邮箱登陆流程在这里
  17. 大四学年个人自我鉴定
  18. Mac下使用imagemagick将PDF转长图
  19. 二次函数图像如何用计算机绘制,如何快速画二次函数图像
  20. rust program英文和汉语混合笔记(2)

热门文章

  1. PCWorld:HTML5会终结移动应用程序吗?
  2. Extjs EditorGridPanel功能
  3. 【超详细教程】告别证书,图文并茂教你免签名XX,三种方法任你选!超简单...
  4. [matlab数字图像处理10]对一副图像进行二值化,ostu算法等
  5. [机器学习实战] 机器学习基础
  6. 三菱fx2n做从站的modbus通讯_第476期丨关于三菱PLC中除法的问题;请教一个监测电流的小物件或方法...
  7. python中没有严格意义上的私有成员_尔雅尔雅学习通APP家园的治理:环境科学概论题库及答案...
  8. 国务院印发《促进大数据发展行动纲要》
  9. mx播放器有没有投屏功能_无线投屏、即插即用,投影仪其实可以更智能:明基 E580T...
  10. 小米8手机android版本下载地址,小米手机8 MIUI 10稳定版完整包发布(附下载链接)...