回溯法实验报告.docx
- 文档编号:27139596
- 上传时间:2023-06-27
- 格式:DOCX
- 页数:15
- 大小:19.81KB
回溯法实验报告.docx
《回溯法实验报告.docx》由会员分享,可在线阅读,更多相关《回溯法实验报告.docx(15页珍藏版)》请在冰豆网上搜索。
回溯法实验报告
实验04回溯法
班级:
0920561姓名:
宋建俭学号:
20
一、实验目的
1.掌握回溯法的基本思想。
2.掌握回溯法中问题的解空间、解向量、显式约束条件、隐式约束条件以及子集树与排列树的递归算法结构等内容。
3.掌握回溯法求解具体问题的方法。
二、实验要求
1.认真阅读算法设计教材,了解回溯法思想及方法;
2.设计用回溯算法求解装载问题、n后问题、图的m着色问题的java程序
三、实验内容
1.有一批共n个集装箱要装上2艘载重量分别为C1和C2的轮船,其中集装箱i的重量为wi,且∑wi≤C1+C2。
装载问题要求确定是否有一个合理的装载方案可将这个集装箱装上这2艘轮船。
如果有,找出一种装载方案。
2.在n×n格的棋盘上放置彼此不受攻击的n个皇后。
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n后问题等价于在n×n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。
3.给定无向连通图G和m种不同的颜色。
用这些颜色为图G的各顶点着色,每个顶点着一种颜色。
是否有一种着色法使G中每条边的2个顶点着不同颜色。
这个问题是图的m可着色判定问题。
四、算法原理
1、装载问题
用回溯法解装载问题时,用子集树表示其解空间是最合适的。
可行性约束可剪去不满足约束条件(w1x1+w2x2+…+wnxn)<=c1的子树。
在子集树的第j+1层结点Z处,用cw记当前的装载重量,即cw=(w1x1+w2x2+…+wjxj),当cw>c1时,以结点Z为根的子树中所有结点都不满足约束条件,因而该子树中的解均为不可行解,故可将该子树剪去。
解装载问题的回溯法中,方法maxLoading返回不超过c的最大子集和,但未给出达到这个最大子集和的相应子集。
算法maxLoading调用递归方法backtrack
(1)实现回溯搜索。
Backtrack(i)搜索子集树中第i层子树。
类Loading的数据成员记录子集树结点信息,以减少传给backtrack的参数。
cw记录当前结点相应的装载重量,bestw记录当前最大装载重量。
在算法backtrack中,当i>n时,算法搜索至叶结点,其相应的装载重量cw。
如果cw>bestw,则表示当前解优于当前最优解,此时应更新bestw。
当i<=n时,当前扩展结点Z是子集树的内部结点。
该结点有x[i]=1和x[i]=0两个儿子结点。
其左儿子结点表示x[i]=1的情形,仅当cw+w[i]<=c时进入左子树,对左子树递归搜索。
其右儿子结点表示x[i]=0的情形。
由于可行结点的右儿子结点总是可行的,故进入右子树时不需检查可行性。
算法backtrack动态地生成问题的解空间树。
在每个结点处算法花费O
(1)时间。
子集树中结点个数为O(2的n次方),故backtrack所需的计算时间为O(2的n次方)。
另外backtrack还需要额外的O(n)递归栈空间。
2、n后问题
用n元祖x[1:
n]表示n后问题的解。
其中x[i]表示皇后i放在棋盘的第i行的第x[i]列。
由于不允许将2个皇后放在同一列,所以解向量中的x[i]互不相同。
2个皇后不能放在同一斜线上是问题的隐约束。
对于一般的n后问题,这一隐约束条件可以化成显约束的形式。
将n×n格棋盘看作二维方阵,其行号从上到下,列号从左到右依次编号为1,2,…,n。
从棋盘左上角到右下角的主对角线及其平行线(即斜率为-1的各斜线)上,2个下标值的差(行号-列号)值相等。
同理,斜率为+1的每一条斜线上,2个下标值的和(行号+列号)值相等。
因此,若2个皇后放置的位置分别是(i,j)和(k,l),且i-j=k-l或i+j=k+l,则说明这2个皇后处于同一斜线上。
以上2个方程分别等价于i-k=j-l和i-k=l-j。
由此可知,只要|i-k|=|j-l|成立,就表明2个皇后位于同一条斜线上。
问题的隐约束化成了显约束。
用回溯法解n后问题时,用完全n叉树表示解空间。
可行性约束place剪去不满足行、列和斜线约束的子树。
解n后问题的回溯法中,递归方法backtrack
(1)实现对整个解空间的回溯搜索。
Backtrack(i)搜索解空间中第i层子树。
类Queen的数据成员记录解空间中节点信息,以减少传给backtrack的参数。
Sum记录当前已找到的可行方案数。
在算法backtrack中,当i>n时,算法搜索至叶节点,得到一个新的n皇后互不攻击方案,当前已找到的可行方案数sum曾1.
当i<=n时,当前扩展节点Z是解空间中的内部结点。
该结点有x[i]=1,2,…,n,共n个儿子结点。
对当前扩展结点Z的每一个儿子结点,由place检查其可行性,并以深度优先的方式递归地对可行子树搜索,或剪去不可行子树。
3、图的m着色问题
给定图G=(V,E)和m种颜色,用图的邻接矩阵a表示无向连接图G=(V,E)。
若(i,j)属于图G=(V,E)的边集E,则a[i][j]=0。
整数1,2,…,m用来表示m种不同颜色。
顶点i所着颜色用x[i]表示。
数组x[1:
n]是问题的解向量。
问题的解空间可表示为一棵高度为n+1的完全m叉树。
解空间树的第i(1<=i<=n)层中每一结点都有m个儿子,每个儿子相应于x[i]的m个可能的着色之一。
第n+1层结点均为叶节点。
在解图的m着色问题的回溯法中,backtrack(i)搜索解空间中第i层子树。
类Coloring的数据成员记录解空间中结点信息,以减少传给backtrack的参数。
Sum记录当前找到的m可着色方案数。
在算法backtrack中,当i>n时,算法搜索至叶结点,得到新的m着色方案,当前找到的m可着色方案数sum增1。
当i<=n时,当前扩展结点Z是解空间中的内部结点。
该结点有x[i]=1,2,…,m共m个儿子结点。
对当前扩展结点Z的每一个儿子结点,由方案ok检查其可行性,并以深度优先的方式递归地对可行子树搜索,或剪去不可行子树。
五、实验程序功能模块
1、装载问题
import;
publicclassMainLoading{
publicstaticvoidmain(String[]args)throwsIOException{
Loadingloading=newLoading();
intn=4;
"集装箱个数:
"+n);
int[]x=newint[n+1];
String[]b=newString[n];
Stringa="30502070";
"集装箱重量:
"+a);
int[]w=newint[n+1];
w[1]=30;
w[2]=50;
w[3]=20;
w[4]=70;
intc1=130;
intc2=70;
"轮船载重量:
"+c1+","+c2);
intresult=loading.maxloading(w,c1,x);
intmax,temp;
for(inti=1;i<3;i++){
for(intj=2;j<3;j++){
if(w[i]>w[j]){
temp=w[i];
w[i]=w[j];
w[j]=temp;
}
}
}
if((w[3]>c1)&&(w[3]>c2)){
"都不可装");
}
else{
"轮船1装载的集装箱:
");
for(intu=1;u if(loading.bestx[u]==1) +""); if(loading.r>(result+c2)) "轮船1可装: "+result+""+"轮船2装不完."); else{ "轮船2装载的集装箱: "); for(intu=1;u if(loading.bestx[u]==0) +""); "最优装载--轮船1: "+result+""+"轮船2: "+(loading.r-result)); } } } } publicclassLoading{ staticintn; staticint[]w; staticintc1,c2;//第一、二艘轮船的载重量 staticintcw; staticintbestw; staticintr; staticint[]x; staticint[]bestx; publicstaticintmaxloading(int[]ww,intcc,int[]xx){ n=ww.length-1; w=ww; c1=cc; bestw=0; cw=0; x=newint[n+1]; bestx=xx; r=0; for(inti=1;i<=n;i++) r+=w[i]; backtrack (1); returnbestw; } privatestaticvoidbacktrack(inti){ if(i>n){ if(cw>bestw){ for(intj=1;j<=n;j++) bestx[j]=x[j]; bestw=cw; } return; } r-=w[i]; if(cw+w[i]<=c1){ x[i]=1; cw+=w[i]; backtrack(i+1); cw-=w[i]; } if(cw+r>bestw){ x[i]=0; backtrack(i+1); } r+=w[i]; } } 2、n后问题 import; publicclassMainNQueen{ publicstaticvoidmain(String[]args){ nQueennqueen=newnQueen(); intnn;//输入n值 intsum;//可行方案个数 try{ nn=4;//将输入值转换为int保存 if(nn<=0){ thrownewIOException("不能输入负数"); } "方格数是: "+nn); sum=nqueen.nQueen(nn);//调用nqueen方法 "可行方案个数为: "+sum);//输出sum }catch(IOExceptione){ ; }catch(NumberFormatExceptione){ "请输入数字。 。 。 "); } } } publicclassnQueen{ staticintn;//皇后个数 staticint[]x;//当前解 staticintsum;//当前已找到的可行方案个数 staticintnQueen(intnn){ n=nn;//把输入给全局变量n sum=0;//初始化totle x=newint[n+1]; for(inti=0;i<=n;i++) x[i]=0;//初始化x backtrack();//调用回溯算法 returnsum; } privatestaticvoidbacktrack(){ x[1]=0; intk=1; while(k>0){ x[k]+=1;//第k列皇后向下移一行 while((x[k]<=n)&&! (place(k))){//如果当前第k列皇后未出界或者和其他皇后冲突 x[k]+=1;//第k列皇后向下移一行继续寻找 } if(x[k]<=n)//找到一个值并且未出界 if(k==n){//已是最后一列说明已找到一个方案 sum++; } else{//不是最后一列故寻找下一列 k++; x[k]=0; } else//找到的值已经出界,回退到上一列 k--; } } //判断皇后是否冲突 privatestaticbooleanplace(intk){ for(intj=1;j if((Math.abs(k-j)==Math.abs(x[j]-x[k]))||(x[j]==x[k])) returnfalse; returntrue; } } 3、图的m着色问题 import; publicclassMainGraph_m_Color{ publicstaticvoidmain(String[]args){ Coloringc=newColoring(); intn=4; "图的顶点数: "+n); intm=3; "颜色数: "+m); booleang[][]=newboolean[n+1][n+1]; g[1][2]=true; g[2][1]=true; g[1][3]=true; g[3][1]=true; g[2][3]=true; g[3][2]=true; g[2][4]=true; g[4][2]=true; g[3][4]=true; g[4][3]=true; c.mColoring(m,n,g); } } publicclassColoring{ staticintn,m; staticboolean[][]a; staticint[]x; staticlongsum; publicstaticlongmColoring(intmm,intnn,boolean[][]g){ m=mm; n=nn; a=g; x=newint[n+1]; sum=0; backtrack (1); returnsum; } privatestaticvoidbacktrack(intt){ if(t>n){ "解决方案: "); sum++; for(inti=1;i<=n;i++) "顶点"+i+"用颜色"+x[i]+""); ; } else for(inti=1;i<=m;i++){ x[t]=i; if(ok(t)) backtrack(t+1); x[t]=0; } } privatestaticbooleanok(intk){ for(intj=1;j<=n;j++) if(a[k][j]&&(x[j]==x[k])) returnfalse; returntrue; } } 七、测试数据 1、装载问题 intn=4; "集装箱个数: "+n); int[]x=newint[n+1]; String[]b=newString[n]; Stringa="30502070"; "集装箱重量: "+a); int[]w=newint[n+1]; w[1]=30; w[2]=50; w[3]=20; w[4]=70; intc1=130; intc2=70; "轮船载重量: "+c1+","+c2); 2、n后问题 nn=4; 3、图的m着色问题 intn=4; "图的顶点数: "+n); intm=3; "颜色数: "+m); booleang[][]=newboolean[n+1][n+1]; g[1][2]=true; g[2][1]=true; g[1][3]=true; g[3][1]=true; g[2][3]=true; g[3][2]=true; g[2][4]=true; g[4][2]=true; g[3][4]=true; g[4][3]=true; 测试结果 装载问题 集装箱个数: 4 集装箱重量: 30502070 轮船载重量: 130,70 轮船1装载的集装箱: 1 3 4 轮船2装载的集装箱: 2 最优装载--轮船1: 120轮船2: 50 n后问题 方格数是: 4可行方案个数为: 2 图的m着色问题 图的顶点数: 4 颜色数: 3 解决方案: 顶点1用颜色1 顶点2用颜色2 顶点3用颜色3 顶点4用颜色1 解决方案: 顶点1用颜色1 顶点2用颜色3 顶点3用颜色2 顶点4用颜色1 解决方案: 顶点1用颜色2 顶点2用颜色1 顶点3用颜色3 顶点4用颜色2 解决方案: 顶点1用颜色2 顶点2用颜色3 顶点3用颜色1 顶点4用颜色2 解决方案: 顶点1用颜色3 顶点2用颜色1 顶点3用颜色2 顶点4用颜色3 解决方案: 顶点1用颜色3 顶点2用颜色2 顶点3用颜色1 顶点4用颜色3
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 回溯 实验 报告