1、mpnn 中,下面考虑从顶点 0 出发求解 TSP问题的填表形式。首先,按个数为 1、2、 n-1 的顺序生成 1n-1 个元素的子集存放在数组 x2n-1中 , 例 如 当 n=4 时 ,x1=1,x2=2,x3=3,x4=1,2,x5=1,3,x6=2,3,x7=1,2,3。设数组dpn2n-1存放迭代结果,其中dpij表示从顶点i经过子集xj中的顶点一次且一次, 最后回到出发点0 的最短路径长度, 动态规划法求解TSP问题的算法如下。算法设计输入:图的代价矩阵 mpnn输出:从顶点 0 出发经过所有顶点一次且仅一次再回到顶点 0 的最短路径长度1.初始化第 0 列(动态规划的边界问题)
2、for(i=1;in;i+)dpi0=mpi02.依次处理每个子集数组 x2n-1for(i=1;if (子集 xj 中不包含 i )对xj 中的每个元素 k,计算 dij=minmpik+dpkj-1;2.输出最短路径长度。实现代码#include cstdlibcstringcmathctimeiostreamalgorithmstringvectordequelistsetmapstackqueuecctypenumericiomanipbitsetsstreamfstream#define debug output for debugn#define pi (acos)#define
3、eps (1e-8)#define inf 0x3f3f3f3f#define ll long long int#define lson l , m , rt 1#define rson m + 1 , r , rt 1 | 1using namespace std;const int Max = 100005;int n,mp2020,dp2040000;int main()while(scanf(%d,&n)int ans=inf;memset(mp,0,sizeof mp);for(int i=0; i i+)for(int j=0; j j+)if(i=j)mpij=inf;conti
4、nue;int tmp;scanf(tmp);mpij=tmp;int mx=(1(n-1);dp00=0;for(int i=1;dpi0=mpi0;dp0mx-1=inf;for(int j=1;(mx-1);if(j&(1(i-1)=0)int x,y=inf;for(int k=1; k0)x=dpk(j-(1(k-1)+mpik;y=min(y,x);dpij=y;dp0mx-1=min(dp0mx-1,mp0i+dpi(mx-1)-(1=1)、xk=xk+1 ,搜索下一个顶点。、若 n 个顶点没有被穷举完,则执行下列操作E,转步骤;、若数组 xn 已经形成哈密顿路径,则输出数组 x
5、n ,算法结束;、若数组 xn 构成哈密顿路径的部分解,则 k=k+1,转步骤 3;、否则,取消顶点 xk 的访问标志,重置 xk,k=k-1 ,转步骤 3。int mp2020;int x30,vis30;int n,k,cur,ans;void init()jj+)mpij=-1;ans=-1;cur=0;=n;i+)xi=i;void dfs(int t)if(t=n)if(mpxn-1xn!=-1&(mpxn1!=-1)&(cur+mpxn-1xn +mpxn1ans|ans=-1)visi=xi;ans=cur+mpxn-1xn+mpxn1;elsefor(int i=t;if(mp
6、xt-1xi!(cur+mpxt-1xiswap(xt,xi);cur+=mpxt-1xt;dfs(t+1);cur-=mpxt-1xt;init();mpij);egin();sum+=*it;it+;return sum/2;int gao(node s)int res=*2;int t1=inf,t2=inf;if(!i)t1=min(t1,mpi);t2=min(t2,mpi);res+=t1;res+=t2;tmp=inf;it=Mpi.begin();res+=*it;tmp=min(tmp,mpji);res+=tmp;return !(res%2) ? (res/2):(res
7、/2+1);void bfs(node s)(s);while(!()node head=();();if=n-1)int p;p=i;break;int cnt=+mpp+mpp;node tmp=();if(cnt=ans=min(ans,cnt);return;up=min(up,cnt);node tmp;=;=+mpi;=i;=+1; j+) j=j;i=1;=gao(tmp);if=up)(tmp);Mpi.clear();if(i!=j)Mpi.push_back(mpij);sort(Mpi.begin(),Mpi.end();memset(vis,0,sizeof vis);
8、vis1=1;up=0;up+=getup(1,1,up);low=getlow();node fir;=1; i+) i=0;1=1;=0;=low;ans=inf;bfs(fir);printf(,ans);分支限界法的复杂度是根据数据的不同而不同,搜索的节点越少,复杂度越低,跟目标函数的选择有很大关系。目标函数值的计算也会需要一定时间,比如此文章中的目标函数值求解的复杂度是 O(n2 ) 。当然此算法仍然有可以优化的地方, 比如在记录该路径每个叶子结点的孩子结点时可以采用二进制的思想,从而使算法的时间复杂度在下降到当前 T/n 的数量级,解决COJ1814问题应该不成问题。总结TSP问题在很多地方都可以运用到, 并且好多问题都是由 TSP问题延伸和发展的,也可以称之为 TSP问题,不过其思路大致相似,于是我们可以运用已学过的算法对其进行解决。 我在学习算法课以前的 TSP问题大都用动态规划以及回溯法,究其时间复杂度以及代码的复杂度比较低,思路比较清晰,在解决此类延伸问题时容易调试和修改。学完算法后最有感触的一点就是,算法的精髓并不在于其方式方法,而在于其思想思路。有了算法的思想,那么潜移默化中问题就可以得到解决。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1