首页 > 编程知识 正文

回溯法八皇后算法思想,八皇后问题最简单算法

时间:2023-05-05 22:11:50 阅读:44371 作者:1935

八皇后问题,是一个古老而有名的问题,是回溯算法的典型例题。 这个问题提出于19世纪著名数学家震动的板栗1850年:

在8X8格国际象棋上安排8个皇后,防止相互攻击。 也就是说,任何皇后都不能位于同一行、同一列或同一条斜线上

(倾斜度为1 ),询问有几种摆动方法。 摇摇晃晃的栗子被认为有76种方案。

1854年柏林将棋杂志发表了40种不同的解,后来用图论的方法得出了92种结果。

计算机发明后,有几种方法可以解决这个问题。

算法思想:

首先我们分析一下问题的解,我们每取出一个皇后,放入一行,共有八种不同的放法,

然后再放第二个皇后,同样如果不考虑规则,还是有八种放法。

于是我们可以用一个八叉树来描述这个过程。从根节点开始,树每增加一层,便是多放一个皇后,

直到第8层(根节点为0层),最后得到一个完全八叉树。  

紧接着我们开始用深度优先遍历这个八叉树,在遍历的过程中,进行相应的条件的判断。以便去掉不合规则的子树。

那么,具体在什么条件下进行子树的裁剪呢?

我们首先就解决问题的机制做出约定。

用X[i]来表示,在第i行,皇后放在了X[i]这个位置。

于是我们考虑第一个条件,不能再同一行,同一列于是我们得到x[i]不能相同。

剩下一个条件是不能位于对角线上,这个条件不是很明显,我们经过分析得到,

设两个不同的皇后分别在j,k行上,x[j],x[k]分别表示在j,k行的那一列上。

那么不在同一对角线的条件可以写为abs((j-k))!=abs(x[j]-x[k]),其中abs为求绝对值的函数。

# includeiostreamusingnamespacestd; int num; int *x; int sum; boolplace(intk ) {for ) intj=1; jk; j ) if(ABS(x[k]-x[j] )=ABS (k-j )||x[j]==x[k] )返回假; 返回真; }语音回溯(int ) if )///num )/num是皇后的数量) sum; //sum是所有可行解for(intm=1; m=num; m ) { cout''m ',' x[m] '; //该行在输出中递归到叶节点时变为可行解} coutendl; }elsefor(intI=1; i=num; I ) { x[t]=i; if(place ) t ) )回溯) t1; //这里的place函数用于判断我们上面提到的条件,如果成立,则下一个递归}}void main () { num=8; sum=0; x=new int[num 1]; for(intI=0; i=num; I ) x[i]=0; 回溯(1; cout '方案为' sumendl; delete []x; }

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。