八皇后问题是一个古老而著名的问题。该问题是19世纪著名的数学家高斯1850年提出:在一个8×8国际象棋盘上,有8个皇后,每个皇后占一格;要求皇后之间不会出现相互“攻击”的现象,即不能有两个皇后处在同一行、同一列或同一对角线上。问共有多少种不同的方法?
回溯算法也叫试探法,是一种搜索问题的解的方法。基本思想是在一个包含所有解的解空间树中,按照深度优先的策略,从根节点出发搜索解空间树。算法搜索至解空间树的任意结点时,总是先判断该结点是否肯定不包含问题的解。如果肯定不包含,则跳过对以该节点为跟的子树的系统搜索,逐层向其祖先结点回溯。否则,进入该子树,继续按深度优先的策略进行搜索。回溯法在用来求问题的所有解时,要回溯到跟,且跟结点的所有子树都已经被搜索遍才结束。
八皇后问题有多种解法,回溯法是其中之一种解法,比较容易理解。
代码:
/************************************************************************/
/* 八后问题 */
/************************************************************************/
#include <stdio.h>
int count = 0;
//判断当前位置是否能放皇后
int IsCorrect(int i, int j, int (*Q)[8])
{
int s,t;
//判断某一行上是否能放皇后
for(s=i,t=0;t<8;t++)
if (Q[s][t]==1 && t!=j)
return 0;
//判断某一列上是否能放皇后
for(t=j,s=0;s<8;s++)
if(Q[s][t]==1 && s!=i)
return 0;
//判断左上是否能放皇后
for(s=i-1,t=j-1;s>=0&&t>=0;s–,t–)
if(Q[s][t]==1)
return 0;
//判断右下是否能放皇后
for(s=i+1,t=j+1;s<8&&t<8;s++,t++)
if(Q[s][t]==1)
return 0;
//判断右上是否能放皇后
for(s=i-1,t=j+1;s>=0&&t<8;s–,t++)
if(Q[s][t]==1)
return 0;
//判断左下是否能放皇后
for(s=i+1,t=j-1;s<8&&t>=0;s++,t–)
if(Q[s][t]==1)
return 0;
//其它情况
return 1;
}
//放置皇后
void Queen(int j, int (*Q)[8])
{
int i,k;
if(j==8) //如果8个皇后全部放置完毕
{
for(i=0;i<8;i++)
{
for(k=0;k<8;k++)
printf(“%d “,Q[i][k]);
printf(“\n”);
}
printf(“\n”);
count++;
return;
}
for(i=0;i<8;i++)
if(IsCorrect(i,j,Q))
{
Q[i][j]=1;
Queen(j+1,Q);
Q[i][j]=0;
}
}
int main()
{
int Q[8][8];
int i,j;
for(i=0;i<8;i++)
for(j=0;j<8;j++)
Q[i][j]=0;
Queen(0,Q);
printf(“%d\n”,count);
return 0;
}
输出结果:
该实验未运用回溯法解答问题,详细的回溯法解决八皇后问题算法有待学习以后更新。
待续。。。