问题描述
一个商品推销员要去若干个城市推销商品,该推销员从一个城市出发,需要经过所有城市后,回到出发地。应如何选择行进路线,以使总的行程最短。
对于n个城市的TSP,本文利用python分别实现混合粒子群算法对该问题的求解。

混合粒子群
混合粒子群算法的基本运算过程如下

  1. 初始化编码:设置最大进化代数T_max、随机生成m个染色体的群体编码
  2. 适应度函数:对每一个染色体,都有其个体适应度值
  3. 交叉:将每个个体与该个体的个体极值和当前群体的群体极值进行交叉操作更新,只有交叉后的新个体比旧个体的适应度更好,才替换更改。
  4. 变异:对单个染色体随机交换两个点的位置,如果变异后的个体比旧个体的适应度更好,就替换更改。

流程图如图

代码

语言:python

第一步初始化参数

import numpy as np
import matplotlib.pyplot as pltclass Hybrid_POS_TSP(object):def __init__(self, data, num_pop=200):self.num_pop = num_pop  # 群体个数self.data = data  # 城市坐标self.num = len(data)  # 城市个数# 群体的初始化和路径的初始化self.chrom = np.array([0] * self.num_pop * self.num).reshape(self.num_pop, self.num)#shape(num_pop,num)self.fitness = [0] * self.num_pop#一个个体一个适应度函数# 路径矩阵,函数matrix_dis同遗传算法self.matrix_distance = self.matrix_dis()

距离函数,加入类Hybrid_POS_TSP

# 计算城市间的距离函数  n*n, 第[i,j]个元素表示城市i到j距离def matrix_dis(self):res = np.zeros((self.num, self.num))for i in range(self.num):for j in range(i + 1, self.num):res[i, j] = np.linalg.norm(self.data[i, :] - self.data[j, :])  # 求二阶范数 就是距离公式res[j, i] = res[i, j]return res

随机产生初始化群体函数,加入类Hybrid_POS_TSP

 # 随机产生初始化群体函数def rand_chrom(self):rand_ch = np.array(range(self.num))  ## num 城市个数 对应染色体长度   城市=14for i in range(self.num_pop):  # num_pop  # 群体个数 200np.random.shuffle(rand_ch)  # 打乱城市染色体编码self.chrom[i, :] = rand_ch#.chrom 父代self.fitness[i] = self.comp_fit(rand_ch)# 计算单个染色体的路径距离值,可利用该函数更新fittnessdef comp_fit(self, one_path):res = 0for i in range(self.num - 1):res += self.matrix_distance[one_path[i], one_path[i + 1]]  # matrix_distance n*n, 第[i,j]个元素表示城市i到j距离res += self.matrix_distance[one_path[-1], one_path[0]]  # 最后一个城市 到起点距离return res

路径可视化函数,加入类Hybrid_POS_TSP

 def out_path(self, one_path):res = str(one_path[0] + 1) + '-->'for i in range(1, self.num):res += str(one_path[i] + 1) + '-->'res += str(one_path[0] + 1) + '\n'print(res)

两条路径的交叉函数:将每个个体与该个体的个体极值和当前群体的群体极值进行交叉操作。代码加入类Hybrid_POS_TSP

#两条路径的交叉函数:将每个个体与该个体的个体极值和当前群体的群体极值进行交叉操作def cross_1(self, path, best_path):#path为 个体最优 ,best_path为群体最优r1 = np.random.randint(self.num)#随机产生小于num的整数r2 = np.random.randint(self.num)#随机产生小于num的整数while r2 == r1:#如果两者相等r2 = np.random.randint(self.num)#重新产生r2left, right = min(r1, r2), max(r1, r2)#left 为(r1,r2)小者,right 为(r1,r2)大者cross = best_path[left:right + 1]#交叉片段为 群体最优中的(r1:r2)片段#下面的for 循环是为了确保 个体染色体(0:(num-(right-left+1)) 片段 不含有 cross中的元素。for i in range(right - left + 1):#有(r2-r1)次遍历for k in range(self.num):#遍历个体染色体中的每一个值if path[k] == cross[i]:#如果当前个体染色体元素path[k]  是cross之内path[k:self.num - 1] = path[k + 1:self.num] #则修改path[k:num - 1] 片段,同时末尾补0  (也就是说把不属于cross的个体染色体元素 往前赶path[-1] = 0path[self.num - right + left - 1:self.num] = cross#把个体染色体(num-(right-left+1):num ) 片段 和群体交叉return path

变异函数:对单个染色体随机交换两个点的位置。代码加入类Hybrid_POS_TSP

    def mutation(self, path):#path 个体染色体r1 = np.random.randint(self.num)#随机生成小于num的整数r2 = np.random.randint(self.num)#随机生成小于num的整数while r2 == r1:#如果r1==r2r2 = np.random.randint(self.num)#则r2再重新生成path[r1], path[r2] = path[r2], path[r1]#交换片段return path

主函数

