Python基于回溯法子集树模板解决旅行商问题(TSP)实例
时间:2019-04-01
本文章向大家介绍Python基于回溯法子集树模板解决旅行商问题(TSP)实例,主要包括Python基于回溯法子集树模板解决旅行商问题(TSP)实例使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
本文实例讲述了Python基于回溯法子集树模板解决旅行商问题(TSP)。分享给大家供大家参考,具体如下:
问题
旅行商问题(Traveling Salesman Problem,TSP)是旅行商要到若干个城市旅行,各城市之间的费用是已知的,为了节省费用,旅行商决定从所在城市出发,到每个城市旅行一次后返回初始城市,问他应选择什么样的路线才能使所走的总费用最短?
分析
此问题可描述如下:G=(V,E)是带权的有向图,找到包含V中每个结点一个有向环,亦即一条周游路线,使得这个有向环上所有边成本之和最小。
这个问题与前一篇文章//www.jb51.net/article/122933.htm的区别就是,本题是带权的图。只要一点小小的修改即可。
解的长度是固定的n+1。
对图中的每一个节点,都有自己的邻接节点。对某个节点而言,其所有的邻接节点构成这个节点的状态空间。当路径到达这个节点时,遍历其状态空间。
最终,一定可以找到最优解!
显然,继续套用回溯法子集树模板!!!
代码
'''旅行商问题(Traveling Salesman Problem,TSP)''' # 用邻接表表示带权图 n = 5 # 节点数 a,b,c,d,e = range(n) # 节点名称 graph = [ {b:7, c:6, d:1, e:3}, {a:7, c:3, d:7, e:8}, {a:6, b:3, d:12, e:11}, {a:1, b:7, c:12, e:2}, {a:3, b:8, c:11, d:2} ] x = [0]*(n+1) # 一个解(n+1元数组,长度固定) X = [] # 一组解 best_x = [0]*(n+1) # 已找到的最佳解(路径) min_cost = 0 # 最小旅费 # 冲突检测 def conflict(k): global n,graph,x,best_x,min_cost # 第k个节点,是否前面已经走过 if k < n and x[k] in x[:k]: return True # 回到出发节点 if k == n and x[k] != x[0]: return True # 前面部分解的旅费之和超出已经找到的最小总旅费 cost = sum([graph[node1][node2] for node1,node2 in zip(x[:k], x[1:k+1])]) if 0 < min_cost < cost: return True return False # 无冲突 # 旅行商问题(TSP) def tsp(k): # 到达(解x的)第k个节点 global n,a,b,c,d,e,graph,x,X,min_cost,best_x if k > n: # 解的长度超出,已走遍n+1个节点 (若不回到出发节点,则 k==n) cost = sum([graph[node1][node2] for node1,node2 in zip(x[:-1], x[1:])]) # 计算总旅费 if min_cost == 0 or cost < min_cost: best_x = x[:] min_cost = cost #print(x) else: for node in graph[x[k-1]]: # 遍历节点x[k-1]的邻接节点(状态空间) x[k] = node if not conflict(k): # 剪枝 tsp(k+1) # 测试 x[0] = c # 出发节点:路径x的第一个节点(随便哪个) tsp(1) # 开始处理解x中的第2个节点 print(best_x) print(min_cost)
效果图
更多关于Python相关内容可查看本站专题:《Python数据结构与算法教程》、《Python Socket编程技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》
希望本文所述对大家Python程序设计有所帮助。
- Golang语言--资源自动回收技术
- Oracle 12.2中的一个参数说明(r12笔记第76天)
- Golang语言社区--【游戏服务器知识】多线程并发
- 用100行Nodejs代码写微博爬虫
- MySQL无法创建表的问题分析(r12笔记第73天)
- Golang语言社区--【H5游戏开发基础知识】JavaScript 用法
- Oracle中的PGA监控报警分析二(r12笔记第87天)
- Oracle 12c PDB的数据备份恢复(r12笔记第84天)
- MySQL和Oracle中唯一性索引的差别(r12笔记第83天)
- 如何用JavaScript进行数组去重
- Oracle 12.1升级到12.2的两种方法(r12笔记第92天)
- Oracle数据库重启后密码失效的问题(r12笔记第91天)
- Oracle和MySQL竟然可以这么写这样的SQL?(r12笔记第99天)
- Golang语言社区--了解C++ 用libcurl库进行http通讯网络编程
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- StackExchange.Redis通用封装类分享
- Invoke 和 BeginInvoke 的区别
- 知识卡片 生成特定形状的词云
- Redis-五种数据类型解析
- MYSQL一次千万级连表查询优化
- mysql explain用法和结果的含义
- PrimeVue 入门
- 使用神经网络为图像生成标题
- 详解匈牙利算法与二分图匹配
- clusterProfiler到底有多难安装呢
- 有些包卸载了就回不去了
- 使用 Vue-CLI 3.x 快速搭建「Vue + TS + Kbone + Kbone-UI + 云开发」 项目
- 「R」R Docker 教程(续)
- 为什么R4.0版本内置的R包那么多
- 为何cytoscape总是说我没有java呢