明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
12
返回列表 发新帖
楼主: cabinsummer

[【风之影】] [风之影][Lisp大挑战第四季]皇后

  [复制链接]
发表于 2011-11-28 17:26 | 显示全部楼层
算法啥的没学过也不是很清楚,
直接一行一行递进计算就行了~!
用Lisp实现速度不是很快~
  1. ;;皇后计算(queen 行数 列数)
  2. (defun queen (rs cs / c lst nlst r)
  3.   ;;位置检查
  4.   (defun isOk (r c lst / a ok r+c r-c)
  5.     (setq r+c (+ r c))
  6.     (setq r-c (- r c))
  7.     (setq ok t)
  8.     (while lst
  9.       (setq a (car lst))
  10.       (setq lst (cdr lst))
  11.       (if (or (= c (cadr a))                ;列号相等
  12.               (= r+c (apply '+ a))        ;-45度对角线
  13.               (= r-c (apply '- a))        ;45度对角线
  14.           )
  15.         (setq ok  nil
  16.               lst nil
  17.         )
  18.       )
  19.     )
  20.     ok
  21.   )
  22.   ;;rs*cs(每行一个皇后)
  23.   (setq lst '(nil))
  24.   (setq r 1)
  25.   (repeat rs
  26.     (setq c 1)
  27.     (setq nLst nil)
  28.     (repeat cs
  29.       (foreach chd lst
  30.         (if (isOk r c chd)
  31.           (setq nLst (cons (cons (list r c) chd) nLst)) ;收集器
  32.         )
  33.       )
  34.       (setq c (1+ c))                        ;列号+1
  35.     )
  36.     (setq lst nLst)
  37.     (setq r (1+ r))                        ;行号+1
  38.   )
  39.   nLst
  40. )

评分

参与人数 1明经币 +1 收起 理由
cabinsummer + 1 赞一个!

查看全部评分

发表于 2011-11-28 17:27 | 显示全部楼层
先写一个求所有解得快速方法
  1. ;;;by:lihuaili 2011.11.28
  2. ;;;参考了网上的一些资料

  3. ;;;构造行列(确定当前所处位置)
  4. (defun make-queen (row col) (list row col))
  5. ;;;得到行号
  6. (defun get-row (queen) (car queen))
  7. ;;;得到列号
  8. (defun get-col (queen) (cadr queen))
  9. ;;;判断是否在同一行
  10. (defun same-row? (nq oq) (= (get-row nq) (get-row oq)))
  11. ;;;判断是否在同一列
  12. (defun same-col? (nq oq) (= (get-col nq) (get-col oq)))
  13. ;;;判断是否在同一对角线上
  14. (defun same-diag? (nq oq)
  15.   (= (abs (- (get-row nq) (get-row oq)))
  16.      (abs (- (get-col nq) (get-col oq)))
  17.   ) ;_ 结束=
  18. ) ;_ 结束defun

  19. ;;;几个位置判断(是否受到攻击)
  20. (defun attacks?  (nq oq)
  21.   (or (same-row? nq oq) (same-col? nq oq) (same-diag? nq oq))
  22. ) ;_ 结束defun

  23. ;;;判断皇后是否安全
  24. (defun safe? (target queens)
  25.   (cond  ((null queens) T)
  26.   ((attacks? target (car queens)) nil)
  27.   (T (safe? target (cdr queens)))
  28.   ) ;_ 结束cond
  29. ) ;_ 结束defun

  30. ;解算棋盘阶数为sz的皇后问题(从书写上看是递归法,实际是一种迭代法).
  31. (defun solve (sz)
  32.   (defun s-rec (sz x y pos sols)
  33.     (cond
  34. ; 如果先通过了最后一列,表示有了一个解.
  35. ; (顺便说一句,反方向是因为pos是从后向前建立的.)
  36.       ((> x sz) (cons (reverse pos) sols))
  37. ; 如果先通过了最后一行,就表示失败.
  38.       ((> y sz) sols)
  39.   ;如果皇后安全, 继续.
  40.       ((safe? (make-queen x y) pos)
  41. ; 这是一种回溯调用. 执行一次就完成一次内部调用。
  42.        (s-rec sz
  43.         x
  44.         (+ y 1)
  45.         pos
  46. ; 运行下一列第一行,如果有任何解决方案的结果,
  47. ; 他们需要传送到回溯调用
  48.         (s-rec sz
  49.          (+ x 1)
  50.          1
  51. ; 当考虑加入这个王后下一列的位置
  52.          (cons (make-queen x y) pos)
  53.          sols
  54.         ) ;_ 结束s-rec
  55.        ) ;_ 结束s-rec
  56.       )
  57.   ; 如果皇后不安全, 移到下一行.
  58.       (T (s-rec sz x (+ y 1) pos sols))
  59.     ) ;_ 结束cond
  60.   ) ;_ 结束defun
  61.   ; 开始递归.
  62.   (s-rec sz 1 1 '() '())
  63. ) ;_ 结束defun

  64. ;;;显示n阶计算方法
  65. (defun show-queens (n)
  66.   (princ "\n")
  67.   (princ (strcat "阶次为 "
  68.      (itoa n)
  69.      " 的皇后问题共有:***"
  70.      (itoa (length (solve n)))
  71.      "***解法."
  72.    ) ;_ 结束list
  73.   ) ;_ 结束display
  74.   (princ)
  75. ) ;_ 结束defun
  76. (mapcar 'show-queens '(1 2 3 4 5 6 7 8 9 10))


  77. ;;;(setq alllst (solve 8))

评分

参与人数 1明经币 +1 收起 理由
cabinsummer + 1 很给力!

查看全部评分

 楼主| 发表于 2011-11-28 19:43 | 显示全部楼层
本帖最后由 cabinsummer 于 2011-11-28 19:45 编辑
xianaihua 发表于 2011-11-28 17:27
先写一个求所有解得快速方法


速度很快,可惜没有输出解,也没有求独立解

点评

最后一行,便是;;;(setq alllst (solve 8))  发表于 2011-11-28 19:56
发表于 2011-11-28 21:39 | 显示全部楼层
就是厉害,无论如何都要顶啦。
发表于 2011-11-29 19:24 | 显示全部楼层
皇后问题完整版
  1. ;;;构造行列(确定当前所处位置)
  2. (defun make-queen (row col) (list row col))
  3. ;;;得到行号
  4. (defun get-row (queen) (car queen))
  5. ;;;得到列号
  6. (defun get-col (queen) (cadr queen))
  7. ;;;判断是否在同一行
  8. (defun same-row? (nq oq) (= (get-row nq) (get-row oq)))
  9. ;;;判断是否在同一列
  10. (defun same-col? (nq oq) (= (get-col nq) (get-col oq)))
  11. ;;;判断是否在同一对角线上
  12. (defun same-diag? (nq oq)
  13.   (= (abs (- (get-row nq) (get-row oq)))
  14.      (abs (- (get-col nq) (get-col oq)))
  15.   ) ;_ 结束=
  16. ) ;_ 结束defun

  17. ;;;几个位置判断(是否受到攻击)
  18. (defun attacks?  (nq oq)
  19.   (or (same-row? nq oq) (same-col? nq oq) (same-diag? nq oq))
  20. ) ;_ 结束defun

  21. ;;;判断皇后是否安全
  22. (defun safe? (target queens)
  23.   (cond  ((null queens) T)
  24.   ((attacks? target (car queens)) nil)
  25.   (T (safe? target (cdr queens)))
  26.   ) ;_ 结束cond
  27. ) ;_ 结束defun

  28. ;解算棋盘阶数为sz的皇后问题(从书写上看是递归法,实际是一种迭代法).
  29. (defun solve (sz)
  30.   (defun s-rec (sz x y pos sols)
  31.     (cond
  32. ; 如果先通过了最后一列,表示有了一个解.
  33. ; (顺便说一句,反方向是因为pos是从后向前建立的.)
  34.       ((> x sz) (cons (reverse pos) sols))
  35. ; 如果先通过了最后一行,就表示失败.
  36.       ((> y sz) sols)
  37.   ;如果皇后安全, 继续.
  38.       ((safe? (make-queen x y) pos)
  39. ; 这是一种回溯调用. 执行一次就完成一次内部调用。
  40.        (s-rec sz
  41.         x
  42.         (+ y 1)
  43.         pos
  44. ; 运行下一列第一行,如果有任何解决方案的结果,
  45. ; 他们需要传送到回溯调用
  46.         (s-rec sz
  47.          (+ x 1)
  48.          1
  49. ; 当考虑加入这个王后下一列的位置
  50.          (cons (make-queen x y) pos)
  51.          sols
  52.         ) ;_ 结束s-rec
  53.        ) ;_ 结束s-rec
  54.       )
  55.   ; 如果皇后不安全, 移到下一行.
  56.       (T (s-rec sz x (+ y 1) pos sols))
  57.     ) ;_ 结束cond
  58.   ) ;_ 结束defun
  59.   ; 开始递归.
  60.   (s-rec sz 1 1 '() '())
  61. ) ;_ 结束defun

  62. ;;;--------------------------------中间内容参考了狂刀的方法(有时间再优化)----------------------------------------
  63. ;;;;表的转置
  64. (defun inv(lst n / res)
  65. (setq i 1)
  66. (repeat n (setq res (cons (1+ (vl-position i lst)) res) i (1+ i)))
  67. (reverse res)
  68. )

  69. ;;;;表在水平方向镜像
  70. (defun mirrorx(lst n)
  71. (mapcar '(lambda(x) (- (1+ n) x)) lst)
  72. )
  73. ;;;;表在垂直方向镜像
  74. (defun mirrory(lst) (reverse lst))
  75. ;;;;表的90度转置
  76. (defun rot90(lst n) (mirrorx (inv lst n) n))
  77. ;;;;所有9种同构的情况
  78. (defun allsame (lst n / res l1 l2 l3)
  79.   (setq  l1  (rot90 lst n)
  80.   res (cons (mirrory l1) (cons (mirrorx l1 n) (cons l1 res)))
  81.   ) ;_ 结束setq
  82.   (setq  l2  (rot90 l1 n)
  83.   res (cons (mirrory l2) (cons (mirrorx l2 n) (cons l2 res)))
  84.   ) ;_ 结束setq
  85.   (setq  l3  (rot90 l2 n)
  86.   res (cons (mirrory l1) (cons (mirrorx l3 n) (cons l3 res)))
  87.   ) ;_ 结束setq
  88.   res
  89. ) ;_ 结束defun


  90. ;;;;处理8皇后解中的重复情况
  91. (defun removeallsame(lst n / res a1)
  92. (while (car lst)
  93.    (setq res (cons (setq a1 (car lst)) res)
  94.          lst (removebfroma (cdr lst) (allsame a1 n)))
  95. )
  96. res
  97. )
  98. ;;;;把lsta中有lstb的元素删除
  99. (defun removebfroma(lsta lstb / x)
  100. (foreach x lstb (setq lsta (vl-remove x lsta)))
  101. )
  102. ;;;--------------------------------中间内容参考了狂刀的方法----------------------------------------

  103. ;;;表的转换
  104. (defun lst_convert (l)
  105.   (if (cdaar l)
  106.     (mapcar (function
  107.         (lambda (a) (mapcar (function (lambda (x) (nth 1 x))) a))
  108.       ) ;_ 结束function
  109.       l
  110.     ) ;_ 结束cons
  111.   ) ;_ 结束if
  112. ) ;_ 结束defun
  113. (defun c:test (/ alllst final)
  114.   ;数字8可根据阶数进行调整
  115.   (setq  alllst (solve 8)
  116.   alllst (reverse (lst_convert alllst))
  117.   unique_solution  (removeallsame alllst 8)
  118.   ) ;_ 结束setq
  119.   (foreach x (reverse unique_solution) (princ "\n") (princ x))
  120.   (princ)
  121. ) ;_ 结束defun
  122. ;;;(1 5 8 6 3 7 2 4)
  123. ;;;(1 6 8 3 7 4 2 5)
  124. ;;;(2 4 6 8 3 1 7 5)
  125. ;;;(2 5 7 1 3 8 6 4)
  126. ;;;(2 5 7 4 1 8 6 3)
  127. ;;;(2 6 1 7 4 8 3 5)
  128. ;;;(2 6 8 3 1 4 7 5)
  129. ;;;(2 7 3 6 8 5 1 4)
  130. ;;;(2 7 5 8 1 4 6 3)
  131. ;;;(3 5 2 8 1 7 4 6)
  132. ;;;(3 5 8 4 1 7 2 6)
  133. ;;;(3 6 2 5 8 1 7 4)


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

点评

真高人也  发表于 2011-11-29 20:07

评分

参与人数 2明经币 +4 收起 理由
仲文玉 + 1 很给力!
Gu_xl + 3 很给力!

查看全部评分

发表于 2011-11-29 23:56 | 显示全部楼层
本帖最后由 飞诗(fsxm) 于 2011-11-30 12:45 编辑

补上皇后去重计算!做一个简单的优化,速度非常快了哦!
去重模块引用的是qjchen的代码,谢了!并针对性做了少量修改,嘿嘿

  1. ;;利用对称性仅计算一半
  2. (defun fs:queen2 (n / c lst nlst r NotOk n/2)
  3.   (defun NotOk (r c lst / cc rr err r+c r-c) ;位置检查
  4.     (setq rr  r
  5.    r+c (+ r c)
  6.    r-c (- r c)
  7.     )
  8.     (while lst
  9.       (setq cc (car lst))
  10.       (setq lst (cdr lst))
  11.       (setq rr (1- rr))
  12.       (if (or (= c cc)   ;列号相等
  13.        (= r+c (+ rr cc))  ;-45度对角线
  14.        (= r-c (- rr cc))  ;45度对角线
  15.    )
  16. (setq err t
  17.        lst nil
  18. )
  19.       )
  20.     )
  21.     err
  22.   )
  23.   (setq n/2 (/ n 2))
  24.   (or (zerop (rem n 2)) (setq n/2 (1+ n/2)))
  25.   (setq c 0)
  26.   (repeat n/2 (setq lst (cons (list c) lst)) (setq c (1+ c)))
  27.   (setq r 0)
  28.   (repeat (1- n)
  29.     (setq c 0)
  30.     (setq nLst nil)
  31.     (repeat n
  32.       (foreach chd lst
  33. (or (NotOk r c chd)
  34.      (setq nLst (cons (cons c chd) nLst)) ;收集器
  35. )
  36.       )
  37.       (setq c (1+ c))   ;列号+1
  38.     )
  39.     (setq lst nLst)
  40.     (setq r (1+ r))   ;行号+1
  41.   )
  42.   nLst
  43. )
  44. ;;;;表的转置
  45. (defun q:queen:inv (lst / res)
  46.   (setq i 0)
  47.   (repeat (length lst)
  48.     (setq res (cons (vl-position i lst) res)
  49.    i   (1+ i)
  50.     )
  51.   )
  52.   (reverse res)
  53. )
  54. ;;;;表的y轴翻转
  55. (defun q:queen:mirrory (lst)
  56.   (mapcar '(lambda (x) (- (length lst) 1 x)) lst)
  57. )
  58. ;;;;表的x轴翻转
  59. (setq q:queen:mirrorx reverse)
  60. ;;;;表的90度转置
  61. (defun q:queen:rot90 (lst)
  62.   (q:queen:mirrory (q:queen:inv lst))
  63. )
  64. (defun q:queen:allsame (lst / l1 l2 l3 l4 l5 l6 l7)
  65.   (list (setq l1 (q:queen:mirrorx lst))
  66. (setq l2 (q:queen:mirrory lst))
  67. (setq l3 (q:queen:mirrorx l2))
  68. (setq l4 (q:queen:rot90 lst))
  69. (setq l5 (q:queen:mirrorx l4))
  70. (setq l6 (q:queen:mirrory l4))
  71. (setq l7 (q:queen:mirrorx l6))
  72.   )
  73. )
  74. ;;;;处理8皇后解中的重复情况
  75. (defun q:queen:removeallsame (lst / res a1)
  76.   (setq n (length (car lst)))
  77.   (setq n/2 (/ n 2))
  78.   (or (zerop (rem n 2)) (setq n/2 (1+ n/2)))
  79.   (while (setq a1 (car lst))
  80.     (setq res (cons a1 res)
  81.    lst (q:list:removebfroma
  82.   (cdr lst)
  83.   (q:queen:allsame a1)
  84.   n/2
  85.        )
  86.     )
  87.   )
  88.   res
  89. )
  90. ;;;;把lsta中有lstb的元素删除
  91. (defun q:list:removebfroma (lsta lstb n / x)
  92.   (foreach x lstb
  93.     (if (< (last x) n)   ;针对性优化
  94.       (setq lsta (vl-remove x lsta))
  95.     )
  96.   )
  97.   lsta
  98. )
  99. ;;皇后问题去重完整版
  100. (defun c:test ()
  101.   (foreach a (q:queen:removeallsame (fs:queen2 8))
  102.     (princ "\n")
  103.     (princ a)
  104.   )
  105.   (princ)
  106. )

点评

真的是飞快!给力!  发表于 2011-12-1 22:55

评分

参与人数 1明经币 +3 收起 理由
Gu_xl + 3 赞一个!

查看全部评分

发表于 2011-12-3 00:48 | 显示全部楼层
本帖最后由 xyp1964 于 2011-12-3 10:41 编辑

'(((1 1) (2 7) (3 4) (4 6) (5 8) (6 2) (7 5) (8 3))
  ((1 2) (2 4) (3 6) (4 8) (5 3) (6 1) (7 7) (8 5))
  ((1 3) (2 5) (3 7) (4 1) (5 4) (6 2) (7 8) (8 6))
  ((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 8) (4 6) (5 1) (6 3) (7 5) (8 7))
  ((1 4) (2 2) (3 7) (4 5) (5 1) (6 8) (7 6) (8 3))
  ((1 4) (2 6) (3 1) (4 5) (5 2) (6 8) (7 3) (8 7))
  ((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 2) (3 4) (4 7) (5 3) (6 8) (7 6) (8 1))
  ((1 6) (2 4) (3 1) (4 5) (5 8) (6 2) (7 7) (8 3))
  ((1 6) (2 3) (3 5) (4 7) (5 1) (6 4) (7 2) (8 8))
  ((1 7) (2 2) (3 4) (4 1) (5 8) (6 5) (7 3) (8 6))
)——不知道哪个重复了?


发表于 2017-8-3 10:44 | 显示全部楼层

楼主很给力!
发表于 2017-8-3 10:47 | 显示全部楼层
飞诗(fsxm) 发表于 2011-11-29 23:56
补上皇后去重计算!做一个简单的优化,速度非常快了哦!
去重模块引用的是qjchen的代码,谢了!并针对性做 ...

飞诗太牛了!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-4-26 12:51 , Processed in 0.433659 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表