当前位置: 首页 > news >正文

遗传算法求解TSP旅行商问题python代码实战

遗传算法求解TSP旅行商问题python代码实战

  • 一、遗传算法简介
    • 1.1智能优化算法
    • 1.2遗传算法原理
  • 二、TSP旅行商问题简介
    • 2.1TSP描述
    • 2.2求解算法
  • 三、求解python代码
    • 3.1共14个城市位置坐标
    • 3.2求解代码
    • 3.3代码说明
      • 3.3.1代码整体说明
      • 3.3.2代码注意事项
    • 3.4求解结果展示

一、遗传算法简介

1.1智能优化算法

遗传算法属于智能优化算法(Intelligent Optimization Algorithms)的一种,智能优化算法也被称为进化计算(Evolutionary Computation, EC)、群体智能算法(Swarm Intelligence Algorithms),属于优化算法大类,但不同于数学优化中的梯度下降、牛顿法,不是精确解法,不追求理论的严谨,而是模拟自然界的过程来寻找较优解

禁忌搜索(Tabu Search或Taboo Search)、蚁群优化(Ant Colony Optimization, ACO)、粒子群优化(Particle Swarm Optimization, PSO)都属于智能优化算法,常用于参数调优组合优化(如旅行商问题 TSP)、工程设计优化、机器学习模型超参数搜索等。

1.2遗传算法原理

遗传算法(Genetic Algorithm, GA),在智能优化算法中使用非常广泛,算法知名度也很高,很多研究学者以遗传算法为基础进行算法的创新。

遗传算法是由美国密歇根大学的John H.Holland教授及其学生于20世纪60年代末到70年代初提出的,算法是模拟自然界中生物遗传物质DNA的遗传和变异,以及生物接受自然选择,适者生存的这一自然过程而借鉴提出。
在这里插入图片描述

算法的基本过程为:

  1. 在搜索空间内产生一个初始种群,种群中的每个个体都是待求解问题的一个解
  2. 根据问题构造适值函数,该函数衡量个体的适应度,即解的优劣,适值函数越大说明解越优秀
  3. 根据某种选择策略选择种群中的个体进行繁殖,产生下一代,繁殖的过程就包括基因互换和变异,基因即为解的某种编码方式;
  4. 若干次繁衍后,得到的种群中适值函数最大的个体即为该算法得出的最优解。

二、TSP旅行商问题简介

2.1TSP描述

TSP(Traveling Salesman Problem)旅行商问题,可简要描述为:求解走完若干个城市的最短路线,要求除出发城市外每个城市只经过一次,且最终回到出发的城市
在这里插入图片描述

2.2求解算法

假设有n个城市,那么考虑到起点固定和方向对称共有(n-1)!/2种路线,目前没有已知的多项式时间算法可以求得最优解,属于NP问题,求解难度大。

常见的解法主要有以下几种:

类型算法特点
寻求最优解动态规划能求最优解,但时间复杂度指数级
寻求次优解智能优化算法,如遗传算法、禁忌搜索算法等求解速度快,但结果是局部最优解,可能不是全局最优解

三、求解python代码

3.1共14个城市位置坐标

本节以求解14个城市的TSP问题为例,14个城市坐标如下:
在这里插入图片描述

3.2求解代码

