码迷,mamicode.com
首页 > 其他好文 > 详细

八皇后问题的回溯和递归方法

时间:2014-06-26 16:17:30      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:style   class   blog   code   color   string   

1、回溯法

用一维数组记录皇后的位置。数组的下标代表皇后所处的行,下标对应的值代表皇后所处的列。用count记录皇后的个数,当count小于queen数时,在循环体中寻找合适位置的queen。寻找queen:从列1依次寻找,满足条件则count+1,继续从列1处寻找下一个queen。如全部找完没找到合适的位置,则count-1,从第count个皇后所在列的下一位置开始继续循环。
public class Queen {

       public void queenInstance(int num ) {
             if (num < 1 )
                   throw new IllegalArgumentException();
             // store the position of the queen
             int[] queen = new int[num + 1];
             // store the queen count
             int count = 1;
             queen[ count] = 1 ;

             while (count > 0 ) {
                   while ((count <= num ) && (queen [count ] <= num)) {
                         if (! isValid( queen, count ))
                               queen[ count] ++;
                         else {
                               count++;
                               if( count <= num)
                                     queen[ count] = 1 ;
                         }
                   }
                   if (count > num ) {
                         for (int i = 1; i <= num ; i++ )
                               System. out.println ("(" + i + ", " + queen[i] + ")") ;
                         break;
                   }
                   count--;
                   queen[ count] ++;
             }
       }

       private boolean isValid(int a [], int count) {
             for (int i = 1; i < count ; i++ )
                   if (a [i ] == a[ count] || ( i - count == a[ i] - a [count ])
                               || (i - count == a [count ] - a[ i]))
                         return false;
             return true;
       }

       public static void main(String ... args) {
             Queen queen = new Queen ();
             queen. queenInstance(8);
       }

2、位运算法

考虑到我们寻找皇后是按照行的顺序依次寻找,因此在程序中,行的信息可以省略,每次的寻找实际上是为了在列中找到一个合适的位置。因此我们用一个int值(当然long也可以),将其第1到列总数的位置为1。这里我们通过将1左移num位减去1得到。函数test方法的三个参数分别是:皇后占用的位、左对角线皇后占用的位、右对角线皇后占用的位置。每次递归中,首先判断row是否等于upplim,等于则说明所有位被皇后占用,递归结束,得到一个解。若不相等,寻找可用的位(upplim & ~(row | ld | rd)),然后判断是否为0,为0说明全被占用,递归结束,未寻找到可行解。若不为0,则依次把所有可以放置皇后的位放置皇后,然后调用递归方法。

 
public class Queen {

       private int upplim;
       private int sum;

       public void queenCalculate(int num ) {
             if (num < 1 || num >= 31 )
                   throw new IllegalArgumentException();
             upplim = (1 << num ) - 1;
             sum = 0;
             test( 0, 0 , 0) ;
       }

       private void test(int row , int ld, int rd) {
             if (row != upplim ) { // row不满,即皇后未放置完全
                   int pos = upplim & ~( row | ld | rd) ; // 寻找空闲位置
                   while (pos != 0 ) { // 仍有可以放置皇后的位置
                         int p = pos & -pos ; // 取出最右边的1
                         pos -= p; // 把皇后放在最右边的1的位置
                         test( row + p, ( ld + p) << 1 , (rd + p ) >> 1) ; // 对下一行调用递归方法
                   }
             } else
                   sum++;
       }

       public static void main(String ... args) {
             Queen queen = new Queen ();
             queen. queenCalculate(12);
             System. out.println (queen .sum + " " );
       }
}

 

 
 

八皇后问题的回溯和递归方法,布布扣,bubuko.com

八皇后问题的回溯和递归方法

标签:style   class   blog   code   color   string   

原文地址:http://www.cnblogs.com/zhouthanos/p/3809038.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!