问题

旅行商问题(Traveling Salesman Problem,TSP)是旅行商要到若干个城市旅行,各城市之间的费用是已知的,为了节省费用,旅行商决定从所在城市出发,到每个城市旅行一次后返回初始城市,问他应选择什么样的路线才能使所走的总费用最短?

分析

此问题可描述如下:G=(V,E)是带权的有向图,找到包含V中每个结点一个有向环,亦即一条周游路线,使得这个有向环上所有边成本之和最小。

这个问题与前一篇文章的区别就是,本题是带权的图。只要一点小小的修改即可。

解的长度是固定的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 回溯法 子集树模板 系列 —— 9、旅行商问题(TSP)的更多相关文章

  1. python 回溯法 子集树模板 系列 —— 18、马踏棋盘

    问题 将马放到国际象棋的8*8棋盘board上的某个方格中,马按走棋规则进行移动,走遍棋盘上的64个方格,要求每个方格进入且只进入一次,找出一种可行的方案. 分析 说明:这个图是5*5的棋盘. 图片来 ...

  2. python 回溯法 子集树模板 系列 —— 17、找零问题

    问题 有面额10元.5元.2元.1元的硬币,数量分别为3个.5个.7个.12个.现在需要给顾客找零16元,要求硬币的个数最少,应该如何找零?或者指出该问题无解. 分析 元素--状态空间分析大法:四种面 ...

  3. python 回溯法 子集树模板 系列 —— 16、爬楼梯

    问题 某楼梯有n层台阶,每步只能走1级台阶,或2级台阶.从下向上爬楼梯,有多少种爬法? 分析 这个问题之前用分治法解决过.但是,这里我要用回溯法子集树模板解决它. 祭出元素-状态空间分析大法:每一步是 ...

  4. python 回溯法 子集树模板 系列 —— 15、总结

    作者:hhh5460 时间:2017年6月3日 用回溯法子集树模板解决了这么多问题,这里总结一下使用回溯法子集树模板的步骤: 1.确定元素及其状态空间(精髓) 对每一个元素,遍历它的状态空间,其它的事 ...

  5. python 回溯法 子集树模板 系列 —— 14、最长公共子序列(LCS)

    问题 输入 第1行:字符串A 第2行:字符串B (A,B的长度 <= 1000) 输出 输出最长的子序列,如果有多个,随意输出1个. 输入示例 belong cnblogs 输出示例 blog ...

  6. python 回溯法 子集树模板 系列 —— 10、m着色问题

    问题 图的m-着色判定问题 给定无向连通图G和m种不同的颜色.用这些颜色为图G的各顶点着色,每个顶点着一种颜色,是否有一种着色法使G中任意相邻的2个顶点着不同颜色? 图的m-着色优化问题 若一个图最少 ...

  7. python 回溯法 子集树模板 系列 —— 8、图的遍历

    问题 一个图: A --> B A --> C B --> C B --> D B --> E C --> A C --> D D --> C E -- ...

  8. python 回溯法 子集树模板 系列 —— 3、0-1背包问题

    问题 给定N个物品和一个背包.物品i的重量是Wi,其价值位Vi ,背包的容量为C.问应该如何选择装入背包的物品,使得放入背包的物品的总价值为最大? 分析 显然,放入背包的物品,是N个物品的所有子集的其 ...

  9. python 回溯法 子集树模板 系列 —— 13、最佳作业调度问题

    问题 给定 n 个作业,每一个作业都有两项子任务需要分别在两台机器上完成.每一个作业必须先由机器1 处理,然后由机器2处理. 试设计一个算法找出完成这n个任务的最佳调度,使其机器2完成各作业时间之和达 ...

随机推荐

  1. 团队项目第二阶段个人进展——Day1

    一.昨天工作总结 冲刺第一天,查看了第一阶段的代码 二.遇到的问题 写个的代码发现看不懂了 三.今日工作规划 重新设计页面布局

  2. Linux网络配置和网络诊断命令介绍

    方法/步骤 1 在接下来的讲解中,讲解的Linux网络配置和网络诊断的命令有: ifconfig.ping.netstat.traceroute.dig和nslookup.host.hostname. ...

  3. Jboss EAP 6 EJB调用常见问题

    1. 调用EJB的三种方法 调用EAP 6 EJB的第一种方法,使用JBoss API,如下: Properties p = new Properties(); p.put("remote. ...

  4. html基础笔记-表单、链接

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <!-- 字符编码U ...

  5. [Python_6] Python 配置 MySQL 访问

    0. 说明 Python 访问 MySQL 数据库,需要安装 MySQL 的 Python 插件. 1. 安装 MySQL 插件 pip install PyMySQL 2. 编写代码 # -*-co ...

  6. javascript 正则表达式的使用

    1. 语法 有两种定义正则表达式的方式 字面量形式 var expression = /pattern/flags 引用 MDN 的解释: pattern:正则表达式的文本. flags:标志,可以是 ...

  7. 第 14 章 结构和其他数据形式(names3)

    /*----------------------------------- names3.c -- 使用指针和 malloc() ----------------------------------- ...

  8. October 20th 2017 Week 42nd Friday

    My life is in these books. Read these and know my heart. 我的人生就在这些书中,读完他们就能读懂我的心. Some people say tha ...

  9. KMP、扩展KMP、Manacher习题

    照着这篇博客刷一下. 自己也做一下笔记 对于KMP算法,可以看我之前总结的这篇博客 hdu 3613 Best Reward 给一个字符串,字符由a~z构成,每个字符有一个权值.在某一点将字符串切成2 ...

  10. 【13】python time时间模块知识点备查

    表示时间的三种形式 # 时间模块 '''UTC(世界协调时间):格林尼治天文时间,世界标准时间,在中国来说是UTC+8DST(夏令时):是一种节约能源而人为规定时间制度,在夏季调快1个小时 时间的表示 ...