import random
import math
import sys
from tqdm import tqdm
import copy
import matplotlib.pyplot as plt
import mathdef init_group_func(init_group_num, code_len):code_group = []for i in range(init_group_num):while True:code = []for j in range(code_len):while True:code_item = int(random.random() * code_len)if code_item not in code:code.append(code_item)breakif code not in code_group:code_group.append(code)breakreturn code_groupdef calc_fitness(code_group, city_pos_list, distance_matrix):fitness_list = []dist_list = []for code in code_group:sum_dist = 0.0for i in range(-1, len(code) - 1):dist = distance_matrix[code[i]][code[i + 1]]sum_dist += distdist_list.append(round(sum_dist, 4))sum_dist = 1.0 / sum_distsum_dist = round(sum_dist, 4)fitness_list.append(sum_dist)return fitness_list, dist_listdef cross_func(new_group01, new_group02):new_group01 = copy.deepcopy(new_group01)new_group02 = copy.deepcopy(new_group02)r1 = int(random.random() * 10)while True:r2 = int(random.random() * 10)if r2 != r1:breakif r1 > r2:r1, r2 = (r2, r1)code_len = len(new_group01)if r2 >= code_len:r2 = code_len - 1for i in range(r1):tmp_val = new_group01[i]while tmp_val in new_group02[r1:r2]:tmp_index = new_group02[r1:r2].index(tmp_val)tmp_val = new_group01[tmp_index + r1]new_group01[i] = tmp_valtmp_val = new_group02[i]num = 0tmp_list = []tmp_indexlist = []while tmp_val in new_group01[r1:r2]:tmp_index = new_group01[r1:r2].index(tmp_val)tmp_val = new_group02[tmp_index + r1]tmp_list.append(tmp_val)tmp_indexlist.append(tmp_index)num += 1if num > 10:print(tmp_list)print(tmp_indexlist)sys.exit(0)new_group02[i] = tmp_valfor i in range(r2, code_len):tmp_val = new_group01[i]while tmp_val in new_group02[r1:r2]:tmp_index = new_group02[r1:r2].index(tmp_val)tmp_val = new_group01[tmp_index + r1]new_group01[i] = tmp_valtmp_val = new_group02[i]while tmp_val in new_group01[r1:r2]:tmp_index = new_group01[r1:r2].index(tmp_val)tmp_val = new_group02[tmp_index + r1]new_group02[i] = tmp_valnew_group01[r1:r2], new_group02[r1:r2] = (new_group02[r1:r2], new_group01[r1:r2])if len(new_group01) != len(set(new_group01)) or len(new_group02) != len(set(new_group02)):print('cross process error')return []return new_group01, new_group02def vary_func(new_group03):new_group03 = copy.deepcopy(new_group03)code_len = len(new_group03)r1 = int(random.random() * 10)if r1 >= code_len:r1 = code_len - 1while True:r2 = int(random.random() * 10)if r2 >= code_len:r2 = code_len - 1if r2 != r1:breaknew_group03[r1], new_group03[r2] = (new_group03[r2], new_group03[r1])return new_group03def vary_reverse_func(new_group04):new_group04 = copy.deepcopy(new_group04)code_len = len(new_group04)r1 = int(random.random() * 10)while True:r2 = int(random.random() * 10)if r2 != r1:breakif r1 > r2:r1, r2 = (r2, r1)if r2 >= code_len:r2 = code_len - 1tmp_list = new_group04[r1:r2]tmp_list.reverse()new_group04[r1:r2] = tmp_listreturn new_group04def cross_vary_group(code_group, cross_num, vary_num, reverse_num, fitness_list, cum_list):new_code_group = []sorted_fitness_list = sorted(fitness_list, reverse = True)best_f_index = fitness_list.index(max(fitness_list))av = sum(fitness_list) / len(fitness_list)for k in range(cross_num):if k != best_f_index and fitness_list[k] < av:new_group01, _ = cross_func(code_group[best_f_index], code_group[k])new_code_group.append(new_group01)else:new_code_group.append(code_group[k])#vary processfor _ in range(vary_num):index03 = int(random.random() * len(code_group))if index03 >= len(code_group):index03 = len(code_group) - 1new_group03 = code_group[index03]new_group03 = vary_func(new_group03)new_code_group.append(new_group03)#reverse processfor _ in range(reverse_num):index04 = int(random.random() * len(code_group))if index04 >= len(code_group):index04 = len(code_group) - 1new_group04 = code_group[index04]new_group04 = vary_reverse_func(new_group04)new_code_group.append(new_group04)for k in range(len(code_group) - len(new_code_group)):tmp_prob01 = random.random()index01 = 0for i in range(len(cum_list)):if tmp_prob01 <= cum_list[i]:index01 = ibreakindex01 = fitness_list.index(sorted_fitness_list[k])new_group01 = code_group[index01]new_code_group.append(new_group01)return new_code_groupdef GA_TSP(city_pos_list, distance_matrix, init_group_num, all_epoches, pc = 0.9, pm = 0.05, pr = 0.01, max_reult = None):code_group = init_group_func(init_group_num, len(city_pos_list))init_group_str = []for code in code_group:tmp_str = '-'.join([str(x) for x in code])init_group_str.append(tmp_str)if (len(init_group_str) != len(set(init_group_str))):print('init group error....')returnmin_distance = 100min_path = ''min_epoch = 0f = open('Rou_select_log.txt', 'w')for k in tqdm(range(all_epoches)):fitness_list, dist_list = calc_fitness(code_group, city_pos_list, distance_matrix)mean_fitness = round(sum(fitness_list) / len(fitness_list), 6)tmp_min = min(dist_list)tmp_min_path = '-'.join([str(x) for x in code_group[fitness_list.index(max(fitness_list))]])if tmp_min < min_distance:min_distance = tmp_minmin_path = tmp_min_pathmin_epoch = k + 1f.write(str(mean_fitness))f.write('\n')sum_fitness = sum(fitness_list)prob_list = [round(x / sum_fitness, 6) for x in fitness_list]cum_list = []cum_list.append(0.0)for i in range(len(prob_list)):cum_val = round(prob_list[i] + cum_list[-1], 6)cum_list.append(cum_val)cum_list.pop(0)if (all_epoches + 1) % 10 == 0:if (all_epoches + 1) % 20 == 0:code_group = cross_vary_group(code_group, int(len(code_group) * pc), int(len(code_group) * pm), int(len(code_group) * pr), fitness_list, cum_list)else:code_group = cross_vary_group(code_group, int(len(code_group) * pc), int(len(code_group) * pm), 0, fitness_list, cum_list)else:code_group = cross_vary_group(code_group, int(len(code_group) * pc), 0, 0, fitness_list, cum_list)if len(code_group) == 0:returnf.close()print('GA done')print(f"min_epoch is {min_epoch}, min_distance is {min_distance}, min_path is {min_path}")returnif __name__ == '__main__':city_pos_list = [(16.47, 96.10), (16.47, 94.44), (20.09, 92.54), (22.39, 93.37), (25.23, 97.24), (22.00, 96.05), (20.47, 97.02), (17.20, 96.29), (16.30, 97.38), (14.05, 98.12), (16.53, 97.38), (21.52, 95.59), (19.41, 97.13), (20.09, 92.55)]distance_matrix = [[0.0, 1.66, 5.0772, 6.5191, 8.8339, 5.5302, 4.1044, 0.7543, 1.2912, 3.1523, 1.2814, 5.0757, 3.1152, 5.0702], [1.66, 0.0, 4.0883, 6.0159, 9.1966, 5.7596, 4.7599, 1.9888, 2.9449, 4.4044, 2.9406, 5.1793, 3.9849, 4.0837], [5.0772, 4.0883, 0.0, 2.4452, 6.9649, 3.996, 4.4961, 4.7344, 6.1473, 8.223, 6.0083, 3.3686, 4.6401, 0.01], [6.5191, 6.0159, 2.4452, 0.0, 4.8003, 2.7082, 4.1242, 5.955, 7.2917, 9.5978, 7.1007, 2.3844, 4.7977, 2.4418], [8.8339, 9.1966, 6.9649, 4.8003, 0.0, 3.4422, 4.7651, 8.086, 8.9311, 11.2146, 8.7011, 4.0604, 5.821, 6.9581], [5.5302, 5.7596, 3.996, 2.7082, 3.4422, 0.0, 1.8116, 4.806, 5.8531, 8.2151, 5.6294, 0.6648, 2.8062, 3.9872], [4.1044, 4.7599, 4.4961, 4.1242, 4.7651, 1.8116, 0.0, 3.3505, 4.1855, 6.5136, 3.9564, 1.7741, 1.0657, 4.4861], [0.7543, 1.9888, 4.7344, 5.955, 8.086, 4.806, 3.3505, 0.0, 1.4135, 3.643, 1.2795, 4.3763, 2.3643, 4.7265], [1.2912, 2.9449, 6.1473, 7.2917, 8.9311, 5.8531, 4.1855, 1.4135, 0.0, 2.3686, 0.23, 5.5184, 3.12, 6.1395], [3.1523, 4.4044, 8.223, 9.5978, 11.2146, 8.2151, 6.5136, 3.643, 2.3686, 0.0, 2.588, 7.8868, 5.4507, 8.2162], [1.2814, 2.9406, 6.0083, 7.1007, 8.7011, 5.6294, 3.9564, 1.2795, 0.23, 2.588, 0.0, 5.3013, 2.8908, 6.0002], [5.0757, 5.1793, 3.3686, 2.3844, 4.0604, 0.6648, 1.7741, 4.3763, 5.5184, 7.8868, 5.3013, 0.0, 2.6122, 3.3595], [3.1152, 3.9849, 4.6401, 4.7977, 5.821, 2.8062, 1.0657, 2.3643, 3.12, 5.4507, 2.8908, 2.6122, 0.0, 4.6302], [5.0702, 4.0837, 0.01, 2.4418, 6.9581, 3.9872, 4.4861, 4.7265, 6.1395, 8.2162, 6.0002, 3.3595, 4.6302, 0.0]]init_group_num = 1000all_epoches = 200GA_TSP(city_pos_list, distance_matrix, init_group_num, all_epoches)

