算法/回溯法/8-Queen八皇后问题

问题描述

八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

八皇后问题图示


算法分析

回溯法又称试探法。回溯法的基本做法是深度优先搜索,是一种组织得井井有条的、能避免不必要重复搜索的穷举式搜索算法。
基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。

不考虑规则的话,每一个皇后放在棋盘上都有8种放法,这样我们能得到一棵完全八叉树:从根节点开始,树每增加一层就是多放一个皇后。接下来是对这棵树进行深度优先遍历,并且舍弃不合规则的子节点。

用 x[i] 表示在第 i 行,皇后放在 x[i] 的位置上(想象关于 i 的函数 f(i) ),要求行和列不相同,即 x[i] != x[j] ,要求对角线也不相同,即 abs(i-j) != abs(x[i]-x[j]) ,代码如下:

import static java.lang.StrictMath.abs;

public class N_Queen {

    private int num;
    private boolean[][] matrix;
    private static int count = 1;

    private N_Queen(int num) {
        this.num = num;
        this.matrix = new boolean[num + 1][num + 1];
        place(1);
    }


    //  判断matrix[i][j]与前面的i-1个皇后是否冲突
    private boolean isLegal(int i, int j) {
        for (int m = 1; m <= i - 1; m++) {
            for (int n = 1; n <= num; n++) {
                if (matrix[m][n]) {
                    if (n == j || abs(i - m) == abs(j - n)) { //与某一个皇后同列或者对角时退出
                        return false;
                    }
                }
            }
        }
        return true;
    }


    //  打印
    private void print() {
        System.out.println("case" + count++);
        for (int i = 1; i <= num; i++) {
            for (int j = 1; j <= num; j++) {
                if (matrix[i][j]) {
                    System.out.print("Q  ");
                } else {
                    System.out.print("·  ");
                }
            }
            System.out.println();
        }
        System.out.println();
    }


    //  放置第i个皇后
    private void place(int i) {

        //  进入本函数时,前i-1个皇后已放置完毕

        if (i > num) {
            print();
        } else {
            for (int j = 1; j <= num; j++) {
                matrix[i][j] = true;
                if (isLegal(i, j)) {
                    place(i + 1);
                }
                matrix[i][j] = false;
            }
        }
    }


    public static void main(String[] args) {
        new N_Queen(8);
    }
}

看了一些大神的代码,先mark一下以后研究 目前最快的n皇后问题算法

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值