#data = np.random.rand(20, 2) * 10  # 随机产生20个城市坐标
def main(data, max_n=200, num_pop=200):#迭代次数max_n200  群体个数num_pop=200Path_short = Hybrid_POS_TSP(data, num_pop=num_pop)  # 混合粒子群算法类Path_short.rand_chrom()  # 初始化种群# 初始化路径绘图fig, ax = plt.subplots()x = data[:, 0]y = data[:, 1]ax.scatter(x, y, linewidths=0.1)for i, txt in enumerate(range(1, len(data) + 1)):ax.annotate(txt, (x[i], y[i]))res0 = Path_short.chrom[0]x0 = x[res0]y0 = y[res0]for i in range(len(data) - 1):plt.quiver(x0[i], y0[i], x0[i + 1] - x0[i], y0[i + 1] - y0[i], color='r', width=0.005, angles='xy', scale=1,scale_units='xy')plt.quiver(x0[-1], y0[-1], x0[0] - x0[-1], y0[0] - y0[-1], color='r', width=0.005, angles='xy', scale=1,scale_units='xy')plt.show()print('初始染色体的路程: ' + str(Path_short.fitness[0]))#定义6个容器 分别存放个体极值,个体染色体,群体最优极值,群体最优染色体,每一次迭代后的最优极值,每一次迭代后最优个体染色体 (容器定义的样子要和染色体个数等一致)# 存储个体极值的路径和距离best_P_chrom = Path_short.chrom.copy()# 个体极值 路径 (个体染色体)best_P_fit = Path_short.fitness.copy()#个体极值 距离min_index = np.argmin(Path_short.fitness)#最优个体的index序号#存储当前种群极值的路径和距离best_G_chrom = Path_short.chrom[min_index, :]#存储当前种群极值的路径(群体最优染色体)best_G_fit = Path_short.fitness[min_index]#存储当前种群极值的距离(群体最优极值)# 存储每一步迭代后的最优路径和距离best_chrom = [best_G_chrom]#当代最优个体best_fit = [best_G_fit]#当代最优极值# 复制当前群体进行交叉变异x_new = Path_short.chrom.copy()# 进入迭代 更新个体极值,个体染色体,群体最优极值,群体最优个体,存放当代最优个体,存放当代最优极值for i in range(max_n):#遍历迭代# 更新当前的个体极值 和路径 #for j in range(num_pop):#遍历每一个个体if Path_short.fitness[j] < best_P_fit[j]:#best_P_fit[j] = Path_short.fitness[j]#更新个体极值best_P_chrom[j, :] = Path_short.chrom[j, :]#更新个体极值路径# 更新当前种群的群体极值min_index = np.argmin(Path_short.fitness)best_G_chrom = Path_short.chrom[min_index, :]#群体极值 路径best_G_fit = Path_short.fitness[min_index]#群体极值# 添加 每一次迭代后的 当代全局最优个体和解极值if best_G_fit < best_fit[-1]:#best_G_fit 全局极值  best_fit每一步迭代后的最优极值best_fit.append(best_G_fit)#best_chrom.append(best_G_chrom)else:best_fit.append(best_fit[-1])best_chrom.append(best_chrom[-1])#遍历每一个个体,将个体与当代最优个体进行有条件交叉;个体有条件自我变异。条件都为(个体适应度是否更好,如果是则交叉变异# 将每个个体与个体极值和当前的群体极值进行交叉for j in range(num_pop):#遍历每一个个体     # 与当代极值交叉x_new[j, :] = Path_short.cross_1(x_new[j, :], best_G_chrom)fit = Path_short.comp_fit(x_new[j, :])if fit < Path_short.fitness[j]:Path_short.chrom[j, :] = x_new[j, :]Path_short.fitness[j] = fit# 变异x_new[j, :] = Path_short.mutation(x_new[j, :])fit = Path_short.comp_fit(x_new[j, :])if fit <= Path_short.fitness[j]:Path_short.chrom[j] = x_new[j, :]Path_short.fitness[j] = fitif (i + 1) % 20 == 0:print('第' + str(i + 1) + '步后的最短的路程: ' + str(Path_short.fitness[min_index]))print('第' + str(i + 1) + '步后的最优路径:')Path_short.out_path(Path_short.chrom[min_index, :])  # 显示每一步的最优路径Path_short.best_chrom = best_chromPath_short.best_fit = best_fit#画出最优路径res1 = Path_short.best_chrom[-1]x0 = x[res1]y0 = y[res1]for i in range(len(data) - 1):plt.quiver(x0[i], y0[i], x0[i + 1] - x0[i], y0[i + 1] - y0[i], color='r', width=0.005, angles='xy', scale=1,scale_units='xy')plt.quiver(x0[-1], y0[-1], x0[0] - x0[-1], y0[0] - y0[-1], color='r', width=0.005, angles='xy', scale=1,scale_units='xy')plt.show()return Path_short  # 返回结果类if __name__ == '__main__':# 路径坐标np.random.seed(10)data = np.random.rand(20, 2) * 10  # 随机产生20个城市坐标main(data,)

结果:
开始路径

结果路径


作者:电气余登武。写作不容易,点个赞再走。