3.3代码说明

3.3.1代码整体说明

  1. 在主函数中定义了城市位置坐标,以及距离矩阵,该矩阵是通过代码计算得出,这里直接列在程序中,读者可进行验证;
  2. 定义了遗传算法的初始种群数为1000,迭代轮数为200,即遗传代数,算法主体通过GA_TSP函数实现;
  3. GA_TSP函数,首先通过init_group_func函数生成初始化种群,然后进行循环,每次循环中依次计算适值函数,选择其中最小距离值为此次最优解并记录,再通过cross_vary_group函数进行交叉变异后,进行下次循环;
  4. cross_vary_group函数功能是对种群进行交叉变异后产生新一代种群,但是并不是所有个体都进行交叉,而是采用某种选择策略,本代码中使用了精英保留策略进行交叉,同时设置一定的比例进行变异。

3.3.2代码注意事项

  1. 本代码中使用了精英保留策略进行选择要交叉的个体,同时还有其他策略,例如旋轮法、锦标赛法等,具体效果读者可进行对比;
  2. 由于使用随机方法初始化种群,因此每次代码执行结果不同是正常的

3.4求解结果展示

代码得出的最短路线距离为30.2471,TSP路线图如下:
在这里插入图片描述

http://www.dtcms.com/a/603296.html

