用离散数学思考八皇后问题的数据结构

mervynhit 2011-09-11 06:43:03
八皇后问题,是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

我们已经知道要用回硕法了,但是用什么数据结构去储存这个棋盘,从而使算法最简便呢。
我们首先想到的肯定是一个8*8二维数组,它显然是一个好方法,我们可以用两个二维数组,一个二维数组存皇后的位置,另外一个二维数组存0,1,判断某一行或者一列已经被占据了,然后,只要用第二个二维数组去判断就可以了。

那么有没有更好的办法呢,我们的数据结构应该尽可能的包含条件的限制,只要条件的限制就由数据结构去考虑了,而不是由我们自己去考虑。

我们用离散数学去思考问题, 我们可以吧棋盘的行看成一个集合A,列看成一个集合B,A={0,1,2,3,4,5,6,7},B = {a,b,c,d,e,f,g,h},那么8皇后的问题应该是一个关系R, 是笛卡尔乘积 A * B的子集。对于任意两个皇后都不能处于同一行、同一列或同一斜线上,也就意味着 R <= A * B &
对于任意 a1, a2 < A, R(a1) != R(a2),这样我们满足了函数(关系的子集)的一个性质,同时我们需要证明这个关系R的定义域为A,假如R的定义域不为A,也就意味着8个皇后放在了小于7的行数上,那么肯定有两个皇后在一行上,矛盾,所以R的定义域为A。那么我们可以确定R为从A到B的一个函数。

前面用的二维数组的,显然是一个关系,它没有规定两个皇后不能在同一列,而需要编程者子集去判断。而如果我们用函数来表示棋盘:
int board[8], 对于i<8, i表示函数,而Borad[i]表示皇后放在第i行的第board[i]列,board是从行到列的一个函数。那么我们不在需要判断皇后不在同一行了(函数的性质),只需要判断列和斜线,也就简化了问题。


PS:其实都是很浅显的道理,完全不需要证明,只是想说,在设计数据结构的时候,尽量让数据结构包含一些条件,而你在这个数据结构上就只需要判断剩下的条件就可以了。
...全文
224 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
pp0354030 2011-09-12
  • 打赏
  • 举报
回复
楼上们也太水了!
xiaoyu_2011 2011-09-12
  • 打赏
  • 举报
回复
LZ思考的还蛮深刻的
尘缘udbwcso 2011-09-11
  • 打赏
  • 举报
回复
看看.

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