算法之分支限界法实现Word文件下载.docx
- 文档编号:21171230
- 上传时间:2023-01-28
- 格式:DOCX
- 页数:20
- 大小:58.69KB
算法之分支限界法实现Word文件下载.docx
《算法之分支限界法实现Word文件下载.docx》由会员分享,可在线阅读,更多相关《算法之分支限界法实现Word文件下载.docx(20页珍藏版)》请在冰豆网上搜索。
j++)
{
if((abs(k-j)==abs(x[j]-x[k]))||(x[j]==x[k]))
returnfalse;
}
returntrue;
}
voidQueen:
Backtrack(intt)
if(t>
n)
sum++;
else
for(inti=1;
i<
=n;
i++)
{
x[t]=i;
if(Place(t))
Backtrack(t+1);
}
intnQueen(intn)
QueenX;
//初始化X
X.n=n;
X.sum=0;
int*p=newint[n+1];
for(inti=0;
p[i]=0;
X.x=p;
X.Backtrack
(1);
delete[]p;
returnX.sum;
intmain()
cout<
<
"
共有"
<
nQueen(8)<
种"
endl;
system("
pause"
);
return0;
截图:
分支限界法:
voidredu(intt);
//剪枝函数
//判断当前状态是否合理,即皇后会不会互相攻击
//所有皇后都不会互相攻击
X.redu
(1);
voidswap(int&
a,int&
b)
intt=a;
a=b;
b=t;
redu(intt)
redu(t+1);
2.单源最短路径问题:
如图求出从源顶点0到其它顶点的最短路径长度,比较贪心算法和分支限界法。
贪心算法(dijk)
#definemaxint10000
//n为节点个数,v为源节点,dist为源节点到其他节点距离数组,
//prev为源节点到顶点i的最短路径上的前一个节点,c为个节点之间的距离数组
voidDijkstra(intn,intv,intdist[],intprev[],int**c)
//顶点集合S
bools[maxint];
for(inti=1;
//源节点到各节点的距离记录
dist[i]=c[v][i];
//S初始化为空
s[i]=false;
if(dist[i]==maxint)//不可达
prev[i]=0;
else
prev[i]=v;
//源节点初始化
dist[v]=0;
s[v]=true;
//核心算法
n;
inttemp=maxint;
intu=v;
for(intj=1;
//寻找距离最小而且不在S中的节点
if(!
s[j]&
&
(dist[j]<
temp))
{
u=j;
temp=dist[j];
}
//把找到的节点加入到S
s[u]=true;
//更新dist数组,通过u节点
intnewdist=dist[u]+c[u][j];
if(newdist<
dist[j])
dist[j]=newdist;
prev[j]=u;
请输入节点个数"
cin>
>
请输入起点(例如1,2,3。
。
)"
intv;
v;
int**c=newint*[n+1];
c[i]=newint[n+1];
请输入各节点之间距离"
cin>
c[i][j];
if(c[i][j]==0)
c[i][j]=maxint;
//测试数据
//for(inti=1;
//for(intj=1;
//c[i][j]=maxint;
//c[1][3]=20;
//c[1][4]=5;
//c[2][3]=30;
//c[2][4]=20;
//c[3][4]=30;
//c[4][5]=10;
intdist[maxint];
intprev[maxint];
Dijkstra(n,v,dist,prev,c);
=5;
if(dist[i]==maxint)
cout<
-->
"
v<
不可达"
dist[i]<
deletec[i];
deletec;
#include<
classMinHeapNode
friendclassGraph;
public:
operatorint()const{returnlength;
inti;
//顶点编号
intlength;
//当前路长
classMinHeap
MinHeap(intmaxheapsize=10);
~MinHeap(){delete[]heap;
MinHeap&
Insert(constMinHeapNode&
x);
DeleteMin(MinHeapNode&
x);
intcs,ms;
MinHeapNode*heap;
MinHeap:
MinHeap(intmaxheapsize)
ms=maxheapsize;
heap=newMinHeapNode[ms+1];
cs=0;
MinHeap&
MinHeap:
Insert(constMinHeapNode&
x)
if(cs==ms)
return*this;
inti=++cs;
while(i!
=1&
x<
heap[i/2])
heap[i]=heap[i/2];
i/=2;
heap[i]=x;
return*this;
DeleteMin(MinHeapNode&
if(cs==0)
x=heap[1];
MinHeapNodey=heap[cs--];
inti=1,ci=2;
while(ci<
=cs)
if(ci<
cs&
heap[ci]>
heap[ci+1])
ci++;
if(y<
=heap[ci])
break;
heap[i]=heap[ci];
i=ci;
ci*=2;
heap[i]=y;
classGraph
friendintmain();
voidShortesPaths(int);
intn,//图G的顶点数
*prev;
//前驱顶点数组
int**c,//图G的领接矩阵
*dist;
//最短距离数组
voidGraph:
ShortesPaths(intv)//单源最短路径问题的优先队列式分支限界法
MinHeapH(1000);
MinHeapNodeE;
//定义源为初始扩展节点
E.i=v;
E.length=0;
while(true)//搜索问题的解空间
if((c[E.i][j]!
=0)&
(E.length+c[E.i][j]<
dist[j])){
//顶点i到顶点j可达,且满足控制约束
dist[j]=E.length+c[E.i][j];
prev[j]=E.i;
//加入活结点优先队列
MinHeapNodeN;
N.i=j;
N.length=dist[j];
H.Insert(N);
try
H.DeleteMin(E);
//取下一扩展结点
catch(int)
break;
if(H.cs==0)//优先队列空
dist[i]=maxint;
GraphG;
G.n=n;
G.c=c;
G.dist=dist;
G.prev=prev;
G.ShortesPaths(v);
endl<
分支限界法"
delete[]c[i];
3.矩阵连乘问题:
A1
A2
A3
A4
30*20
20*15
15*25
25*20
已知A1~A4矩阵及其维数求最优计算顺序。
voidmatrixChain(int*p,int**m,int**s,intlen)
//p用来记录矩阵,m[i][j]表示第i个矩阵到第j个矩阵的最优解,s[][]记录从最优解断开位置,len为矩阵个数
intn=len-1;
i++)//初始化数组
for(intj=1;
j<
=n;
j++)
m[i][j]=0;
for(intr=2;
r<
r++)
=n-r+1;
i++)//行循环
intj=i+r-1;
m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];
//初始化s[i][j]=k;
寻找最优解,以及最优解断开位置
s[i][j]=i;
for(intk=i+1;
k<
j;
k++)
intt=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
if(t<
m[i][j])
{
s[i][j]=k;
//在k位置断开得到最优解
m[i][j]=t;
}
voidtraceback(int**s,inti,intj)
if(i==j)
return;
traceback(s,i,s[i][j]);
traceback(s,s[i][j]+1,j);
MultiplyA"
"
s[i][j]<
andA"
s[i][j]+1<
intp[5]={30,20,15,25,20};
intlen=5;
各矩阵为:
=4;
cout<
'
M'
'
p[i-1]<
*'
p[i]<
;
int**m=newint*[len];
len;
m[i]=newint[len];
int**s=newint*[len];
s[i]=newint[len];
matrixChain(p,m,s,len);
traceback(s,1,4);
最优计算次数为"
m[1][4]<
4.二分搜索问题:
对于给定的有序整数集a={6,9,13,15,25,33,45},编写程序查找18与33,记录每次比较基准数。
voidbinary_search(inta[],intn,intkey)
//a为按降序排列好了的数组,n为数组大小,key为查找的数字
intleft=0;
//数组的首位置
intright=n-1;
//数组的最后一个位置
while(left<
=right)
intmid=left+((right-left)>
1);
//用移位代替除以2可以提高效率
if(a[mid]>
key)
a[mid]<
为基准数"
right=mid-1;
elseif(a[mid]<
left=mid+1;
找到!
!
return;
//未找到
此数不存在!
!
return;
inta[7]={6,9,13,15,25,33,45};
intn=7;
binary_search(a,7,18);
binary_search(a,7,33);
四、实验体会:
n后问题来说,回溯和分支限界法没有什么差别,因为回溯法,基于深度搜索,遍历每一种方案后,寻找一种最佳方法,而这题,是求次数,需要遍历每一种可行的方法。
而分支限界法,因为,最终每一种可行方案都是[1..n]的一个全排列,所以n后问题中,回溯和分支限界,差别不大,基本没有差别。
第二题贪心算法,主要就是借助新加入的节点,作为中间节点,搜索路径,看看有没有能够找到更近到其他未到节点的路径。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 分支 限界 实现