八皇后问题

来源:互联网 发布:Java swing主题大全 编辑:程序博客网 时间:2024/06/05 02:38

    回溯法在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树。算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解。如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层向其祖先结点回溯;否则,进入该子树,继续按深度优先策略搜索。

    对于n后问题的任何一个解而言,每一个皇后在棋盘上的位置无任何规律,不具有系统性,而更象是随机放置的。由此容易想到下面的拉斯维加斯算法。 与蒙特卡罗算法类似,拉斯维加斯算法找到正确解的概率随着它所用的计算时间的增加而提高。对于所求解问题的任一实例,用同一拉斯维加斯算法反复对该实例求解足够多次,可使求解失败的概率任意小。拉斯维加斯算法的一个显著特征是它所作的随机性决策有可能导致算法找不到所需的解。

    在棋盘上相继的各行中随机地放置皇后,并注意使新放置的皇后与已放置的皇后互不攻击,直至n个皇后均已相容地放置好,或已没有下一个皇后的可放置位置时为止。

     n后问题

     问题描速:在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于在n×n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。

     四皇后问题

    这个问题要求在一个4X4的棋盘上放上4个皇后,使得每一个皇后既攻击不到另外三个皇后,也不被另外三个皇后所攻击。按照国际象棋的规则,一个皇后可以攻击与之处在同一行或同一列或同一斜线上的其他任何棋子。因此,四后问题等于要求四个皇后中的任意两个不能被放在同一行或同一列或同一斜线上。

我们给4×4棋盘的行和列分别从左到右和从上到下编号为1234,同时也给四个皇后也分别编为1234。由于要求不同的皇后不能放在同一行,不失广般性,可设皇后i只放在第i行。这样,四后问题的解可用4元组(x1x2x3x4)来表示。其中xi表示皇后i所处的列的列号。因此,四后问题相应的

     E={(x1,x2,x3,x4) ∣xi∈Si i=l,2,3,4}

   Si={1,2,3,4}  1≤i≤4。


    四后问题相应的约束集D包含如下的约束:

    ①xi≠xj(皇后i和j不在同一列上);

    ② xi −i≠ xj− j(皇后i和j不在斜率为-l的同一条斜线上);

    ③ xi+i≠ xj+j (皇后i和j不在斜率为+l的同一条斜线上);

    ④ 其中i、j=1,2,…,k,且i<>j。从这些约束的几何含义便可断定D具有完备性。

   四后问题相应的状态空间树是一棵满四叉树 。

conio.h不是C标准库中的头文件,在C standard library,ISO C 和POSIX标准中均没有定义。

conio是Console Input/Output(控制台输入输出)的简写,其中定义了通过控制台进行数据输入和数据输出的函数,主要是一些用户通过按键盘产生的对应操作,比如getch()函数等等。

八皇后实现代码

// SQUEEN12.cpp : 定义控制台应用程序的入口点。
//


#include "stdafx.h"
#include <stdlib.h>
#include<conio.h>//Console Input/Output(控制台输入输出)的简写,getch()函数
#include<iostream>
using namespace std;


//用queens[]数组储存每个皇后的位置


#define  Max 8
int sum = 0;


class QueenPuzzle
{


    int queens[Max];
public:
    void printout();
    int  IsVaild(int n);//判断第n个皇后放上去以后,是否合法
    void PlaceQueen(int i);
};


void QueenPuzzle::printout()
{
for (int i=0;i<Max;i++)
{
     for (int j=0;j<Max;j++)
     {
         if (j==queens[i])
             cout<<"■";
         else
             cout<<"□";


     }
     cout<<endl;


}


    cout<<"按q键退出,按其他键继续"<<endl<<endl;
     if(getch()=='q')//从键盘上获得q
         exit(0);


}


void QueenPuzzle::PlaceQueen(int i)
{


    for(int j=0;j<Max;j++)
        //如果全部放完输出结果;
    {
        if (i==Max)
        {
            sum++;
            cout<<"第"<<sum<<"组解"<<endl;
            printout();
            return;
        }


        //放置皇后
        queens[i] = j;
       //判断下一位置能放皇后不
        if (IsVaild(i))
        {
            PlaceQueen(i+1);
        }
    
    }
}


//判断皇后放上去是否合法,是否无冲突
int QueenPuzzle::IsVaild(int n)
{
  //将第n个皇后与第n+1个皇后进行比较
   for (int i=0;i<n;i++)
   {
     if (queens[i]==queens[n])//是否是同一列
         return 0;
     if(abs(queens[i]-queens[n])==(n-i))//是否在同一条对角线 
         return 0;


   }


   return 1;
  
}


int  main()
{
QueenPuzzle queen;
queen.PlaceQueen(0);//给PlaceQueen(i)中的i初始赋值 0
cout<<"共有"<<sum<<"组解"<<endl;


    return 0;
}











0 0
原创粉丝点击