动态规划法回溯法分支限界法求解TSP问题实验报告doc.docx

上传人:b****6 文档编号:7136025 上传时间:2023-01-21 格式:DOCX 页数:26 大小:18.73KB
下载 相关 举报
动态规划法回溯法分支限界法求解TSP问题实验报告doc.docx_第1页
第1页 / 共26页
动态规划法回溯法分支限界法求解TSP问题实验报告doc.docx_第2页
第2页 / 共26页
动态规划法回溯法分支限界法求解TSP问题实验报告doc.docx_第3页
第3页 / 共26页
动态规划法回溯法分支限界法求解TSP问题实验报告doc.docx_第4页
第4页 / 共26页
动态规划法回溯法分支限界法求解TSP问题实验报告doc.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

动态规划法回溯法分支限界法求解TSP问题实验报告doc.docx

《动态规划法回溯法分支限界法求解TSP问题实验报告doc.docx》由会员分享,可在线阅读,更多相关《动态规划法回溯法分支限界法求解TSP问题实验报告doc.docx(26页珍藏版)》请在冰豆网上搜索。

动态规划法回溯法分支限界法求解TSP问题实验报告doc.docx

动态规划法回溯法分支限界法求解TSP问题实验报告doc

 

TSP问题算法实验报告

 

指导教师:

季晓慧

 

姓名:

辛瑞乾

 

学号:

 

提交日期:

2015年11月

 

总述......................................................................

动态规划法................................................................

算法问题分析............................................................

算法设计................................................................

实现代码................................................................

输入输出截图............................................................

OJ提交截图..............................................................

算法优化分析............................................................

回溯法....................................................................

算法问题分析............................................................

算法设计................................................................

实现代码................................................................

输入输出截图............................................................

OJ提交截图..............................................................

算法优化分析............................................................

分支限界法................................................................

算法问题分析............................................................

 

算法设计................................................................

实现代码................................................................

输入输出截图............................................................

OJ提交截图..............................................................

算法优化分析............................................................

总结......................................................................

 

总述

 

TSP问题又称为旅行商问题,是指一个旅行商要历经所有城市一次最后又

 

回到原来的城市,求最短路程或最小花费,解决TSP可以用好多算法,比如

 

蛮力法,动态规划法⋯具体的时间复杂的也各有差异,本次实验报告包含动

 

态规划法,回溯法以及分支限界法。

 

动态规划法

 

算法问题分析

 

假设n个顶点分别用0~n-1的数字编号,顶点之间的代价存放在数组

 

mp[n][n]中,下面考虑从顶点0出发求解TSP问题的填表形式。

首先,按个

 

数为1、2、⋯、n-1的顺序生成1~n-1个元素的子集存放在数组x[2^n-1]

中,例如当n=4时,

 

x[1]={1},x[2]={2},x[3]={3},x[4]={1,2},x[5]={1,3},x[6]={2,3},x[7]=

 

{1,2,3}

设数组

dp[n][2^n-1]

存放迭代结果,其中

dp[i][j]

表示从顶点

i

 

经过子集

x[j]

中的顶点一次且一次,最后回到出发点

0的最短路径长度,动

 

态规划法求解

TSP问题的算法如下。

 

算法设计

 

输入:

图的代价矩阵mp[n][n]

 

输出:

从顶点0出发经过所有顶点一次且仅一次再回到顶点0的最短路径长

 

 

