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


    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,则依次把所有可以放置皇后的位放置皇后,然后调用递归方法。

    package algorithm;
    
    public class Queen {
    
        private int upplim;
        private int sum;
        private int queen[];
        private int count;
    
        public void queenCalculate(int num) {
            if (num < 1 || num > 31)
                throw new IllegalArgumentException();
            upplim = (1 << num) - 1;
            sum = 0;
            queen = new int[num + 1];
            count = 1;
            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的位置
                    // 记录位置用于打印输出
                    int i = 0;
                    while(p != (1 << i))
                        i++;
                    queen[count++] = i + 1;
                    test(row + p, (ld + p) << 1, (rd + p) >> 1); // 对下一行调用递归方法
                }
            } else {
                sum++;
                for (int i = 1; i < count ; i++ )
                    System. out.print("(" + i + ", " + queen[i] + ")") ;
                System.out.println();
            }
            count--;
        }
    
        public static void main(String... args) {
            Queen queen = new Queen();
            queen.queenCalculate(8);
            System.out.println(queen.sum + " ");
        }
    
    }
     
  • 相关阅读:
    JAVA8 Optional类记录
    Annotation-specified bean name 'customerMapper' for bean class [com.jiutong.zeus.old.mapper.zqp.CustomerMapper] conflicts with existing, non-compatible bean definition of same name and class
    正则 0-100的正整数
    Windows 安装ElasticSearch 安装IK 分词器
    Push failed Invocation failed Server returned invalid Response. java.lang.RuntimeException: Invocation failed Server returned invalid Response.
    BigDecimal 方法使用
    Factory method 'eurekaClient' threw exception; nested exception is java.lang.RuntimeException: Failed to initialize DiscoveryClient!
    子项目的逆向工程-代码生成器
    安装 RabbitMQ
    redis 分布式锁-简易版与 redisson 实验
  • 原文地址:https://www.cnblogs.com/zhouthanos/p/3809038.html
Copyright © 2020-2023  润新知