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

    一、八皇后问题简介

    八皇后问题,一个古老而著名的问题,是回溯算法的典型案例。该问题由国际西洋棋棋手马克斯·贝瑟尔于 1848 年提出:在 8×8 格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。高斯认为有 76 种方案。1854 年在柏林的象棋杂志上不同的作者发表了 40 种不同的解,后来有人用图论的方法解出 92 种结果。

    如下图是它的一种解法

    二、解决思路

    采用递归回溯的方法解决。

    先做如下约定

    • 我们用ways[8],这个数组存储摆放皇后的方式,其中,下标表示第几行,对应的值表示皇后所在的列
    • judge(int n) 表示判断正在放置的第n个皇后,是否会与之前摆放好的皇后存在列冲突对角线冲突(默认皇后不摆放在一行)
    • putQueen(int n) 该方法为递归的调用放置皇后的方法,若出现冲突则回溯

    具体步骤:

    1. 先在第一行第一列放置第一个皇后,然后,再第二行放置第二个皇后,若与现有皇后站位不冲突,则继续在第三行放置第三个皇后......
    2. 如果发现冲突,则调整列,直到所有列均试完,若发现可以放置,则继续放置下一行,直至八个皇后均摆放完毕,如果,所有的列均与现有皇后的站位冲突则,回溯至上一行,继续遍历上一行的各列,以此类推,直到将第一行的各列均遍历完毕,就得到所有的结果。

    三、代码实现

    /**
     * @author ymy
     * @date 2020/5/12
     *
     * 八皇后问题:
     *      在8*8的棋盘上,放置八个皇后,
     *      要求这八个皇后的任意两个不在同一行,同一列,同一斜线
     */
    public class EightQueens {
    
        private int queenNum = 8;//皇后数量
        private static int WAYS_NUM;
        private int [] ways=new int [8];//放置方法
        private static int judgeNums;
    
        /**
         * @param n 表示正在放置的第n个皇后
         * @return
         * 因为ways存储的含义就不包括同一行,所以只需要判断是否在同一列或者同一斜线即可。
         */
        public boolean jugde(int n){
            judgeNums++;
            for (int i = 0; i <n ; i++) {
                //  同一行               同一列(参考正方形对角线)
                if (ways[i]==ways[n] || Math.abs(ways[i]-ways[n])==Math.abs(i-n)){
                    return false;
                }
            }
            return true;
        }
    
        public void print(){
            WAYS_NUM++;
            System.out.printf("这是第%d种方法:",WAYS_NUM);
            for (int a:ways){
                System.out.print(a+" ");
            }
            System.out.println();
        }
    
        /**
         * @param n 放置的第n个皇后
         */
        public void putQueen(int n){
            if (n==queenNum){
                print();
                return;
            }
            for (int i=0;i<queenNum;i++){
                ways[n]=i;
                if (jugde(n)){
                    putQueen(n+1);
                }
            }
        }
    
        public static void main(String[] args) {
            EightQueens eightQueens = new EightQueens();
            eightQueens.putQueen(0);
            System.out.println("判断次数:"+judgeNums);
        }
    
    }
    

    四、测试结果

  • 相关阅读:
    chrome.declarativeWebRequest
    webRequest模块的解读
    C#连接池
    sftp
    Lynx
    LD_PRELOAD & LD_LIBRARY_PATH 动态库路径
    libc.so.6 误删后修复
    man 转 pdf _____ jpg 转 pdf
    here文档
    lsof fuser
  • 原文地址:https://www.cnblogs.com/polary/p/12876802.html
Copyright © 2011-2022 走看看