回溯法解八皇后、幕集输出、迷宫问题
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
以下是我写用回溯法解八皇后问题:其中 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
相关文章推荐
- 八皇后问题(DFS加回溯)输出排列的所有情况
- 回溯法的典型问题 八皇后 马踏棋盘 迷宫
- 回溯法——八皇后问题
- poj(3984)——迷宫问题(输出路径)
- POJ - 3984 迷宫问题 (BFS+前缀处理输出路径)
- C#WPF实现回溯算法解决八皇后问题
- 回溯法解八皇后问题及再看八皇后问题优化
- GDI+学习(7) 八皇后问题回溯算法演示系统
- 八皇后问题 回溯
- ACM:回溯法,八皇后问题,素数环
- poj 3984 迷宫问题 bfs输出路径
- 【算法入门经典】7.4回溯法【八皇后问题】
- 八皇后问题 回溯
- 回溯法解迷宫问题
- 回溯法求迷宫问题
- 回溯算法思想与八皇后问题解的个数
- 回溯法——迷宫问题
- 八皇后问题回溯解法
- VB探索法(回溯)应用于迷宫问题你
- Java利用回溯思想解决迷宫问题(寻找最短路径)