TSP问题-程序员宅基地

技术标签: 启发算法  

前言

TSP问题是广为人知的组合优化问题,它易于描述,但是难以求解。基于TSP问题的特性,决定使用通过TSP问题来学习各类启发算法,比较不同启发算法在旅行商问题上的表现。

问题

TSP问题可以描述为:现有一些节点,节点和节点之间均可相连形成边,节点之间的边存在距离,需要找到一个遍历方案先后访问所有的点,使的遍历的总距离最短。
在这里插入图片描述
在这里插入图片描述

模型

旅行商问题可以建模为一个纯整数规划模型:
在这里插入图片描述
目标函数最小化总距离,约束1-2保证每个节点都能进出一次,约束3保证不会出现多个圈,约束4-5保证便利顺序属于0~n-1,约束6-7约束变量为整数。

数据

数据集保存在distance.txt中,为纯距离数据,数据来源TSP问题官方dataset,共26个节点。

0	83	93	129	133	139	151	169	135	114	110	98	99	95	81	152	159	181	172	185	147	157	185	220	127	181
83	0	40	53	62	64	91	116	93	84	95	98	89	68	67	127	156	175	152	165	160	180	223	268	179	197
93	40	0	42	42	49	59	81	54	44	58	64	54	31	36	86	117	135	112	125	124	147	193	241	157	161
129	53	42	0	11	11	46	72	65	70	88	100	89	66	76	102	142	156	127	139	155	180	228	278	197	190
133	62	42	11	0	9	35	61	55	62	82	95	84	62	74	93	133	146	117	128	148	173	222	272	194	182
139	64	49	11	9	0	39	65	63	71	90	103	92	71	82	100	141	153	124	135	156	181	230	280	202	190
151	91	59	46	35	39	0	26	34	52	71	88	77	63	78	66	110	119	88	98	130	156	206	257	188	160
169	116	81	72	61	65	26	0	37	59	75	92	83	76	91	54	98	103	70	78	122	148	198	250	188	148
135	93	54	65	55	63	34	37	0	22	39	56	47	40	55	37	78	91	62	74	96	122	172	223	155	128
114	84	44	70	62	71	52	59	22	0	20	36	26	20	34	43	74	91	68	82	86	111	160	210	136	121
110	95	58	88	82	90	71	75	39	20	0	18	11	27	32	42	61	80	64	77	68	92	140	190	116	103
98	98	64	100	95	103	88	92	56	36	18	0	11	34	31	56	63	85	75	87	62	83	129	178	100	99
99	89	54	89	84	92	77	83	47	26	11	11	0	23	24	53	68	89	74	87	71	93	140	189	111	107
95	68	31	66	62	71	63	76	40	20	27	34	23	0	15	62	87	106	87	100	93	116	163	212	132	130
81	67	36	76	74	82	78	91	55	34	32	31	24	15	0	73	92	112	96	109	93	113	158	205	122	130
152	127	86	102	93	100	66	54	37	43	42	56	53	62	73	0	44	54	26	39	68	94	144	196	139	95
159	156	117	142	133	141	110	98	78	74	61	63	68	87	92	44	0	22	34	38	30	53	102	154	109	51
181	175	135	156	146	153	119	103	91	91	80	85	89	106	112	54	22	0	33	29	46	64	107	157	125	51
172	152	112	127	117	124	88	70	62	68	64	75	74	87	96	26	34	33	0	13	63	87	135	186	141	81
185	165	125	139	128	135	98	78	74	82	77	87	87	100	109	39	38	29	13	0	68	90	136	186	148	79
147	160	124	155	148	156	130	122	96	86	68	62	71	93	93	68	30	46	63	68	0	26	77	128	80	37
157	180	147	180	173	181	156	148	122	111	92	83	93	116	113	94	53	64	87	90	26	0	50	102	65	27
185	223	193	228	222	230	206	198	172	160	140	129	140	163	158	144	102	107	135	136	77	50	0	51	64	58
220	268	241	278	272	280	257	250	223	210	190	178	189	212	205	196	154	157	186	186	128	102	51	0	93	107
127	179	157	197	194	202	188	188	155	136	116	100	111	132	122	139	109	125	141	148	80	65	64	93	0	90
181	197	161	190	182	190	160	148	128	121	103	99	107	130	130	95	51	51	81	79	37	27	58	107	90	0

求解

使用ortools调用SCIP求解器对上述TSP问题进行求解。

import pandas as pd
from ortools.linear_solver import pywraplp

# 数据
distance = pd.read_table('distance.txt', header=None, index_col=None)
distance = distance.values.tolist()
city_num = len(distance)

# 求解器
solver = pywraplp.Solver.CreateSolver('SCIP')

