精选数据结构课设TSP贪心算法.docx
- 文档编号:4985125
- 上传时间:2022-12-12
- 格式:DOCX
- 页数:12
- 大小:96.24KB
精选数据结构课设TSP贪心算法.docx
《精选数据结构课设TSP贪心算法.docx》由会员分享,可在线阅读,更多相关《精选数据结构课设TSP贪心算法.docx(12页珍藏版)》请在冰豆网上搜索。
精选数据结构课设TSP贪心算法
数据结构课程设计
设计说明书
题目
TSP问题贪心算法
起止日期:
2014年11月10日至2014年11月17日
学生姓名
滕文亮
班级
113301班
成绩
指导教师(签字)
计算机科学与工程学院
2014年11月9日
课程设计任务书
一、设计目的
熟悉各种数据结构和运算,会使用数据结构的基本操作解决一些实际问题。
二、设计要求
在本课程设计过程中要求学生:
(1)重视课程设计环节,用严谨、科学和踏实的工作态度对待课程设计的每一项任务;
(2)按照课程设计的题目要求,独立地完成各项任务,严禁抄袭;凡发现抄袭,抄袭者与被抄袭者皆以零分计入本课程设计成绩。
凡发现实验报告或源程序雷同,涉及的全部人员皆以零分计入本课程设计成绩。
(3)学生在接受设计任务后,根据要求认真完成。
(4)认真编写课程设计报告。
三、设计内容
TSP问题(贪心法求解)
1)问题描述
所谓TSP问题是指旅行家要旅行n个城市,要求各个城市经历且仅经历一次,并要求所走的路程最短。
该问题又称为货郎担问题、邮递员问题、售货员问题,是图问题中最广为人知的问题。
2)基本要求
(1)上网查找TSP问题的应用实例;
(2)分析求TSP问题的全局最优解的时间复杂度;
(3)设计一个求近似解的算法;
(4)分析算法的时间复杂度。
3)设计思想
对于TSP问题,一种最容易想到的也肯定能得到最佳解的算法是穷举法,即考虑所有可能的旅行路线,从中选择最佳的一条。
但是用穷举法求解TSP问题的时间复杂度为Ο(n!
),当n大到一定程度后是不可解的。
4)设计思想
对于TSP问题,一种最容易想到的也肯定能得到最佳解的算法是穷举法,即考虑所有可能的旅行路线,从中选择最佳的一条。
但是用穷举法求解TSP问题的时间复杂度为Ο(n!
),当n大到一定程度后是不可解的。
本实验只要求近似解,可以采用贪心法求解:
任意选择某个城市作为出发点,然后前往最近的未访问的城市,直到所有的城市都被访问并且仅被访问一次,最后返回到出发点。
为便于查找离某顶点最近的邻接点,可以采用邻接矩阵存储该图。
算法用伪代码描述如下:
1. 任意选择某个顶点v作为出发点;
2. 执行下述过程,直到所有顶点都被访问:
2.1v=最后一个被访问的顶点;
2.2 在顶点v的邻接点中查找距离顶点v最近的未被访问的邻接点j;
2.2 访问顶点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 //读取一行数据,数据格式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) for(inti=0;i distance[i][i]=0;//对角线为0 for(intj=i+1;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 //distance[i][j]=tij+1; //distance[j][i]=distance[i][j]; //}else{ //distance[i][j]=tij; //distance[j][i]=distance[i][j]; //} 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;i col[i]=1; } row=newint[cityNum]; for(inti=0;i 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 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); System.out.println("总距离为: "+s); } publicintselectmin(int[]p){ intj=0,m=p[0],k=0; //寻找第一个可用节点,注意最后一次寻找,没有可用节点 while(col[j]==0){ j++; //System.out.print(j+""); if(j>=cityNum){ //没有可用节点,说明已结束,最后一次为*-->0 m=p[0]; break; //或者直接return0; } else{ m=p[j]; } } //从可用节点J开始往后扫描,找出距离最小节点 for(;j if(col[j]==1){ if(m>=p[j]){ m=p[j]; k=j; } } } returnk; } publicvoidprintinit(){ System.out.println("printbegin...."); for(inti=0;i for(intj=0;j System.out.print(distance[i][j]+""); } System.out.println(); } System.out.println("printend...."); } publicstaticvoidmain(String[]args)throwsIOException{ System.out.println("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-->0 总距离为: 12842 五、总结 单从求解结果来看,我个人其实还是能接受这个解,但仔细想想,实际上这个求解结果有太多运气成分在里面,贪心算法毕竟是贪心算法,只能缓一时,而不是长久之计,问题的模型、参数对贪心算法求解结果具有决定性作用,这在某种程度上是不能接受的,于是聪明的人类就发明了各种智能算法(也叫启发式算法),但在我看来所谓的智能算法本质上就是贪心算法和随机化算法结合,例如传统遗传算法用的选择策略就是典型的贪心选择,正是这些贪心算法和随机算法的结合,我们才看到今天各种各样的智能算法。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 精选 数据结构 TSP 贪心 算法