[精品文档]旅行商问题
旅行商问题

一、 问题描述旅行商问题:给定一个完全无向带权图G=(V,E),其每条边(u,v)∈E 有一非负整数权值w(u,v)。
要求找出G 的一条经过每个顶点一次且仅经过一次的回路,使得该回路上所有边的权值之和尽可能地小。
二、 算法分析旅行商问题的各个城市间的距离可以用代价矩阵来表示,就是邻接矩阵表示法。
如果E j i ∉),(,则∞=ij c 。
先说明旅行商问题具有最优解结构。
设s s s s p ,,.....,,21是从s 出发的一条路径长度最短的简单回路,假设从s 到下一个城市1s 已经求出,则问题转化为求1s 到S 的最短路径,显然s s s s p ,,.....,,21一定构成一条从1s 到S 的最短路径,如果不然,设s r r r s q ,,.....,,,211是一条从1s 到S 的最短路径且经过n-1个城市,则s r r r s s q ,,.....,,,,211将是从S 出发的路径长度最短的简单回路且比s s s s s p ,,.....,,,21要短,从而导致矛盾。
所以,旅行商问题一定满足最优性原理。
穷举法:穷举法解决旅行商问题的思路很简单,就是遍历所有可能的情况,然后把符合条件(最短)的路径找到并输出可以了。
动态规划法:假设从顶点i 出发,令)',(V i d 表示从顶点i 出发经过V ’中各个顶点一次且仅一次,最后回到出发点i 的最短路径的长度,开始时,V ’=V-{i},于是,旅行商问题的动态规划函数为:)({}),()'})}({',(min{)',(i k c k d V k k V k d c V i d ki ik ≠=∈-+=)2()1( 下面举个实例说明算法的执行过程。
下图是无向带权图的邻接矩阵表示法:⎢⎢⎢⎢⎣⎡∞=763C323∞ 226∞ ⎥⎥⎥⎥⎦⎤∞237在上图所示的带权图中,从城市0出发,经城市1,2,3然后回到城市0的最短路径长度为:})}2,1{,3(}),3,1{,2(}),3,2{,1(min{})3,2,1{,0(030201d c d c d c d +++=这是最后一个阶段的决策,它必须知道})3,1{,3(}),3,1{,2(}),3,2{,1(d d d 的计算结果,而:})}2{,3(}),3{,2(min{})3,2{,1(1312d c d c d ++=})}1{,3(}),3{,1(min{})3,1{,2(2321d c d c d ++= })}1{,2(}),2{,1(min{})2,1{,3(3231d c d c d ++=这一阶段的决策又依赖于下面的计算结果:{}),2(})2{,3({}),,3(})3{,2({}),,2(})2{,1(322312d c d d c d d c d +=+=+= {}),1(})1{,3({}),,1(})1{,2({}),,3(})3{,1(312113d c d d c d d c d +=+=+= 而下面的就可以直接获得(括号中是该策略引起的路径):)03(7{}),3(),02(6{}),2(),01(3})0{,1(302010>-==>-==>-==c d c d c d向前推导,可以得到:)23(862{}),2(})2{,3()13(633{}),1(})1{,3()12(532{}),1(})1{,2()32(972{}),3(})3{,2()31(1073{}),3(})3{,1()21(862{}),2(})2{,1(323121231312>-=+=+=>-=+=+=>-=+=+=>-=+=+=>-=+=+=>-=+=+=d c d d c d d c d d c d d c d d c d再向前推导有:)23(7}7,11min{})}1{,2(}),2{,1(min{})2,1{,3()32(8}8,12min{})}1{,3(}),3{,1(min{})3,1{,2()21(11}11,11min{})}2{,3(}),3{,2(min{})3,2{,1(323123211312>-==++=>-==++=>-==++=d c d c d d c d c d d c d c d 最后有:})}2,1{,3(}),3,1{,2(}),3,2{,1(min(})3,2,1{,0(030201d c d c d c d +++=)302010(14}14,14,14min{}77,86,113min{>->->-==+++=or or所以,从顶点0出发的旅行商问题的最短路径长度为14,其中一条路径为01320>->->->-。
A星算法求解旅行商问题(可打印修改)

int size = str_arr.length; int[] int_arr = new int[size];
for(int i = 0; i < size; i ++){ int_arr[i] = Integer.valueOf(str_arr[i]);
}
return int_arr; }
//获取所有路径中最短的路径 private int get_min_distance(){
FileInputStream fi = new FileInputStream(file);
InputStreamReader ir = new InputStreamReader(fi);
BufferedReader br = new BufferedReader(ir);
//------------------------------------
城市之间的距离:通过 n*n 矩阵 city_distance 表示,其中 n 表示城市的个数。编号为 k 的城市到各个城市之间的距离可以从第(k-1)行获取。
open 表:用队列表示,城市结点进入队列之前需要根据估计值 fvalue 按升序排列。
close 表:用向量表示。 搜索图:搜索图通过 open 表构建,将路径的编号保存在一个数组 id_list 中。 四、实验结果和分析 1、输入数据 第一行的数Байду номын сангаас 8 表示城市结点的个数,后面是一个 8*8 的数组,数组的值表示城市之 间的距离。任何一个结点到自身的距离是 0,数组中的第 0 行表示第 1 个城市到各个城市 之间的距离,其他的可类推。
Astar 算法求解旅行商问题
一、问题描述 一共有 n 个城市,某推销员从其中的一个城市 A 出发经过每个城市一次且仅一次后回
图算法--旅行商问题

图算法--旅⾏商问题旅⾏商问题的描述试想⼀下,⼀个业务员因⼯作需要必须访问多个城市。
他的⽬标是每个城市只访问⼀次,并且尽可能地缩短旅⾏的距离,最终返回到他开始旅⾏的地点,这就是旅⾏商问题的主要思想。
在⼀幅图中,访问每个顶点⼀次,并最终返回起始顶点,这个访问的轨迹称为哈密顿圈。
要解决旅⾏商问题,需要⽤图G=(V,E)作为模型,寻找图中最短的哈密顿圈。
G是⼀个完整的、⽆⽅向的带权图,其中V代表将要访问的顶点的集合,E为连接这些顶点的边的集合。
E中每条边的权值由顶点之间的距离决定。
由于G中⼀个完整的、⽆⽅向的图,因此E包含V(V-1)/2条边。
事实上,旅⾏商问题是⼀种特殊的⾮多项式时间问题,称为NP完全问题。
NP完全问题是指那些多项式时间算法未知,倘没有证据证明没有解决的可能性的问题。
考虑到这种思想,通常⽤⼀种近似算法来解决旅⾏商问题。
最近邻点法的应⽤⼀种近似的计算旅⾏商路线的⽅法就是使⽤最近邻点法。
其运算过程如下:从⼀条仅包含起始顶点的路线开始,将此顶点涂⿊。
其他顶点为⽩⾊,在将其他顶点加⼊此路线中后,再将相应顶点涂⿊。
接着,对于每个不在路线中的顶点v,要为最后加⼊路线的顶点u与v之间的边计算权值。
在旅⾏商问题中,u与v之间边的权值就是u到v 之间的距离。
这个距离可以⽤每个顶点的坐标计算得到。
两个点(x1,y1)与(x2,y2)之间距离的计算公式如下:r = √(x2 - x1)2 + (y2 - y1)2 (注意是求和的平⽅根)利⽤这个公式,选择最接近u的顶点,将其涂⿊,同时将其加⼊路线中。
接着重复这个过程,直到所有的顶点都涂成⿊⾊。
此时再将起始顶点加⼊路线中,从⽽形成⼀个完整的回路。
下图展⽰了使⽤最近邻点法来解决旅⾏商问题的⽅法。
通常,在为旅⾏商问题构造⼀个图时,每个顶点之间相连的边不会显⽰表⽰出来,因为这种表⽰会让图不清晰了,也没有必要。
在图中,每个顶点旁边都显⽰其坐标值,虚线表⽰在此阶段需要⽐较距离的边。
算法论文:旅行商问题的求解方法(动态规划法和贪心法)讲解

旅行商问题的求解方法摘要旅行商问题(TSP问题)时是指旅行家要旅行n个城市然后回到出发城市,要求各个城市经历且仅经历一次,并要求所走的路程最短。
该问题又称为货郎担问题、邮递员问题、售货员问题,是图问题中最广为人知的问题。
本文主要介绍用蛮力法、动态规划法、贪心法和分支限界法求解TSP问题,其中重点讨论动态规划法和贪心法,并给出相应求解程序。
关键字:旅行商问题;动态规划法;贪心法;分支限界法1引言旅行商问题(TSP)是组合优化问题中典型的NP-完全问题,是许多领域内复杂工程优化问题的抽象形式。
研究TSP的求解方法对解决复杂工程优化问题具有重要的参考价值。
关于TSP的完全有效的算法目前尚未找到,这促使人们长期以来不断地探索并积累了大量的算法。
归纳起来,目前主要算法可分成传统优化算法和现代优化算法。
在传统优化算法中又可分为:最优解算法和近似方法。
最优解算法虽然可以得到精确解,但计算时间无法忍受,因此就产生了各种近似方法,这些近似算法虽然可以较快地求得接近最优解的可行解,但其接近最优解的程度不能令人满意。
但限于所学知识和时间限制,本文重点只讨论传统优化算法中的动态规划法、贪心法和分支限界法,并对蛮力法做简单介绍,用以比较。
2正文2.1蛮力法2.1.1蛮力法的设计思想蛮力法所依赖的基本技术是扫描技术,即采用一定的策略将待求解问题的所有元素一次处理一次,从而找出问题的解。
一次处理所有元素的是蛮力法的关键,为了避免陷入重复试探,应保证处理过的元素不再被处理。
在基本的数据结构中,一次处理每个元素的方法是遍历。
2.1.2算法讨论用蛮力法解决TSP问题,可以找出所有可能的旅行路线,从中选取路径长度最短的简单回路。
如对于图1,我们求解过程如下:(1)路径:1->2->3->4->1;路径长度:18;(2)路径:1->2->4->3->1;路径长度:11;(3)路径:1->3->2->4->1;路径长度:23;(4)路径:1->3->4->2->1;路径长度:11;(5) 路径:1->4->2->3->1;路径长度:18;(6) 路径:1->4->3->2->1;路径长度:18;从中,我们可以知道,路径(2)和(4)路径长度最短。
建模经典问题——旅行商问题图文 文档全文预览

目录第7章 旅行商问题1.问题概述2.求解算法2.1.下界和上界算法2.2.分支定界法2.3.动态规划法2.5.近似算法2.5.竞赛题
2
§7-1 问题概述一 、数学模型1.标准TSP旅行商问题(简称TSP ), 也称货郎担问题或 旅行推销员问题,是运筹学中一个著名的问题,其 一般提法为:有一个旅行商从城市1出发,需要到 城市2、3、 …、n 去推销货物,最后返回城市1,若 任意两个城市间的距离已知,则该旅行商应如何选 择其最佳行走路线?
18
TS 多面体研究中的一个重要问题就是寻找能导出Q” 最大面的不等式, Grotschel 等人发现了一类很重要的能导 出最大面的梳子不等式,并予以了证明。此外,还有其它 能导出最大面的不等式,如团树不等式等。可见, Q" 的最 大面极多,曾经计算过由梳子不等式所导出的最大面个数 如表7-1所示:表 7 - 1
27
对结点i的e(i)1, 边e(i)1 的一个结点为i, 另 一 个结点为j=dmi n_j(i,1), 若e(i)1 也是结点j 关联边 中最小的两条边之一,即i =dmin_j(j,1) 或 i=dmin_j(j,2 ), 则对边e(i)1 来说就不需要调整,否则 按以下方式调整:
8
从严格的数学意义而言,瓶颈TSP (简称BTSP )并没有降低问题的难度,也未能提供任何特殊的解决 办法。瓶颈TSP的数学模型与标准TSP类似,仅目标函 数不同:min Z=max{d,·xi|i,jeV}
由于目标函数为瓶颈值,故求得的最佳巡回路 线与标准TSP的往往截然不同。
16
称X为路线T的关联向量,其m=n(n-2)/2 个分量中,恰好 有个为1,其余的都为0。图有许多H amilt on回路,设为T₁.T₂.…T,, 对应的关联向 量记为X₁,X₂…X 。, 在m维空间Rm中,考虑这些向量生成的 凸包( convex hull) Q":
旅行商问题+背包问题--经典问题

旅⾏商问题+背包问题--经典问题问题描述:旅⾏商问题(Traveling Salesman Problem,TSP)是旅⾏商要到若⼲个城市旅⾏,各城市之间的费⽤是已知的,为了节省费⽤,旅⾏商决定从所在城市出发,到每个城市旅⾏⼀次后返回初始城市,问他应选择什么样的路线才能使所⾛的总费⽤最短?此问题可描述如下:设G=(V,E)是⼀个具有边成本cij的有向图,cij的定义如下,对于所有的i和j,cij>0,若<i,j>不属于E,则cij=∞。
令|V|=n,并假设n>1。
G的⼀条周游路线是包含V中每个结点的⼀个有向环,周游路线的成本是此路线上所有边的成本和。
旅⾏商问题(Traveling Saleman Problem,TSP)⼜译为旅⾏推销员问题、货郎担问题,简称为TSP问题,是最基本的路线问题,该问题是在寻求单⼀旅⾏者由起点出发,通过所有给定的需求点之后,最后再回到原点的最⼩路径成本。
最早的旅⾏商问题的数学规划是由Dantzig(1959)等⼈提出。
TSP问题在物流中的描述是对应⼀个物流配送公司,欲将n个客户的订货沿最短路线全部送到。
如何确定最短路线。
TSP问题最简单的求解⽅法是枚举法。
它的解是多维的、多局部极值的、趋于⽆穷⼤的复杂解的空间,搜索空间是n个点的所有排列的集合,⼤⼩为(n-1)。
可以形象地把解空间看成是⼀个⽆穷⼤的丘陵地带,各⼭峰或⼭⾕的⾼度即是问题的极值。
求解TSP,则是在此不能穷尽的丘陵地带中攀登以达到⼭顶或⾕底的过程。
问题分析旅⾏商问题要从图G的所有周游路线中求取最⼩成本的周游路线,⽽从初始点出发的周游路线⼀共有(n-1)!条,即等于除初始结点外的n-1个结点的排列数,因此旅⾏商问题是⼀个排列问题。
排列问题⽐⼦集合的选择问题通常要难于求解得多,这是因为n个物体有n!种排列。
通过枚举(n-1)!条周游路线,从中找出⼀条具有最⼩成本的周游路线的算法,其计算时间显然为O(n!)。
旅行商问题 Traveling Salesman Problem

• 旅行商问题吸引了越来越多的人对它进行研究。 其中,有数学家,计算机科学家,运筹学家,还 有一些其它领域的研究者。
• 增加变异概率实际上是把遗传算法退化成了一种 纯粹的随机搜索,所谓的自适应也无从谈起!
灾变思想
• 那么如何解决遗传算法容易陷入局部极值的问题呢? • 让我们来看看大自然提供的方案。六千五百万年以前,恐
龙和灵长类动物并存,恐龙在地球上占绝对统治地位,如 果恐龙没有灭绝灵长类动物是绝没有可能统治地球的。正 是恐龙的灭绝才使灵长类动物有了充分进化的余地。 • 事实上地球至少经历了5次物种大灭绝,每次物种灭绝都 给更加高级的生物提供了充分进化的余地。 • 所以要跳出局部极值就必须杀死当前所有的优秀个体,从 而让远离当前极值的点有充分的进化余地。这就是灾变思 想。
Traveling Salesman Problem (TSP)
旅行商问题的发展历史
• 旅行商问题,也称货郎担问题,是一个较 古老的问题。其起源已经有些模糊了。最 早大概可以追溯到 1759 年 Euler 提出的骑 士旅行问题。
• 十九世纪初,爱尔兰数学家William R. Hamilton和英国数学家Thomas P. Kirkman 研究过一些与旅行商问题相关的数学问题。
• 对旅行商问题的研究经过几十年的发展,已经产生了许多 其它扩展形式,例如多旅行商问题(Multi-Salesman Problem),多目标旅行商问题(Multi-Objective TSP)等等。
旅行商问题

旅行商问题
旅行商问题(Traveling Salesman Problem,TSP)是一个有着悠久历史的经典优化问题,也是一个非常重要的研究领域。
贪婪法是常用的解决TSP问题的算法之一。
它的思想是每次都选择与当前位置最近的城市,最后回到出发城市,进而完成一个TSP问题的解决。
贪婪法的TSP问题可以通过求解最佳匹配(Minimazing Tour Cost)而简单地实现。
它要求先求出各城市带来的价值,然后将价值作为各城市之间的距离权重,计算出最佳匹配。
另外,贪婪算法解决TSP问题还可以使用基于穷举搜索的解法。
它对所有有可能存在的路线进行排查,从而最终求出最短路径长度。
但是,由于TSP问题的解空间很大,穷举搜索的解法无法保证能够求出最优解,运行时间也增加了很多,贪婪算法求解TSP问题速度较快。
总之,贪婪算法解决TSP问题能够在短时间内快速求出最短路径,但是求得的解不一定是最优解,而且TSP问题求解的解空间非常大,仍然有很多未知问题需要进一步研究。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
算法设计与分析实验报告实验三旅行商问题
院系:
班级:计算机科学与技术
学号:
姓名:
任课教师:
成绩:
湘潭大学
2016年5月
实验三旅行商问题
一. 实验内容
分别编程实现回溯法和分支限界法求TSP问题的最优解,分析比较两种算法的时间复杂度并验证分析结果。
二.实验目的
1、掌握回溯法和分支限界法解决问题的一般步骤,学会使用回溯法和分支限界法解决实际问题;
2、理解回溯法和分支限界法的异同及各自的适用范围。
三. 算法描述
旅行商问题的回溯法算法可描述如下:
Template <class Type>
Class Traveling{
friend Type TSP(int ** , int[],int ,Type);
Private;
Void Backtrack(int i);
Int n, //图G的顶点数
*x; //当前解
*bestx; //当前最优解
Type **a, //图G的邻接矩阵
cc, //当前费用
bestc,//当前最优解
NoEdge; //无边标记
};
Template <class Type>
Void Traveling<Type> : : backtrack(int i)
{if(i ==n){
if(a[x[n-1]][x[n]]!=NoEdge&&a[x[n]][1]!=NoEdge&&
(cc+a[x[n-1]][x[n]]+a[x[n]][1] +a[x[n]][1]<bestc || bestc == NoEdge)){
for(int j = 1;j<=n;j++) bestx[j] = x[j];
bestc == cc + a[x[n-1]][x[n]]+a[x[n]][1]};
}else{
For (int j = i;j<= n;j++)
//是否可进入x[j]子树?
If(a[x[i-1]][x[j]] != NoEdge &&(cc+a[x[i-1]][x[j]] < bestc || bestc == NoEdge)){ //搜素子树
Swap(x[i],x[j]);
cc += a[x[i-1]][x[i]];
Backtrack(i + 1);
cc -= a[x[i-1]][x[i]];
Swap(x[i],x[j]);
}
}
}
Template<class Type>
Type TSP(Type**a, int v[], int n, Type NoEdge)
{Traveling<Type> Y;
//初始化Y
Y.x = new int [n+1];
//置x为单位排列
For(int i = 1;i <= n;i++)
Y.x[i] = i;
Y.a = a;
Y.n = n;
Y.bestc = NoEdge;
Y.bestx = v;
= 0;
Y.NoEdge = NoEdge;
//搜索x[2:n]的全排列
Y.Backtrack(2);
Delete[]Y.x;
Return Y.bestc;
}
算法效率:
如果不考虑更新bestx所需的计算时间,则Backtrack需
要O((n-1)!)计算时间。
由于算法Backtrack在最坏情款下
可能需要更新当前最优解O((n-1)!)次,每次更新需O(n)
计算时间,从而整个算法的计算时间复杂性为O(n!)。
旅行商问题的分支界限法算法可描述如下:
使用优先队列来存储活节点,优先队列中的每个活节点都存储从根到该活节点的相应路径。
具体算法可描述如下:
Template<class Type>
Class MinHeapNode{
firend Traveling<Type>;
Public:
Operator Type() const {return lcost;}
Private:
Type lcost, //子树费用的下界
cc, //当前费用。