# 决策变量
x = [[solver.IntVar(0, 1, 'x[{}][{}]'.format(i, j)) for j in range(city_num)] for i in range(city_num)]
y = [solver.IntVar(0, solver.infinity(), 'y[{}]'.format(i)) for i in range(city_num)]

# 目标函数
expression_obj = 0
for i in range(city_num):
    for j in range(city_num):
        expression_obj += distance[i][j] * x[i][j]
solver.Minimize(expression_obj)

# 约束
solver.Add(y[0] == 0, 'c0')
for i in range(city_num):
    solver.Add(sum([x[i][j] for j in range(city_num) if i != j]) == 1, 'c1[{}]'.format(i))  # 每个城市只能进一次
    solver.Add(sum([x[j][i] for j in range(city_num) if i != j]) == 1, 'c2[{}]'.format(i))  # 每个城市只能出一次
    solver.Add(y[i] <= city_num - 1, 'c3[{}]'.format(i))
    for j in range(1, city_num):
        if i == j:
            continue
        solver.Add(y[j] >= y[i] + 1 - (1 - x[i][j]) * city_num, 'c4[{}][{}]'.format(i, j))  # 防止多个圈

# 求解
# print(solver.ExportModelAsLpFormat(False))
print('number of variables = ', solver.NumVariables())
print('number of constraints = ', solver.NumConstraints())
status = solver.Solve()
# 结果
if status == solver.OPTIMAL:
    print('total length = ', solver.Objective().Value())
    print('the travel order is:')
    for i in range(city_num):
        for j in range(city_num):
            if y[j].solution_value() == i:
                print(j)
    print(0)
else:
    print('no optimal solution found')

结果

总旅行距离为937

number of variables =  702
number of constraints =  704
total length =  937.0
the travel order is:
0
24
23
22
25
21
20
16
17
19
18
15
10
11
12
14
13
9
8
7
6
4
5
3
2
1
0

Process finished with exit code 0
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_38442390/article/details/119838625

智能推荐

东北大学c语言编程及答案,东北大学c语言编程试题及其答案.doc-程序员宅基地

文章浏览阅读730次。东北大学C语言题库第一部分( 选择题 )1、构成C语言的基本单位是________。你的答案是:正确答案是:B过程函数语句命令2、设x为整型变量,不能正确表达数学关系:55<="">x>5&&x<10x==6||x==7||x==8||x==9!(x<=5)&&(x<10)3、在C语言中,逻辑运算符的优先级从高到低的排列顺序为__..._以下有关结构体类型描述正确的是 a.结构体类型的大小为其各成员所占内存的总和b.

c语言迪杰斯拉算法,麻烦改成迪杰特拉斯算法-程序员宅基地

文章浏览阅读61次。该楼层疑似违规已被系统折叠隐藏此楼查看此楼#includeusing namespace std;const int n=5; //n表示公园图中顶点个数const int e=7; //e表示公园图中路径bool visited[n+1];#define max 32767class graph{public:int arcs[n+1][n+1]; //领接矩阵int a[n+1][n+1];..._迪特拉斯算法代码

Vue学习看这篇就够_vue看这篇-程序员宅基地

文章浏览阅读183次。Vue -渐进式JavaScript框架介绍vue 中文网 vue github Vue.js 是一套构建用户界面(UI)的渐进式JavaScript框架库和框架的区别我们所说的前端框架与库的区别?Library库,本质上是一些函数的集合。每次调用函数,实现一个特定的功能,接着把控制权交给使用者代表:jQuery jQuery这个库的核心:DOM操作,即:封装DOM操作,简化DOM操作Framework框架,是一套完整的解决方案,使用框架的时候,需要把你的代码放到框架合适_vue看这篇

BUffalo 巴法络 Whr hp G300n 编程器固件以及非编程器固件可以说是大全了 免费下载_whr-hp-g300n最稳定固件-程序员宅基地

文章浏览阅读473次。前一阵帮同学折腾这个BUffalo 巴法络 Whr-hp-G300n的硬改,本来他系统刷的ubnt,不停重启,抱着死马当活马医的心态给各种固件折腾一通,最后修好。然后就下来几个固件,也等于亲自测试一遍,现在把能用的都传上来给大家分享下。请大家看好,有的是编程器固件,需要把rom拿下来刷的哈,自己找自己需要的吧。openwrt 非编程器固件:https://474b.com/file/20096151-445330538dd-wrt的编程器固件:https://474b.com/file/20096_whr-hp-g300n最稳定固件