基于组合遗传粒子群算法的旅行商问题求解相关推荐

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

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

  2. 4.基于多目标粒子群算法冷热电联供综合能源系统运行优化

    4.基于多目标粒子群算法冷热电联供综合能源系统运行优化<文章复现> 相关资源代码:基于多目标粒子群算法冷热电联供综合能源系统运行优化 基于多目标算法的冷热电联供型综合能源系统运行优化 考虑 ...

  3. 基于改进二进制粒子群算法的配电网重构(matlab实现)

    目录 一.引言 1.问题背景 2.二进制粒子群算法 2.1简介 2.2 S i g m o i d Sigmoid Sigmoid函数 2.3二进制粒子群算法 2.4算法的改进 二.配电网重构模型 1 ...

  4. 基于多目标粒子群算法的冷热电联供型综合能源系统运行优化。 包括燃气轮机,燃气锅炉,电制冷机等设备。

    基于多目标粒子群算法的冷热电联供型综合能源系统运行优化. 包括燃气轮机,燃气锅炉,电制冷机等设备. _:5660667510835416宇哥代码铺

  5. 【优化算法】基于matlab量子粒子群算法求解单目标优化问题【含Matlab源码 2203期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[优化算法]基于matlab量子粒子群算法求解单目标优化问题[含Matlab源码 2203期] 点击上面蓝色字体,直接付费下载,即可. 获 ...

  6. 基于遗传算法和粒子群算法的PID悬架控制、LQR悬架控制和滑模悬架控制

    目录 1.基于遗传算法和粒子群算法的的PID悬架控制 1.1 两种悬架系统 1.1.1 将路面激励整合到悬架系统 1.1.2 不将路面激励整合到悬架系统 1.1.3 总结 1.2 PID经典控制理论 ...

  7. MATLAB代码:基于多目标粒子群算法冷热电联供综合能源系统运行优化

    MATLAB代码:基于多目标粒子群算法冷热电联供综合能源系统运行优化 关键词:综合能源 冷热电三联供 粒子群算法 多目标优化 参考文档:<基于多目标算法的冷热电联供型综合能源系统运行优化> ...

  8. 【微电网优化】基于量子行为粒子群算法机组燃烧控制系统建模含Matlab源码

    1 简介 能源问题与环境问题随着现代社会的快速发展已成为中国乃至全世界关注的焦点.就我国现状来说,由于独特的能源架构和社会形态,直接决定了我国的电力工业在当今乃至未来相当长的一段时期内将以燃煤火电机组 ...

  9. 基于多目标粒子群算法的配电网储能选址定容(含MATLAB程序)

    一.主要内容 程序是对文章<基于多目标粒子群算法的配电网储能选址定容>的方法复现,具体内容如下: 以系统节点电压水平(电网脆弱性).网络损耗以及储能系统总容量为目标建立了储能选址定容优化模 ...

最新文章

  1. 作为JavaScript开发人员,这些必备的VS Code插件你都用过吗
  2. 计算机网络与通信基础知识,计算机网络与通信基础/谢雨飞
  3. CSS实现三列图片等宽等间距布局
  4. 为UIKeyboardTypeNumberPad增加自定义按键
  5. 拍不完的脑袋:推荐系统打压保送重排策略
  6. 新建一个java程序并运行
  7. 通过 .git 目录深入理解 Git!
  8. 删除排序数组中的重复数字 II · Remove Duplicates from Sorted Array II
  9. 9.react 从入门到放弃
  10. 搭建微信小程序(前后端)
  11. 博主亲测Mac OSX 上好用必备的PC端软件
  12. 计算机组成原理实验报告一静态随机存储器
  13. 买卖股票的最佳时间含手续费的代码实现
  14. Windows Server 2019的安装模式
  15. android 微信分享注册链接显示app的logo出现黑边处理方案
  16. STM32串口通信中的USART_RecieveData函数分析
  17. 提高系统的业务价值—柯莱特钱建宇谈应用管理服务外包
  18. 产品经理的10大困惑
  19. 中南大学计算机网,中南大学计算机网络习题2014
  20. 传输层TCP/UDP的一些疑问

热门文章

  1. linux运行python乱码_linux下python中文乱码解决方案详解
  2. android表格布局的使用方法,Android布局(RelativeLayout、TableLayout等)使用方法
  3. python创建float型的列表_如何在Python中进行列表的创建?
  4. CHM文件显示目录无法显示内容的解决方案
  5. mysql中怎么删除表中的一列数据_mysql如何删除表中一行数据?
  6. FLEX+Delphi,FLEX+Java,FLEX+C# 的聊天室
  7. ElasticSearch搜索引擎: 内存分析与设置
  8. 2018计算机领域大事件,吕伟:2018年计算机行业回顾
  9. 谷歌浏览器出现方格xp系统_win10系统谷歌浏览器扩展程序打不开的解决方案
  10. 为什么做了梦第二天想不起来_元旦提醒:为什么有人睡觉爱把脚伸到被子外面?其实与身体状况有关…切勿忽视...