精选数据结构课设TSP贪心算法Word文档下载推荐.docx
《精选数据结构课设TSP贪心算法Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《精选数据结构课设TSP贪心算法Word文档下载推荐.docx(12页珍藏版)》请在冰豆网上搜索。
![精选数据结构课设TSP贪心算法Word文档下载推荐.docx](https://file1.bdocx.com/fileroot1/2022-12/12/40045a75-7227-46a5-819c-b4bb982d09b6/40045a75-7227-46a5-819c-b4bb982d09b61.gif)
该问题又称为货郎担问题、邮递员问题、售货员问题,是图问题中最广为人知的问题。
2)基本要求
(1)上网查找TSP问题的应用实例;
(2)分析求TSP问题的全局最优解的时间复杂度;
(3)设计一个求近似解的算法;
(4)分析算法的时间复杂度。
3)设计思想
对于TSP问题,一种最容易想到的也肯定能得到最佳解的算法是穷举法,即考虑所有可能的旅行路线,从中选择最佳的一条。
但是用穷举法求解TSP问题的时间复杂度为Ο(n!
),当n大到一定程度后是不可解的。
4)设计思想
本实验只要求近似解,可以采用贪心法求解:
任意选择某个城市作为出发点,然后前往最近的未访问的城市,直到所有的城市都被访问并且仅被访问一次,最后返回到出发点。
为便于查找离某顶点最近的邻接点,可以采用邻接矩阵存储该图。
算法用伪代码描述如下:
1.
任意选择某个顶点v作为出发点;
2.
执行下述过程,直到所有顶点都被访问:
2.1v=最后一个被访问的顶点;
2.2
在顶点v的邻接点中查找距离顶点v最近的未被访问的邻接点j;
访问顶点j;
3.
从最后一个访问的顶点直接回到出发点v;
四、参考文献
1.王红梅,数据结构,清华大学出版社;
2.王红梅,数据结构学习辅导与实验指导,清华大学出版社;
3.王晓东,计算机算法设计与分析,电子工业出版社。
一、TSP问题
TSP问题(TravellingSalesmanProblem)即旅行商问题,又译为旅行推销员问题、货郎担问题,是数学领域中著名问题之一。
假设有一个旅行商人要拜访n个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。
路径的选择目标是要求得的路径路程为所有路径之中的最小值。
TSP问题是一个组合优化问题。
该问题可以被证明具有NPC计算复杂性。
TSP问题可以分为两类,一类是对称TSP问题(SymmetricTSP),另一类是非对称问题(AsymmetricTSP)。
所有的TSP问题都可以用一个图(Graph)来描述:
V={c1,c2,…,ci,…,cn},i=1,2,…,n,是所有城市的集合.ci表示第i个城市,n为城市的数目;
E={(r,s):
r,s∈V}是所有城市之间连接的集合;
C={crs:
r,s∈V}是所有城市之间连接的成本度量(一般为城市之间的距离);
如果crs=csr,那么该TSP问题为对称的,否则为非对称的。
一个TSP问题可以表达为:
求解遍历图G=(V,E,C),所有的节点一次并且回到起始节点,使得连接这些节点的路径成本最低。
二、贪心算法
贪心算法,又名贪婪算法,是一种常用的求解最优化问题的简单、迅速的算法。
贪心算法总是做出在当前看来最好的选择,它所做的每一个在当前状态下某种意义上是最好的选择即贪心选择,并希望通过每次所作的贪心选择导致最终得到问题最优解。
必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。
1、贪心算法的基本思路
从问题的某一个初始解触发逐步逼近给定的目标,以尽可能快地求得更好的解。
当达到某算法中的某一步不能再继续前进时,算法停止。
大致步骤如下:
1)建立数学模型来描述问题;
2)把求解的问题分成若干个子问题
3)对每一个子问题求解,得到子问题的局部最优解
4)把子问题的局部最优解合成原问题的一个解
2、贪心算法的实现框架
贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择,而贪心策略适用的前提是:
局部最优策略能导致产生全局最优解。
从问题的某一初始解出发;
while(能朝给定总目标前进一步)
{
利用可行的决策,求出可行解的一个解元素;
}
由所有解元素组合成问题的一个可行解;
3、贪心算法存在的问题
1)不能保证求得的最后解是最佳的;
2)不能用来求最大最小解问题;
3)只能在某些特定条件约束的情况下使用,例如贪心策略必须具备无后效性等。
4、典型的贪心算法使用领域
马踏棋盘、背包、装箱等。
三、问题求解:
TSP问题,要求先画一个旅行的线路图的图示,然后假设有个人,遍历所有的旅行的城市,考虑所有可能的旅行路线,从中选择最佳的一条。
突出其中用到的中间数据是:
数组形式,初始数据是各个城市间的距离。
假设我们进行我们的旅游计划,共五个城市,然后前往最近的未访问的城市,直到所有的城市都被访问并且仅被访问一次,最后返回到出发点。
要求这时遍历各城市的距离为最短距离。
当我们要求整体的最优解时,可以从它的局部最优解求的,抱着这样的思想我们从起始城市1出发比较与之最近的城市的距离是2(2号城市),由于不能返回,所以从2号城市继续寻找与之最近的城市(1号城市除外)的距离是4(3号城市),以此类推,最终在返回起始城1。
补充:
上面的最短距离要记录下来,求和,则得到最短路径。
如果城市数目增加,则重复第一个城市到第二个城市这个步骤。
在计算机中实现这个程序,则要记住每个最优城市的标号。
存放数组中,再输出最优路径。
四、程序流程图:
五、核心源程序清单和执行结果
packagetwl;
importjava.io.BufferedReader;
importjava.io.FileInputStream;
importjava.io.IOException;
importjava.io.InputStreamReader;
publicclassTxTsp{
privateintcityNum;
//城市数量
privateint[][]distance;
//距离矩阵
privateint[]col;
//代表列,也表示是否走过,走过置0
privateint[]row;
//代表行,选过置0
publicTxTsp(intn){
cityNum=n;
privatevoidinit(Stringfilename)throwsIOException{
//读取数据
int[]x;
int[]y;
Stringstrbuff;
BufferedReaderdata=newBufferedReader(newInputStreamReader(
newFileInputStream(filename)));
distance=newint[cityNum][cityNum];
x=newint[cityNum];
y=newint[cityNum];
for(inti=0;
i<
cityNum;
i++){
//读取一行数据,数据格式167341453
strbuff=data.readLine();
//字符分割
String[]str=strbuff.split("
"
);
x[i]=Integer.valueOf(str[1]);
//x坐标
y[i]=Integer.valueOf(str[2]);
//y坐标
}
data.close();
//计算距离矩阵
//,针对具体问题,距离计算方法也不一样,此处用的是TSPlib上的att48作为案例,它有48个城市,距离计算方法为伪欧氏距离(最优值为10628)
cityNum-1;
distance[i][i]=0;
//对角线为0
for(intj=i+1;
j<
j++){
doublerij=Math
.sqrt(((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])
*(y[i]-y[j]))/10.0);
//四舍五入,取整
//inttij=(int)Math.round(rij);
//if(tij<
rij){
//distance[i][j]=tij+1;
//distance[j][i]=distance[i][j];
//}else{
//distance[i][j]=tij;
//}
distance[i][j]=(int)rij+1;
distance[j][i]=distance[i][j];
//矩阵对称
}
distance[cityNum-1][cityNum-1]=0;
//矩阵右下角
col=newint[cityNum];
col[0]=0;
for(inti=1;
col[i]=1;
row=newint[cityNum];
row[i]=1;
publicvoidsolve(){
int[]temp=newint[cityNum];
Stringpath="
0"
;
ints=0;
//计算距离
inti=0;
//当前节点
intj=0;
//下一个节点
//默认从0开始
while(row[i]==1){
//复制距离矩阵一行
for(intk=0;
k<
k++){
temp[k]=distance[i][k];
//System.out.print(temp[k]+"
//System.out.println();
//选择下一个节点,要求不是已经走过,并且与i不同
j=selectmin(temp);
//找出下一节点
row[i]=0;
//行置0,表示已经选过
col[j]=0;
//列0,表示已经走过
path+="
-->
"
+j;
//System.out.println(i+"
+j);
//System.out.println(distance[i][j]);
s=s+distance[i][j];
i=j;
//当前节点指向下一节点
System.out.println("
路径:
+path);
总距离为:
+s);
publicintselectmin(int[]p){
intj=0,m=p[0],k=0;
//寻找第一个可用节点,注意最后一次寻找,没有可用节点
while(col[j]==0){
j++;
//System.out.print(j+"
if(j>
=cityNum){
//没有可用节点,说明已结束,最后一次为*-->
m=p[0];
break;
//或者直接return0;
else{
m=p[j];
//从可用节点J开始往后扫描,找出距离最小节点
for(;
if(col[j]==1){
if(m>
=p[j]){
m=p[j];
k=j;
}
returnk;
publicvoidprintinit(){
printbegin...."
for(intj=0;
System.out.print(distance[i][j]+"
System.out.println();
printend...."
publicstaticvoidmain(String[]args)throwsIOException{
Start...."
TxTspts=newTxTsp(48);
ts.init("
."
+File.separotor+"
data.txt"
//ts.printinit();
ts.solve();
}
运行结果:
Start....
0-->
8-->
37-->
30-->
43-->
17-->
6-->
27-->
35-->
29-->
5-->
36-->
18-->
26-->
42-->
16-->
45-->
32-->
14-->
11-->
10-->
22-->
13-->
24-->
12-->
20-->
46-->
19-->
39-->
2-->
21-->
15-->
40-->
33-->
28-->
4-->
47-->
38-->
31-->
23-->
9-->
41-->
25-->
3-->
34-->
44-->
1-->
7-->
12842
五、总结
单从求解结果来看,我个人其实还是能接受这个解,但仔细想想,实际上这个求解结果有太多运气成分在里面,贪心算法毕竟是贪心算法,只能缓一时,而不是长久之计,问题的模型、参数对贪心算法求解结果具有决定性作用,这在某种程度上是不能接受的,于是聪明的人类就发明了各种智能算法(也叫启发式算法),但在我看来所谓的智能算法本质上就是贪心算法和随机化算法结合,例如传统遗传算法用的选择策略就是典型的贪心选择,正是这些贪心算法和随机算法的结合,我们才看到今天各种各样的智能算法。