zoukankan      html  css  js  c++  java
  • 回溯法解决八皇后问题

    八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。

    八皇后问题最早是由国际国际象棋棋手马克斯·贝瑟尔于1848年提出。之后陆续有数学家对其进行研究,其中包括高斯康托,并且将其推广为更一般的n皇后摆放问题。八皇后问题的第一个解是在1850年由弗朗兹·诺克给出的。诺克也是首先将问题推广到更一般的n皇后摆放问题的人之一。1874年,S.冈德尔提出了一个通过行列式来求解的方法,这个方法后来又被J.W.L.格莱舍加以改进。

    艾兹格·迪杰斯特拉在1972年用这个问题为例来说明他所谓结构性编程的能力。

    八皇后问题在1990年代初期的著名电子游戏第七访客NDS平台的著名电子游戏雷顿教授与不可思议的小镇中都有出现。

    以上内容来自维基百科。

    解决八皇后问题的思路:

    1、用数组queues表示八个皇后的位置,下标为列,值为行。这样初始时八个皇后就在不同的列,问题变成了给八个皇后行的排列组合。

    2、找到第i行棋盘上的可以放置皇后的方格,即行号和列号满足3就可以放置皇后。检查第j列,满足放置条件进入4,否则进入5。

    3、

      a.方格与已经标记的皇后不在同一列,不在同一行。

      b.方格与已经标记的皇后不在同一正斜线,不在同一反斜线。

    4、标记皇后为queues[i]=j,如果此时所有行都已经放置皇后,即行号i = 7,则放置方法总数加1,否则 将i = i+1,返回步骤2。

    5、将j = j+1,返回步骤2。

    代码如下:

    package com.smikevon.basic.interview;
    
    /**
     * Created by fengxiao on 15-2-27.
     */
    public class EightQueen {
        
        private static final int CHESS_SIZE = 8;
    
        //数组下标表示列,数组对应的值表示行
        private static int[] queens = new int[CHESS_SIZE];
        
        private static int sum;
        
        public static void main(String[] args){
            
            //初始化为一个不存在的行
            for(int i=0;i<CHESS_SIZE;i++){
                //保证列列不受初始值影响
                queens[i] = 10000;
            }
            
            //查找将哪个皇后放在第0行
            count(queens,0);
            System.out.println("total:"+sum);
        }
        
        /**
         * 找出一个皇后放在第row行
         */
        public static  void count(int[] queens, int row){
            
            for(int i=0;i<CHESS_SIZE;i++){
                queens[row]=i;
                if(checkLegal(row)){
                    if(row == CHESS_SIZE-1){
                        printChess();
                        sum++;
                    }else{
                        count(queens,row+1);
                    }
                }
            }
            
        }
    
        /**
         * 和第row行之前已经放置好的皇后进行比较,查看是否是合规位置
         */
        public static boolean checkLegal(int row){
            for(int i=0;i<row;i++){
                if(queens[i]-queens[row] == row-i || row-i ==queens[row]-queens[i] || queens[row]==queens[i]){
                    return false;
                }
            }
            return true;
        }
    
        /**
         * 打印出棋局
         */
        public static void printChess(){
            System.out.println();
            for(int i=0;i<CHESS_SIZE;i++){
                for(int j=0;j<CHESS_SIZE;j++){
                    if(queens[i] != j){
                        System.out.print("* ");
                    }else{
                        System.out.print("Q ");
                    }
                }
                System.out.println();
            }
            
        }
    
    }

    打印结果:

    * * * * * Q * * 
    * * * Q * * * * 
    Q * * * * * * * 
    * * * * Q * * * 
    * * * * * * * Q 
    * Q * * * * * * 
    * * * * * * Q * 
    * * Q * * * * * 
    
    * * * * * Q * * 
    * * * Q * * * * 
    * Q * * * * * * 
    * * * * * * * Q 
    * * * * Q * * * 
    * * * * * * Q * 
    Q * * * * * * * 
    * * Q * * * * * 
    
    * * * * * Q * * 
    * * * Q * * * * 
    * * * * * * Q * 
    Q * * * * * * * 
    * * Q * * * * * 
    * * * * Q * * * 
    * Q * * * * * * 
    * * * * * * * Q 
    
    * * * * * Q * * 
    * * * Q * * * * 
    * * * * * * Q * 
    Q * * * * * * * 
    * * * * * * * Q 
    * Q * * * * * * 
    * * * * Q * * * 
    * * Q * * * * * 
  • 相关阅读:
    lncRNA表达定量方法评估
    比对软件之STAR的使用方法
    怎么检测自己fastq的Phred类型 | phred33 phred64
    质控工具之TrimGalore使用方法
    怎么从bam文件中提取出比对OR没比对上的paired reads | bamToFastq | STAR
    RepBaseRepeatMaskerEdition下载 | RepeatMasker
    Nr,GenBank, RefSeq, UniProt 数据库的异同
    质控工具之cutadapt的使用方法
    初步了解hg19注释文件的内容 | gtf
    单细胞数据高级分析之消除细胞周期因素 | Removal of cell cycle effect
  • 原文地址:https://www.cnblogs.com/seanvon/p/4303728.html
Copyright © 2011-2022 走看看