zoukankan      html  css  js  c++  java
  • 递归--基于回溯和递归的八皇后问题解法

    八皇后问题是在8*8的棋盘上放置8枚皇后,使得棋盘中每个纵向、横向、左上至右下斜向、右上至左下斜向均只有一枚皇后。八皇后的一个可行解如图所示:

                 

       

             

                 
             

       
     

               
           

         
               

     
         

           

    思路

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

    此处可用借鉴陈海涛网易博客中的思路,不用二维数组,而采用一维数组进行回溯,参见http://www.cnblogs.com/jiayouwyhit/p/3226757.html。因为1维数组的下标即可表示行或者列,再在一维数组里面赋值,即可代表列或者行。此条件即可至少满足八皇后问题的一个条件:两个皇后不同行或者不同列。省去后文的一个步骤判断。

    本人参考网上别人的回溯思路,写的代码如下:(注意,本代码已经在VC6.0下通过实验测试)

    //8皇后问题
    //基于递归的回溯算法
    const int length=8;

    int counter=0;

    bool Check(int matrix[], int row)//检验是否合理
    {
        int i=0;
        for (i=0;i<=row-1;i++)
        {
            if (matrix[i]==matrix[row] || row-i==matrix[row]-matrix[i] ||i-row==matrix[row]-matrix[i])
                return false;
        }
        return true;
    }

    void EightQueen(int matrix[], int row)
    {
        int i=0,j=0;
        for (i=0;i<length;i++)
        {
            matrix[row]=i;
            if (Check(matrix,row) && row<=length-1)//满足要求
            {
                if (row==length-1)
                {
                    ++counter;
                    printf("Solution %d: ",counter);
                    for (j=0;j<length;j++)
                        printf("%4d",matrix[j]);
                    printf(" ");
                }
                else
                      EightQueen(matrix,row+1);
            }
        }
    }

    int main(int argc, char* argv[])
    {
        int matrix[length]={0};
        EightQueen(matrix,0);

        printf("We have solved the problem! ");
        return 0;
    }

    复杂度分析:本文算法的时间复杂度为O[n^(n+1)]。比http://www.cnblogs.com/jiayouwyhit/p/3226757.html时间复杂度更高.

    实际上,经过实际的实验测试,本文的算法实际上在时间上要比前面提到的算法性能要好很多。经过仔细分析,其原因在于:本文算法中对递归有一个限制条件

    Check(matrix,row),即:当当前点不满足我们的约束条件时,直接就不再进行递归,因此函数void EightQueen(int matrix[], int row) 的时间复杂度会远远小于O[n^n](假如不考虑check函数自身的时间复杂度的话)。但该算法具体的时间复杂度是多少,由于有判断语句的存在,本人觉得此处无法写出具体的复杂度表达式(再一次说明本人数学功底还有待提高啊(^o^)/~)。

  • 相关阅读:
    Android 新建项目报错(CANNOT RESOLVE SYMBOL R)
    GIT相关
    Java 语言基础
    StarUML
    public static void main(String[] args)的理解
    软件安装以及环境搭配
    基础
    字符串的格式化
    python里的正则表达式
    集合
  • 原文地址:https://www.cnblogs.com/jiayouwyhit/p/3227314.html
Copyright © 2011-2022 走看看