相关文章:

  • Servlet 网页重定向
  • Eclipse 生成 jar 包
  • 学Java第四十三天——Map双列集合
  • 淮南服装网站建设地址房产网站如何做
  • 北京牛鼻子网站建设公司网站建设kaituozu
  • 服务器A需要调用银行的https://xx.xx.xx.xx:10000/infoBatch接口 nginx作为中间转发 怎么配置
  • 中国源码网游戏开服衡阳网站优化方案
  • 商品网站开发南宁做网站
  • Linux之中断子系统-中断控制器的中断函数gic_handle_irq分析(5)
  • 社交网站开发平台建工在线
  • Agentic AI TASK02 Reflection Design and Pattern
  • 撰写网站专题活动策划方案网站备案域名购买
  • 2014 吉林省赛题解 | CCUT应用OJ题解——F[X] + X = N
  • 如何做网站使用手册两个网站如何使用一个虚拟主机
  • 【云运维】Kubernetes 安装(基于Containerd+Calico)
  • 芜湖高端网站建设网站推广 济南
  • 公共部门网站建设维护网站挂黑链
  • wordpress怎么做的wifi优化大师下载
  • 免费婚庆网站模板嵌入式网站开发培训
  • 网站关键词先后开发公司安全管理组织机构图
  • 网站建设域名什么意思wordpress插件点不开
  • wordpress怎样建立多站点手机百度账号登录个人中心
  • 2025-11-12[第三大的数、将x减到0的最小操作数]
  • 基层建设刊物网站建筑工程网签备案合同
  • 强化学习基础概念与核心算法全解析
  • 解释型与编译型编程语言的区别 | 深入了解两者的工作原理与优劣
  • 人工智能网站应怎么做长春市长春网站建设哪家好
  • 建宣传网站北京营销策划公司有哪些
  • 网站系统开发毕业设计网站建设ppt百度文库
  • 2.2 前向传播与反向传播:深度学习的核心机制全解析