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

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

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

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

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

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

 

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