实验内容
(1)八皇后及N皇后问题
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种方法可以解决此问题。
请编程实现八皇后问题,并把92种解的前三种解输出到屏幕(8*8的二维矩阵,Q代表皇后,X代表空)。并把此问题的求解过程延伸到N皇后问题。
代码实现:
package com.alogrithm;
public class NQueen {
private int queenCount ; //皇后个数
private int[] feasible ; //可接受的分配方案,feasible为皇后所在行,feasible[n]为第n行皇后所在列
private int[] vol={0,0,0,0,0,0,0,0};//保存所在列值,用于将置放皇后所在位置的值置为1
private long sum ; //当前已找到的可行方案数
private static int index ; //记录遍历方案序数
private int[][] location;//皇后所在的位置i,j第i行第j列
/**
*
* @param n 皇后的个数
*/
public NQueen(int n){
sum = 0 ; //初始化方案数为1,当回溯到最佳方案的时候,就自增1
queenCount = n ; //求n皇后问题,由自己定义
feasible = new int[n+1]; //x[i]表示皇后i放在棋盘的第i行的第x[i]列
index = 1 ; //这个是我额外定义的变量,用于遍历方案的个数,请看backTrace()中h变量的作用,这里将它定义为static静态变量
location = new int[n][n];
for(int i=0;i<queenCount;i++){
for(int j=0;j<queenCount;j++)
location[i][j]=0;
}
}
/**
*
* @param k 第k行判断
* @return 是否可置于该位置
*/
public boolean place (int k){
for (int j = 1 ; j < k ; j++){
//皇后所在的位置不可同行,同列,且斜率不为-1或1
if ( (Math.abs(k - j)) == (Math.abs(feasible[j]-feasible[k])) || (feasible[j] == feasible[k]) ){
return false;
}
}
return true ;
}
/**
*
* @param t 检测后可放置的皇后个数
*/
public void backTrace (int t){
//t大于皇后的数目
if (t > queenCount){
sum ++ ; //可行方案数+1
System.out.println ("可行方案" + (index++) + "↓");
output(feasible);
System.out.println("------------------------------");
}
//t小于皇后的数目
else {
//扩展queenCount个子节点
for (int i = 1 ; i <= queenCount ; i++){
feasible[t] = i ;
if (place (t)){ //检查子结点的可行性
backTrace (t+1);//递归调用
}
}
}
}
/**
*
* @param mid 中间变量
*/
public void output (int[] mid){
for (int i = 1 ; i < mid.length ; i++){
vol[i-1] =mid[i];//可放置皇后的列值
}
//将皇后所在的位置的值为1
for(int n=0;n<location.length;n++){
location[n][vol[n]-1] = 1;
}
//输出皇后所在位置的数组,1为皇后所在的位置
for(int m=0;m<location.length;m++){
for(int n=0;n<location[m].length;n++){
if(location[m][n] == 1){
//删除最后一个','
if(n==location.length-1)
System.out.print("Q");
else
System.out.print("Q,");
}
else{
//删除最后一个','
if(n==location.length-1)
System.out.print("X");
else
System.out.print("X,");
}
}
//将皇后所在位置的置置为0,以便下一次数组安排皇后的位置
location[m][vol[m]-1] = 0;
System.out.println();
}
}
public static void main (String[] args){
System.out.println("------------------------------");
NQueen queen= new NQueen(7);
queen.backTrace(1); //从1开始回溯
System.out.println ("\n综上所述,"+queen.queenCount+"皇后的可行方案个数为:" + queen.sum);
}
}
运行结果:
本文介绍了一个经典的回溯算法案例——八皇后问题及其扩展到N皇后问题的解决方案。通过编程实现,展示了如何确保皇后间不发生冲突,并给出了部分可行解的具体实例。
866

被折叠的 条评论
为什么被折叠?