1.初始化第0列(动态规划的边界问题)for(i=1;i

 

dp[i][0]=mp[i][0]

 

2.依次处理每个子集数组x[2^n-1]

 

for(i=1;i

 

if(子集x[j]中不包含i)

 

对x[j]中的每个元素k,计算d[i][j]=min{mp[i][k]+dp[k][j-1]};

 

2.输出最短路径长度。

 

实现代码

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#definedebug"outputfordebug\n"

 

#definepi(acos)

 

#defineeps(1e-8)

 

#defineinf0x3f3f3f3f

 

#definelllonglongint

 

#definelsonl,m,rt<<1

 

#definersonm+1,r,rt<<1|1

 

usingnamespacestd;

 

constintMax=100005;

 

intn,mp[20][20],dp[20][40000];

 

intmain()

 

{

 

while(~scanf("%d",&n))

 

{

 

intans=inf;

 

memset(mp,0,sizeofmp);

 

for(inti=0;i

 

{

 

for(intj=0;j

 

{

 

if(i==j)

 

{

 

mp[i][j]=inf;

 

continue;

 

}

 

inttmp;

 

scanf("%d",&tmp);

 

mp[i][j]=tmp;

 

}

 

}

 

intmx=(1<<(n-1));

 

dp[0][0]=0;

 

for(inti=1;i

 

{

 

dp[i][0]=mp[i][0];

 

}

 

dp[0][mx-1]=inf;

 

for(intj=1;j<(mx-1);j++)

 

{

 

for(inti=1;i

 

{

 

if((j&(1<<(i-1)))==0)

 

{

 

intx,y=inf;

 

for(intk=1;k

 

{

 

if((j&(1<<(k-1)))>0){

 

x=dp[k][(j-(1<<(k-1)))]+mp[i][k];

 

y=min(y,x);

 

}

 

}

 

dp[i][j]=y;

 

}

 

}

 

}

 

dp[0][mx-1]=inf;

 

for(inti=1;i

 

dp[0][mx-1]=min(dp[0][mx-1],mp[0][i]+dp[i][(mx-1)-(1<<(i-1))]);printf("%d\n",dp[0][mx-1]);

}

 

return0;

 

}

 

输入输出截图

 

OJ提交截图

 

算法优化分析

 

该算法需要对顶点集合{1,2,⋯,n-1}的每一个子集进行操作,因此时

 

间复杂度为O(2^n)。

和蛮力法相比,动态规划法求解TSP问题,把原来的时

 

间复杂度是O(n!

)的排列问题,转化为组合问题,从而降低了算法的时间复

 

杂度,但仍需要指数时间。

 

回溯法

 

算法问题分析

 

回溯法求解TSP问题,首先把所有的顶点的访问标志初始化为0,然后在解空间树中从根节点出发开始搜索,如果从根节点到当前结点对应一个部分解,即满足上述约束条件,则在当前结点处选择第一棵子树继续搜索,否则,对当前子树的兄弟结点进行搜索,如果当前结点的所有子树都已尝试过并且发生冲突,则回溯到当前结点的父节点。

采用邻接矩阵mp[n][n]存储顶点之

 

间边的情况,为避免在函数间传递参数,将数组mp设置为全局变量,设数组x[n]表示哈密顿回路经过的顶点。

 

算法设计

 

输入:

无向图G=(V,E)

 

输出:

哈密顿回路

 

1、将顶点数组x[n]初始化为0,标志数组vis[n]初始化为0;

 

2、从顶点0出发构造哈密顿回路:

vis[0]=1;x[0]=1;k=1;

 

3、While(k>=1)

 

、x[k]=x[k]+1,搜索下一个顶点。

 

、若n个顶点没有被穷举完,则执行下列操作

 

∈E,转步骤;

 

、若数组x[n]已经形成哈密顿路径,则输出数组x[n],算法结束;、若数组x[n]构成哈密顿路径的部分解,则k=k+1,转步骤3;

 

、否则,取消顶点x[k]的访问标志,重置x[k],k=k-1,转步骤3。

 

实现代码

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#include

 

#definedebug"outputfordebug\n"

 

#definepi(acos)

 

#defineeps(1e-8)

 

#defineinf0x3f3f3f3f

 

#definelllonglongint

 

#definelsonl,m,rt<<1

 

#definersonm+1,r,rt<<1|1

 

usingnamespacestd;

 

intmp[20][20];

 

intx[30],vis[30];

 

intn,k,cur,ans;

 

voidinit()

 

{

 

for(inti=0;i

 

for(intj=0;j

 

mp[i][j]=-1;

 

ans=-1;cur=0;

 

for(inti=1;i<=n;i++)x[i]=i;

 

}

 

voiddfs(intt)

 

{

 

if(t==n)

 

{

 

if(mp[x[n-1]][x[n]]!

=-1&&(mp[x[n]][1]!

=-1)&&(cur+mp[x[n-1]][x[n]]+mp[x[n]][1]

{

 

for(inti=1;i<=n;i++)

 

vis[i]=x[i];

 

ans=cur+mp[x[n-1]][x[n]]+mp[x[n]][1];

 

}

 

}

 

else

 

{

 

for(inti=t;i<=n;i++)

 

{

 

if(mp[x[t-1]][x[i]]!

=-1&&(cur+mp[x[t-1]][x[i]]

 

{

 

swap(x[t],x[i]);

 

cur+=mp[x[t-1]][x[t]];

 

dfs(t+1);

 

cur-=mp[x[t-1]][x[t]];

 

swap(x[t],x[i]);

 

}

 

}

 

}

 

}

 

intmain()

 

{

 

while(~scanf("%d",&n))

 

{

 

init();

 

for(inti=1;i<=n;i++)

 

{

 

for(intj=1;j<=n;j++)

 

{

 

if(i==j)

 

continue;

 

scanf("%d",&mp[i][j]);

 

}

 

}

 

egin();

 

sum+=*it;

 

it++;

 

sum+=*it;

 

}

 

returnsum/2;

 

}

 

intgao(nodes)

 

{

 

intres=*2;

 

intt1=inf,t2=inf;

 

for(inti=1;i<=n;i++)

 

{

 

if(!

[i])

 

{

 

t1=min(t1,mp[i][]);

 

t2=min(t2,mp[][i]);

 

}

 

}

 

res+=t1;

 

res+=t2;

 

inttmp;

 

for(inti=1;i<=n;i++)

 

{

 

tmp=inf;

 

if(!

[i])

 

{

 

it=Mp[i].begin();

 

res+=*it;

 

for(intj=1;j<=n;j++)

 

tmp=min(tmp,mp[j][i]);

 

res+=tmp;

 

}

 

}

 

return!

(res%2)?

(res/2):

(res/2+1);

 

}

 

voidbfs(nodes)

 

{

 

(s);

 

while(!

())

 

{

 

nodehead=();

 

();

 

if==n-1)

 

{

 

intp;

 

for(inti=1;i<=n;i++)

 

{

 

if(!

[i])

 

{

 

p=i;

 

break;

 

}

 

}

 

intcnt=+mp[p][]+mp[][p];

 

nodetmp=();

 

if(cnt<=

 

{

 

ans=min(ans,cnt);

 

return;

 

}

 

else

 

{

 

up=min(up,cnt);

 

ans=min(ans,cnt);

 

continue;

 

}

 

}

 

nodetmp;

 

for(inti=1;i<=n;i++)

 

{

 

if(!

[i])

 

{

 

=;

 

=+mp[][i];

 

=i;

 

=+1;

 

for(intj=1;j<=n;j++)[j]=[j];

 

[i]=1;

 

=gao(tmp);

 

if<=up)

 

(tmp);

 

}

 

}

 

}

 

}

 

intmain()

 

{

 

while(~scanf("%d",&n))

 

{

 

for(inti=0;i<=n;i++)

 

Mp[i].clear();

 

for(inti=1;i<=n;i++)

 

{

 

for(intj=1;j<=n;j++)

 

{

 

if(i!

=j)

 

{

 

scanf("%d",&mp[i][j]);

 

Mp[i].push_back(mp[i][j]);

 

}

 

else

 

mp[i][j]=inf;

 

}

 

sort(Mp[i].begin(),Mp[i].end());

 

}

 

memset(vis,0,sizeofvis);

 

vis[1]=1;

 

up=0;

 

up+=getup(1,1,up);

 

low=getlow();

 

nodefir;

 

=1;

 

=1;

 

=1;

 

for(inti=1;i<=n;i++)[i]=0;

 

[1]=1;

 

=0;

 

=low;

 

ans=inf;

 

bfs(fir);

 

printf("%d\n",ans);

 

}

 

return0;

 

}

 

输入输出截图

 

OJ提交截图

 

算法优化分析

 

分支限界法的复杂度是根据数据的不同而不同,搜索的节点越少,复杂

 

度越低,跟目标函数的选择有很大关系。

目标函数值的计算也会需要一定时

 

间,比如此文章中的目标函数值求解的复杂度是O(n^2)。

当然此算法仍然

 

有可以优化的地方,比如在记录该路径每个叶子结点的孩子结点时可以采用

 

二进制的思想,从而使算法的时间复杂度在下降到当前T/n的数量级,解决

 

COJ1814问题应该不成问题。

 

总结

 

TSP问题在很多地方都可以运用到,并且好多问题都是由TSP问题延伸和

 

发展的,也可以称之为TSP问题,不过其思路大致相似,于是我们可以运用

 

已学过的算法对其进行解决。

我在学习算法课以前的TSP问题大都用动态规

 

划以及回溯法,究其时间复杂度以及代码的复杂度比较低,思路比较清晰,

 

在解决此类延伸问题时容易调试和修改。

学完算法后最有感触的一点就是,

 

算法的精髓并不在于其方式方法,而在于其思想思路。

有了算法的思想,那

 

么潜移默化中问题就可以得到解决。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 院校资料

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1