八皇后问题-回溯算法

问题描述

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

《八皇后问题-回溯算法》

问题分析

对于八皇后的求解可采用回溯算法,从上至下依次在每一行放置皇后,进行搜索,若在某一行的任意一列放置皇后均不能满足要求,则不再向下搜索,而进行回溯,回溯至有其他列可放置皇后的一行,再向下搜索,直到搜索至最后一行,找到可行解,输出。可以使用递归函数实现上述回溯算法,递归函数用于求解在某一行放置皇后

那么,我们应该怎么做呢?其实步骤不太难:

    (1)在第n行寻找可以插入的位置,中间涉及到位置合法性的判断

    (2)如果没有可以插入的位置,返回

    (3)如果有可以插入的位置, 插入数据。此时再判断是否已经是最后一行,如果是,打印输出返回;反之继续对下一行数据进行试探处理。


php代码

public static $gEightQueen = array(0,0,0,0,0,0,0,0);
public static $gCount=0;
//打印八皇后结果
private function display($gEightQueen){
    for($outer = 0; $outer <8; $outer ++){
        for($inner = 0; $inner < $gEightQueen[$outer]; $inner ++)  echo "# ";
        echo "@ ";
        for($inner = $gEightQueen[$outer] + 1; $inner < 8; $inner ++)  echo "# ";
        echo "<br>";
    }
    echo "===========================<br>";
}
//位置合法性判断
private function check_position_valid($loop,$value){

    for($index=0; $index<$loop; $index++) {
        $data =  $this->gEightQueen[$index];
        //位于同一列
        if($data == $value) {
            return 0;
        }
        //反向对角线
        if(($loop+$value) == ($data+$index)){
            return 0;
        }
        //正向对角线
        if(($loop-$value) == ($index-$data)){
            return 0;
        }
    }
    return 1;

}
private function eight_queen($index){
    for($loop=0; $loop<8; $loop++) {
        if($this->check_position_valid($index,$loop)) {
            $this->gEightQueen[$index] = $loop;
            //判断是否已经是最后一行
            if($index == 7){
                $this->gCount++;
                echo $this->gCount."解法<br>";
                $this->display( $this->gEightQueen);
                return 1;
            }
            $this->eight_queen($index+1);
        }
    }

}
public function eight_queen_result(){
    $this->eight_queen(0);
}

    原文作者:八皇后问题
    原文地址: https://blog.csdn.net/jespere_ling/article/details/48711055
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