习题7-4 求矩阵各行元素之和(15 分) 本题要求编写程序,求一个给定的m×n矩阵各行元素之和。_本题要求编写程序,求一个给定的m×n矩阵各行元素之和。输入格式:输入第一行给出两个正整数m和n(1≤-程序员宅基地

文章浏览阅读8.4w次,点赞18次,收藏50次。习题7-4 求矩阵各行元素之和(15 分)本题要求编写程序,求一个给定的m×n矩阵各行元素之和。输入格式:输入第一行给出两个正整数m和n(1≤m,n≤6)。随后m行,每行给出n个整数,其间以空格分隔。输出格式:每行输出对应矩阵行元素之和。输入样例:3 26 31 -83 12输出样例:9-715#include &lt;stdio.h&..._本题要求编写程序,求一个给定的m×n矩阵各行元素之和。输入格式:输入第一行给出两个正整数m和n(1≤m,n≤6)。随后m行,每行给出n个整数,其间以空格分隔。输出格式:每行输出对应矩阵行元素之和。

《入门级-Cocos2d 4.0塔防游戏开发》---第二课:游戏加载界面开发_cocos 塔防-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏5次。入门级-Cocos2d 4.0塔防游戏开发,模仿国王保卫战,一步一步教你怎么编写一个塔防游戏。_cocos 塔防

随便推点

uipath和python哪个好_UiPath从入门到精通视频教程-程序员宅基地

文章浏览阅读251次。匠厂出品,必属精品 Uipath中文社区qq交流群:465630324uipath中文交流社区:https://uipathbbs.comRPA之家qq群:465620839第一课--UiPath的安装与激活第二课--UiPath设计器介绍第三课--UiPath变量介绍第四课--UiPath条件判断第五课--UiPath循环第六课--UiPath整合流程控制语句第七课--UiPath邮件发送之..._uipath和python哪个好

Doolittle分解法(LU分解法)的Python实现_杜立特尔三角分解法python-程序员宅基地

文章浏览阅读7.2k次,点赞8次,收藏17次。在解一般的非奇异矩阵线性方程组的时候,或者在迭代改善算法中,需要使用LU分解法。对于一个一般的非奇异矩阵A=(a11, a12,…,a1n,a21,…ann),可分解为一个下三角矩阵L和一个上三角矩阵U。其中L的主对角线元素都是1.希望得到一个M,最后在需要的时候将M拆分为L和UM=[[u11 u12 u13 ...... u1n l21 u22 u23 ...... u2n ..._杜立特尔三角分解法python

python关键词统计_Python3 利用openpyxl 以及jieba 对帖子进行关键词抽取 ——对抽取的关键词进行词频统计...-程序员宅基地

文章浏览阅读384次。Python3 利用openpyxl 以及jieba 对帖子进行关键词抽取 ——对抽取的关键词进行词频统计20180413学习笔记一、工作前天在对帖子的关键词抽取存储后,发现一个问题。我似乎将每个关键词都存到分离的cell中,这样在最后统计总词频的时候,比较不好处理。于是,上回的那种样式:是不行的,应该把它们放到同一列(行)中,组装成一个list或tuple再进行词频统计。1.读取输出文件“t1..._openpyxl如何关键字出现计数

python在数据分析方面的应用、下列说法正确_智慧树知到大数据分析的python基础答案...-程序员宅基地

文章浏览阅读1.8k次。智慧树知到大数据分析的python基础答案在派生类中可以通过 “ 基类名 . 方法名 ()” 的方式来调用基类中的方法 .下面代码的执行结果是 : ( ) a = 10.99 print( complex(a))numpy 中求最大值方法是: ( )下面代码的输出结果是 : ( ) vlist = list( range(5)) print( vlist)计算numpy中元素个数的方法是: ( ..._关于python在数据分析方面的应用,以下说法正确的是哪些选项

win10硬盘锁怎么解除_win10如何使用bitlocker解锁硬盘加密-程序员宅基地

文章浏览阅读4.5k次。日常使用计算机的时候,有些情况下可能会遇到需要给bitlocker的加密进行解锁。win10如何使用bitlocker解锁硬盘加密?其实可在系统中直接进行操作。首先找到自己需要解锁的硬盘,右键找到需要进入的选项,初始化之后点击下一步然后再进行一系列的操作即可,具体步骤见下面详细介绍~win10如何使用bitlocker解锁硬盘加密1、选择需要加密的磁盘,然后右击,点击“启用bitlocker”;2..._csdn 硬盘带密码怎么解除

vue koa mysql_[全栈教程]用vue全家桶+koa2+soket.io +mysql写一个聊天应用-程序员宅基地

文章浏览阅读103次。tips:接下去会在github写博客,简书不再更新和修改文章,欢迎大家逛逛我的新博客点击查看 ,我会尽量用更容易理解的方式写好每一篇博客,大家一起学习交流????。vue-chat airchat介绍这是我的毕设项目,产品功能和页面参照qq,微信,TIM,不完全一样,有些是自己的想法。前后端都自己写。感觉是一个挺不错的全栈入门项目,各种交互各种业务逻辑,不花哨,但实用。对node(koa)和vue学习..._koa+mysql聊天功能实现

推荐文章

热门文章

相关标签