您的位置:首页 > 理论基础 > 数据结构算法

回溯法解八皇后、幕集输出、迷宫问题

2012-05-26 16:47 295 查看
以前虽写过迷宫算法,但是非递归的,今天看数据结构,发现八皇后问题与迷宫问题很相似,八皇后、幕集输出、迷宫问题都可以用回溯法解决,即先序遍历求解过程当中的状态树。

以下是我写用回溯法解八皇后问题:其中 Box类省略了。

package cn.test;

import java.util.ArrayList;

import java.util.List;

/**

* 八皇后问题

* @author liubin

*

*/

public class Test {

//棋盘当前部局 的格子

public static int max=8;//矩阵行列数

public static void main(String[] args) {

List<Box> lst=new ArrayList<Box>();

trial(0,max,lst);

}

/**

* 递归方法

* @param row 当前行

* @param max 矩阵行列数

*/

public static void trial(int row ,int max,List<Box> lst){

if (row>=max){

//摆放完毕 输出图形

for(int p=0;p<lst.size();p++){

int x=lst.get(p).getRow();

int y=lst.get(p).getColumn();

switch(y){

case 0:System.out.println("*0000000");break;

case 1:System.out.println("0*000000");break;

case 2:System.out.println("00*00000");break;

case 3:System.out.println("000*0000");break;

case 4:System.out.println("0000*000");break;

case 5:System.out.println("00000*00");break;

case 6:System.out.println("000000*0");break;

case 7:System.out.println("0000000*");break;

}

}

System.out.println();

//return;

}else{

for(int j=0;j<max;j++){

//检测摆放是否合法

Box b=new Box();

b.setRow(row);

b.setColumn(j);

lst.add(b);

if(Legitimate(lst)){//布局合法

//System.out.println("合法");

trial(row+1,max,lst);

}else{//布局不合法移除

lst.remove(lst.size()-1);

}

//trial(row+1,max);

}//end else

lst.remove(lst.size()-1);

}//end else

}

/**

* 检测排列是否合法

* @param lst 要检测的棋子对列

* @return 是否合法 合法返回true 否则反回false

*/

public static boolean Legitimate(List<Box> lst){

//检测是否同行

//检测是否有同列

if (lst.size()==1)//队列只有一个元素

return true;

int x=lst.get(lst.size()-1).getRow();

int y=lst.get(lst.size()-1).getColumn();

for(int i=lst.size()-2;i>=0;i--){

int x1=lst.get(i).getRow();

int y1=lst.get(i).getColumn();

if(x==x1||y==y1){

//System.out.println("同行或同列");

return false;

}

if ( Math.abs( ((float)(y1-y))/(x1-x) )==1 ){//在同一对角线上

//System.out.println("在同一对角线上");

return false;

}

}

return true;

}

}

运行结果:

*0000000

0000*000

0000000*

00000*00

00*00000

000000*0

0*000000

000*0000

以下是幕集输出程序:

package cn.test;

/**

* 幕集输出程序

*/

import java.util.ArrayList;

import java.util.List;

public class Test {

public static int var[]={1,2,3};

public static int k=0;//var 初始序列

/**

* 主函数

* @param args

*/

public static void main(String[] args) {

List lst=new ArrayList<Integer>();

PowerSet(var,lst,k);

}

/**

* 递归函数

* @param sa 原始集合

* @param sb 原始集合的幕集

* @param k

*/

public static void PowerSet(int sa[],List<Integer> sb,int k){

if(k>sa.length-1){

//输出幕集

for(int j=0;j<sb.size();j++){

System.out.print(sb.get(j)+" ");

}

System.out.println();

}else{

//取一个原始集合元素

sb.add(sa[k++]);

PowerSet(sa,sb,k);

//舍一个原始集合元素

sb.remove(sb.size()-1);

PowerSet(sa,sb,k);

}//end else

}

}

运行结果:

1 2 3

1 2

1 3

1

2 3

2

3
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息