回溯与分支限界算法设计说明Word文档格式.docx
《回溯与分支限界算法设计说明Word文档格式.docx》由会员分享,可在线阅读,更多相关《回溯与分支限界算法设计说明Word文档格式.docx(16页珍藏版)》请在冰豆网上搜索。
先进先出队列式分支限界法
输入数据,将计算出的最少变换次数和相应的变换序列输出。
第1行是最少变换次数。
从第2行开始,每行用4个数表示一次变换。
程序及运行结果
1.骑士游历问题的程序:
package.t5;
importjava.util.Scanner;
publicclassQishi{
privatebooleanTravel(intfirstX,intfirstY,int[][]board){
//对应骑士可走的8个方向
int[]movex={-2,-1,1,2,2,1,-1,-2};
int[]movey={1,2,2,1,-1,-2,-2,-1};
//下一步出路的位置
int[]nextStepX=newint[board.length];
int[]nextStepY=newint[board.length];
//记录出路的个数
int[]exitS=newint[board.length];
intnextX=firstX;
intnextY=firstY;
board[nextX][nextY]=1;
for(intm=2;
m<
=Math.pow(board.length,2);
m++){
//初始化下一个位置可走的位置的数目
for(inti=0;
i<
board.length;
i++){
exitS[i]=0;
}
intcount=0;
//试探8个方向
8;
inttemI=nextX+movex[i];
inttemJ=nextY+movey[i];
//走到边界,路断
if(temI<
0||temI>
7||temJ<
0||temJ>
7){
continue;
//记录下可走的方向
if(0==board[temI][temJ]){
nextStepX[count]=temI;
nextStepY[count]=temJ;
count++;
//到这里,cout表示当前点有几种走法。
nextStep中存储各种走法的坐标。
intmin=-1;
if(count==0){
returnfalse;
if(1==count){
min=0;
}else{
count;
for(intj=0;
j<
j++)
{
inttemI=nextStepX[i]+movex[j];
inttemJ=nextStepY[i]+movey[j];
if(temI<
//记录下这个位置可走的方向数
exitS[i]++;
inttem=exitS[0];
//从可走的方向中,寻找最少走的出路
for(inti=1;
if(tem>
exitS[i]){
tem=exitS[i];
min=i;
//得到最少的出路
nextX=nextStepX[min];
nextY=nextStepY[min];
board[nextX][nextY]=m;
returntrue;
publicstaticvoidmain(String[]args){
intfirstX,firstY;
System.out.println("
输入起始点(0-7):
"
);
Scannerscanner=newScanner(System.in);
firstX=scanner.nextInt();
firstY=scanner.nextInt();
int[][]board=newint[8][8];
Qishiknight=newQishi();
if(knight.Travel(firstX,firstY,board)){
游历完成:
}else{
游历失败!
\n"
board[0].length;
j++){
if(board[i][j]<
10){
System.out.print("
"
+board[i][j]);
System.out.print(board[i][j]);
System.out.println();
实例:
2.行列变换问题的程序:
package.t8;
importjava.util.LinkedList;
classgraph{
staticintsour,dest;
//sour是图形的初始整数,dest是图形的目的整数
staticintans[]=newint[1<
<
16];
//静态变量(即全局变量),用于存放图形变换的路径
intm=4,n=4,x;
introw[]=newint[4];
intcol[]=newint[4];
voidsetx(intx){
this.x=x;
}
intgetx(){
returnthis.x;
voidrowx(){//将一个整数划分成四行二进制
inty;
for(inti=0;
i<
m;
i++){
y=1;
row[i]=0;
for(intj=0;
j<
n;
j++){
if((x&
1)!
=0)//如果x的最低位是1
row[i]|=y;
y<
=1;
x>
>
}
}
voidcolx(){//将一个整数划分成四列二进制
for(intj=0;
j++)col[j]=0;
y=1;
col[j]|=y;
y<
voidrowy(){//将四行二进制转换成一个整数
intz=1,x=0,y;
y=row[i];
if((y&
=0)//如果y的最低位是1
x|=z;
z<
y>
voidcoly(){//将四列二进制转换成一个整数
if((col[j]&
col[j]>
voidSwaprow(inti,intj){//将二进数进行行互换
into;
o=row[i];
row[i]=row[j];
row[j]=o;
voidSwapcol(inti,intj){//将二进数进行列互换
o=col[i];
col[i]=col[j];
col[j]=o;
voidreveR(intk){//将二进数进行行颠倒
inty=0,z=1<
(4-1);
4;
if((row[k]&
y|=z;
z>
row[k]>
row[k]=y;
voidreveC(intk){//将二进数进行列颠倒
if((col[k]&
col[k]>
col[k]=y;
introwswap(intx,inti,intj){//将二进制数的第i行与第j行互换
rowx();
Swaprow(i,j);
rowy();
intcolswap(intx,inti,intj){//将二进制数的第i列与第j列互换
colx();
Swapcol(i,j);
coly();
intrevrow(intx,intk){//将二进制数的第K行颠倒
reveR(k);
intrevcol(intx,intk){//将二进制数的第K列颠倒
reveC(k);
}
publicclassTuxing{
publicstaticvoidmain(String[]args){
finalintMaxsize=1<
16;
graphgN;
//用于进行行变换、列变换、行颠倒、列颠倒
intE,N;
//变换前的初始值,变换前的结果值
gN=newgraph();
inthash[]=newint[1<
inti,j,h=0;
charc;
graphG1=newgraph();
//初始化,输入初始值和目标值,即01010和00101
Scannerscanner=newScanner(System.in);
Stringss=scanner.nextLine();
char[]chArrs=ss.toCharArray();
for(graph.sour=i=0;
c=chArrs[i];
graph.sour|=(int)(c-'
0'
)<
i;
Stringsd=scanner.nextLine();
char[]chArrd=sd.toCharArray();
for(graph.dest=i=0;
c=chArrd[i];
graph.dest|=(int)(c-'
LinkedListqueue=newLinkedList();
//初始化先进先出队列
for(intk=0;
k<
Maxsize;
k++)hash[k]=-1;
G1.x=graph.sour;
hash[G1.x]=0;
queue.add(G1.x);
while(!
queue.isEmpty()){//以先进先出队列式实现分支限界法
E=(int)queue.removeFirst();
for(i=0;
4-1;
i++){//行变换
for(j=i+1;
gN.x=gN.rowswap(E,i,j);
N=gN.x;
if(hash[N]==-1){
hash[N]=hash[E]+1;
graph.ans[N]=E;
queue.add(N);
}
}
}
i++){//列变换
gN.x=gN.colswap(E,i,j);
i++){//行颠倒
gN.x=gN.revrow(E,i);
i++){//列颠倒
gN.x=gN.revcol(E,i);
N=gN.x;
if(hash[N]==-1){
hash[N]=hash[E]+1;
graph.ans[N]=E;
queue.add(N);
}
if(hash[graph.dest]!
=-1){//如果目的值被遍历到,则退出循环
System.out.println("
OK"
break;
System.out.println(hash[graph.dest]);
output(graph.dest);
//输出变换的路径
publicstaticvoidoutb(intx){//将一个整数以四行二进制的形式显示
i<
=0)System.out.print
(1);
elseSystem.out.print(0);
x/=2;
System.out.println();
publicstaticvoidoutput(intN){
if(N==graph.sour){
outb(N);
return;
output(graph.ans[N]);
//graph.ans[N]存放着从初始值到目的值的遍历路径
System.out.println();
outb(N);
总结
实验心得体会:
掌握回溯法解决问题的一般步骤。
学会使用回溯法解决实际问题。
掌握分支限界法解决问题的基本思想。
学会使用分支限界法解决实际问题
改进意见:
对于分支限界法了解的不透彻,应与老师沟通解决此问题,回溯法可以帮我们更好的解决一些多解的复杂性问题,所以,要更好的去学习和运用回溯法思想。
实验成绩:
指导教师:
年月日