八皇后问题解法(Common Lisp实现)

如何才能在一张国际象棋的棋盘上摆上八个皇后而不致使她们互相威胁呢?这个著名的问题可以方便地通过一种树搜索方法来解决。

首先,我们需要写一个函数来判断棋盘上的两个皇后是否互相威协。在国际象棋中,皇后可以沿棋盘的行、列和通过它们所在位置的两条对角线移动。如果我们给行和列标上数字,我们就可以对棋盘上的位置编码。

使用函数threat判断两个位置是否互相威胁;函数conflict用来判断向棋盘上添加一个新皇后时,位置(n m)是否是安全的;函数queen列出八皇后问题的解(对于2X2和3X3的棋盘无解)。

Lisp源代码

;判断两个位置(i j)和(a b)是否互相威胁
(defun threat (i j a b)
	(or
		(equal i a) 			;同行,
		(equal j b) 			;同列,
		(equal(- i j)(- a b))	;西南-东北对角线. 
		(equal(+ i j)(+ a b))	;西北-东南对角线
	)
)
;判断向棋盘上添加一个新皇后时,位置(n m)是否是安全的
(defun conflict (n m board)
	(cond 
		((null board) nil) ;棋盘为空时,不冲突
		((or (threat n m (caar board) (cadar board)) 
			 (conflict n m (cdr board))))	;递归调用
	)
)
;列出八皇后问题的解, 棋盘大小为size X size
(defun queen(size)
	(prog (n m board)
		(setq n 1)	;第一行
	loop_n 
		(setq m 1) 	;第一列
	loop_m
		(cond ((conflict n m board) (go un_do_m)))	;检查冲突. 若冲突,则转un_do_m
		(setq board (cons (list n m) board))		;若不冲突,则在棋盘上加一个皇后
		(cond((> (setq n (+ n 1)) size)		;进行下一行
			(print (reverse board))) 				;如n放完,打印结果
		) 
		(go loop_n) 								;去找列
	un_do_n
		(cond
			((null board)(return 'finished))		;所有可能情况找完
			(t
				(setq 		;用移去最后放置的一个皇后来取消最后一个结局
					m (cadar board) 	
					n (caar board) 
					board (cdr board)
				)
			)
		)
	un_do_m 
		(cond
			((> (setq m (+ m 1)) size)
				(go un_do_n)) 	;进行下一列
			(t (go loop_m))
		)
	)
)

程序运行结果

在大小4*4的棋盘上运行命令为:

(queen 4)

运行结果为:

 

在大小8*8的棋盘上运行命令为:

(queen 8)

一共有92个解,列出如下:

((1 1) (2 5) (3 8) (4 6) (5 3) (6 7) (7 2) (8 4))

((1 1) (2 6) (3 8) (4 3) (5 7) (6 4) (7 2) (8 5))

((1 1) (2 7) (3 4) (4 6) (5 8) (6 2) (7 5) (8 3))

((1 1) (2 7) (3 5) (4 8) (5 2) (6 4) (7 6) (8 3))

((1 2) (2 4) (3 6) (4 8) (5 3) (6 1) (7 7) (8 5))

((1 2) (2 5) (3 7) (4 1) (5 3) (6 8) (7 6) (8 4))

((1 2) (2 5) (3 7) (4 4) (5 1) (6 8) (7 6) (8 3))

((1 2) (2 6) (3 1) (4 7) (5 4) (6 8) (7 3) (8 5))

((1 2) (2 6) (3 8) (4 3) (5 1) (6 4) (7 7) (8 5))

((1 2) (2 7) (3 3) (4 6) (5 8) (6 5) (7 1) (8 4))

((1 2) (2 7) (3 5) (4 8) (5 1) (6 4) (7 6) (8 3))

((1 2) (2 8) (3 6) (4 1) (5 3) (6 5) (7 7) (8 4))

((1 3) (2 1) (3 7) (4 5) (5 8) (6 2) (7 4) (8 6))

((1 3) (2 5) (3 2) (4 8) (5 1) (6 7) (7 4) (8 6))

((1 3) (2 5) (3 2) (4 8) (5 6) (6 4) (7 7) (8 1))

((1 3) (2 5) (3 7) (4 1) (5 4) (6 2) (7 8) (8 6))

((1 3) (2 5) (3 8) (4 4) (5 1) (6 7) (7 2) (8 6))

((1 3) (2 6) (3 2) (4 5) (5 8) (6 1) (7 7) (8 4))

((1 3) (2 6) (3 2) (4 7) (5 1) (6 4) (7 8) (8 5))

((1 3) (2 6) (3 2) (4 7) (5 5) (6 1) (7 8) (8 4))

((1 3) (2 6) (3 4) (4 1) (5 8) (6 5) (7 7) (8 2))

((1 3) (2 6) (3 4) (4 2) (5 8) (6 5) (7 7) (8 1))

((1 3) (2 6) (3 8) (4 1) (5 4) (6 7) (7 5) (8 2))

((1 3) (2 6) (3 8) (4 1) (5 5) (6 7) (7 2) (8 4))

((1 3) (2 6) (3 8) (4 2) (5 4) (6 1) (7 7) (8 5))

((1 3) (2 7) (3 2) (4 8) (5 5) (6 1) (7 4) (8 6))

((1 3) (2 7) (3 2) (4 8) (5 6) (6 4) (7 1) (8 5))

((1 3) (2 8) (3 4) (4 7) (5 1) (6 6) (7 2) (8 5))

((1 4) (2 1) (3 5) (4 8) (5 2) (6 7) (7 3) (8 6))

((1 4) (2 1) (3 5) (4 8) (5 6) (6 3) (7 7) (8 2))

((1 4) (2 2) (3 5) (4 8) (5 6) (6 1) (7 3) (8 7))

((1 4) (2 2) (3 7) (4 3) (5 6) (6 8) (7 1) (8 5))

((1 4) (2 2) (3 7) (4 3) (5 6) (6 8) (7 5) (8 1))

((1 4) (2 2) (3 7) (4 5) (5 1) (6 8) (7 6) (8 3))

((1 4) (2 2) (3 8) (4 5) (5 7) (6 1) (7 3) (8 6))

((1 4) (2 2) (3 8) (4 6) (5 1) (6 3) (7 5) (8 7))

((1 4) (2 6) (3 1) (4 5) (5 2) (6 8) (7 3) (8 7))

((1 4) (2 6) (3 8) (4 2) (5 7) (6 1) (7 3) (8 5))

((1 4) (2 6) (3 8) (4 3) (5 1) (6 7) (7 5) (8 2))

((1 4) (2 7) (3 1) (4 8) (5 5) (6 2) (7 6) (8 3))

((1 4) (2 7) (3 3) (4 8) (5 2) (6 5) (7 1) (8 6))

((1 4) (2 7) (3 5) (4 2) (5 6) (6 1) (7 3) (8 8))

((1 4) (2 7) (3 5) (4 3) (5 1) (6 6) (7 8) (8 2))

((1 4) (2 8) (3 1) (4 3) (5 6) (6 2) (7 7) (8 5))

((1 4) (2 8) (3 1) (4 5) (5 7) (6 2) (7 6) (8 3))

((1 4) (2 8) (3 5) (4 3) (5 1) (6 7) (7 2) (8 6))

((1 5) (2 1) (3 4) (4 6) (5 8) (6 2) (7 7) (8 3))

((1 5) (2 1) (3 8) (4 4) (5 2) (6 7) (7 3) (8 6))

((1 5) (2 1) (3 8) (4 6) (5 3) (6 7) (7 2) (8 4))

((1 5) (2 2) (3 4) (4 6) (5 8) (6 3) (7 1) (8 7))

((1 5) (2 2) (3 4) (4 7) (5 3) (6 8) (7 6) (8 1))

((1 5) (2 2) (3 6) (4 1) (5 7) (6 4) (7 8) (8 3))

((1 5) (2 2) (3 8) (4 1) (5 4) (6 7) (7 3) (8 6))

((1 5) (2 3) (3 1) (4 6) (5 8) (6 2) (7 4) (8 7))

((1 5) (2 3) (3 1) (4 7) (5 2) (6 8) (7 6) (8 4))

((1 5) (2 3) (3 8) (4 4) (5 7) (6 1) (7 6) (8 2))

((1 5) (2 7) (3 1) (4 3) (5 8) (6 6) (7 4) (8 2))

((1 5) (2 7) (3 1) (4 4) (5 2) (6 8) (7 6) (8 3))

((1 5) (2 7) (3 2) (4 4) (5 8) (6 1) (7 3) (8 6))

((1 5) (2 7) (3 2) (4 6) (5 3) (6 1) (7 4) (8 8))

((1 5) (2 7) (3 2) (4 6) (5 3) (6 1) (7 8) (8 4))

((1 5) (2 7) (3 4) (4 1) (5 3) (6 8) (7 6) (8 2))

((1 5) (2 8) (3 4) (4 1) (5 3) (6 6) (7 2) (8 7))

((1 5) (2 8) (3 4) (4 1) (5 7) (6 2) (7 6) (8 3))

((1 6) (2 1) (3 5) (4 2) (5 8) (6 3) (7 7) (8 4))

((1 6) (2 2) (3 7) (4 1) (5 3) (6 5) (7 8) (8 4))

((1 6) (2 2) (3 7) (4 1) (5 4) (6 8) (7 5) (8 3))

((1 6) (2 3) (3 1) (4 7) (5 5) (6 8) (7 2) (8 4))

((1 6) (2 3) (3 1) (4 8) (5 4) (6 2) (7 7) (8 5))

((1 6) (2 3) (3 1) (4 8) (5 5) (6 2) (7 4) (8 7))

((1 6) (2 3) (3 5) (4 7) (5 1) (6 4) (7 2) (8 8))

((1 6) (2 3) (3 5) (4 8) (5 1) (6 4) (7 2) (8 7))

((1 6) (2 3) (3 7) (4 2) (5 4) (6 8) (7 1) (8 5))

((1 6) (2 3) (3 7) (4 2) (5 8) (6 5) (7 1) (8 4))

((1 6) (2 3) (3 7) (4 4) (5 1) (6 8) (7 2) (8 5))

((1 6) (2 4) (3 1) (4 5) (5 8) (6 2) (7 7) (8 3))

((1 6) (2 4) (3 2) (4 8) (5 5) (6 7) (7 1) (8 3))

((1 6) (2 4) (3 7) (4 1) (5 3) (6 5) (7 2) (8 8))

((1 6) (2 4) (3 7) (4 1) (5 8) (6 2) (7 5) (8 3))

((1 6) (2 8) (3 2) (4 4) (5 1) (6 7) (7 5) (8 3))

((1 7) (2 1) (3 3) (4 8) (5 6) (6 4) (7 2) (8 5))

((1 7) (2 2) (3 4) (4 1) (5 8) (6 5) (7 3) (8 6))

((1 7) (2 2) (3 6) (4 3) (5 1) (6 4) (7 8) (8 5))

((1 7) (2 3) (3 1) (4 6) (5 8) (6 5) (7 2) (8 4))

((1 7) (2 3) (3 8) (4 2) (5 5) (6 1) (7 6) (8 4))

((1 7) (2 4) (3 2) (4 5) (5 8) (6 1) (7 3) (8 6))

((1 7) (2 4) (3 2) (4 8) (5 6) (6 1) (7 3) (8 5))

((1 7) (2 5) (3 3) (4 1) (5 6) (6 8) (7 2) (8 4))

((1 8) (2 2) (3 4) (4 1) (5 7) (6 5) (7 3) (8 6))

((1 8) (2 2) (3 5) (4 3) (5 1) (6 7) (7 4) (8 6))

((1 8) (2 3) (3 1) (4 6) (5 2) (6 5) (7 7) (8 4))

((1 8) (2 4) (3 1) (4 3) (5 6) (6 2) (7 7) (8 5))

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alexabc3000

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值