zoukankan      html  css  js  c++  java
  • 《sicp》八皇后谜题

    《sicp》八皇后谜题

    书中练习2.42.八皇后谜题问的是如何将八个皇后摆在国际象棋棋盘上,使得任意一个皇后都不能攻击另一个皇后(也就是说任意两个皇后都不能在同一行,同一列和同一对角线上).

    解题思想

    递归加模块化设计程序

    递归:解决这一谜题,可以使用递归的方法,每次在一列中放置一个皇后.

    • 1.已经放置好了前k-1列的所有皇后.
    • 2.第k列处理方法:
      • 1.将第k列的每一行都放置一个皇后.
      • 2.将第k列不满足条件的皇后过滤掉.

    数据结构

    每一个具体的解法用列表表示.列表的第一个元素表示第 8 列的皇后所在的行,而列表的第二个元素表示第 7 列的皇后所在的行,以此类推。
    例如

    可以表示为 (list 6 3 1 7 5 8 2 4) 。

    所有解法综合起来采用二维列表表示.(list (list 6 3 1 7 5 8 2 4) (list ...) (list ...) ...).
    列表内的每一个列表都代表一个具体的解法.

    scheme程序

    程序框架

    (define (queens board-size)
      (define (queen-cols k)
    	(if (= k 0)
    	   (list empty-board)
    	   (filter
    		  (lambda (positions)  (safe? k positions))
    		  (flatmap 
    		    (lambda (rest-of-queens)
    			  (map (lambda (new-row)
    					  (adjoin-position new-row k rest-of-queens))
    			        (enumerate-interval 1 board-size)))
                (queen-cols (- k 1))))))
       (queen-cols board-size))
    

    其中:
    queen-cols返回在棋盘前k列放置皇后的所有格局的序列
    filter是过滤掉不符合条件的解法
    flatmap是在前k-1列已放好的格局中,将第k列的每一个行中放入一个皇后
    rest-of-queens是在前k-1列放置k-1个皇后的一种方式

    过滤方式

    前k-1列已经放置好,所以只需检验第k行是否满足.
    从第k-1行开始,一行一行的检验三个条件,假设第i列的皇后放置位置为(i,y1),第k列的皇后放置为(k,y2)

    1.不在同一列,这个肯定满足,无需检验
    2.不在同一行,取出当前列的放置行数和第k列的放置行数相比,看是否相等,即y1 =? y2
    3.不在同一对角线上,分为两种情况,1:对角线斜率为1,做出过(i,y1)的斜率为1的直线,看与直线x=k,交点是否为(k,y2),如是,则不满足条件,2:斜率为-1,同上

    总程序

    (define (filter predicate sequence)
        (cond ((null? sequence) '())
    	      ((predicate (car sequence)) (cons (car sequence) (filter predicate (cdr sequence))))
    		  (else (filter predicate (cdr sequence)))))
    (define ( accumulate op initial sequence)
     (if (null? sequence)
         initial
    	 (op (car sequence)  (accumulate op initial (cdr sequence)))))
    (define (flatmap proc seq)
       (accumulate append '() (map proc seq)))
    (define (enumerate-interval low high) 
      (if (> low high)
          '()
    	  (cons low (enumerate-interval (+ low 1) high))))
    
    (define empty-board '())
    
    (define (safe? k positions)
       (define (noconflict? pk x list)
    	(cond ((= x 0 ) #t)
    	      ((or (= pk (car list))  (= pk ( + k (- (car list) x)))   (= pk ( - ( + (car list) x)  k )))   #f)
    		  (else (noconflict? pk (- x 1) (cdr list)))))
       (noconflict? (car positions) (- k 1) (cdr positions)))
    
    (define (adjoin-position new-row k rest-of-queens)
        (cons new-row rest-of-queens))
    
    (define (queens board-size)
      (define (queen-cols k)
    	(if (= k 0)
    	   (list empty-board)
    	   (filter
    		  (lambda (positions)  (safe? k positions))
    		  (flatmap 
    		    (lambda (rest-of-queens)
    			  (map (lambda (new-row)
    					  (adjoin-position new-row k rest-of-queens))
    			        (enumerate-interval 1 board-size)))
                (queen-cols (- k 1))))))
       (queen-cols board-size))
    
    

    结果

    1 ]=> (for-each (lambda (pos)
                        (begin
                            (display pos)
                            (newline)))
                    (queens 8))
    
    (4 2 7 3 6 8 5 1)
    (5 2 4 7 3 8 6 1)
    (3 5 2 8 6 4 7 1)
    (3 6 4 2 8 5 7 1)
    (5 7 1 3 8 6 4 2)
    (4 6 8 3 1 7 5 2)
    (3 6 8 1 4 7 5 2)
    (5 3 8 4 7 1 6 2)
    (5 7 4 1 3 8 6 2)
    (4 1 5 8 6 3 7 2)
    (3 6 4 1 8 5 7 2)
    (4 7 5 3 1 6 8 2)
    (6 4 2 8 5 7 1 3)
    (6 4 7 1 8 2 5 3)
    (1 7 4 6 8 2 5 3)
    (6 8 2 4 1 7 5 3)
    (6 2 7 1 4 8 5 3)
    (4 7 1 8 5 2 6 3)
    (5 8 4 1 7 2 6 3)
    (4 8 1 5 7 2 6 3)
    (2 7 5 8 1 4 6 3)
    (1 7 5 8 2 4 6 3)
    (2 5 7 4 1 8 6 3)
    (4 2 7 5 1 8 6 3)
    (5 7 1 4 2 8 6 3)
    (6 4 1 5 8 2 7 3)
    (5 1 4 6 8 2 7 3)
    (5 2 6 1 7 4 8 3)
    (6 3 7 2 8 5 1 4)
    (2 7 3 6 8 5 1 4)
    (7 3 1 6 8 5 2 4)
    (5 1 8 6 3 7 2 4)
    (1 5 8 6 3 7 2 4)
    (3 6 8 1 5 7 2 4)
    (6 3 1 7 5 8 2 4)
    (7 5 3 1 6 8 2 4)
    (7 3 8 2 5 1 6 4)
    (5 3 1 7 2 8 6 4)
    (2 5 7 1 3 8 6 4)
    (3 6 2 5 8 1 7 4)
    (6 1 5 2 8 3 7 4)
    (8 3 1 6 2 5 7 4)
    (2 8 6 1 3 5 7 4)
    (5 7 2 6 3 1 8 4)
    (3 6 2 7 5 1 8 4)
    (6 2 7 1 3 5 8 4)
    (3 7 2 8 6 4 1 5)
    (6 3 7 2 4 8 1 5)
    (4 2 7 3 6 8 1 5)
    (7 1 3 8 6 4 2 5)
    (1 6 8 3 7 4 2 5)
    (3 8 4 7 1 6 2 5)
    (6 3 7 4 1 8 2 5)
    (7 4 2 8 6 1 3 5)
    (4 6 8 2 7 1 3 5)
    (2 6 1 7 4 8 3 5)
    (2 4 6 8 3 1 7 5)
    (3 6 8 2 4 1 7 5)
    (6 3 1 8 4 2 7 5)
    (8 4 1 3 6 2 7 5)
    (4 8 1 3 6 2 7 5)
    (2 6 8 3 1 4 7 5)
    (7 2 6 3 1 4 8 5)
    (3 6 2 7 1 4 8 5)
    (4 7 3 8 2 5 1 6)
    (4 8 5 3 1 7 2 6)
    (3 5 8 4 1 7 2 6)
    (4 2 8 5 7 1 3 6)
    (5 7 2 4 8 1 3 6)
    (7 4 2 5 8 1 3 6)
    (8 2 4 1 7 5 3 6)
    (7 2 4 1 8 5 3 6)
    (5 1 8 4 2 7 3 6)
    (4 1 5 8 2 7 3 6)
    (5 2 8 1 4 7 3 6)
    (3 7 2 8 5 1 4 6)
    (3 1 7 5 8 2 4 6)
    (8 2 5 3 1 7 4 6)
    (3 5 2 8 1 7 4 6)
    (3 5 7 1 4 2 8 6)
    (5 2 4 6 8 3 1 7)
    (6 3 5 8 1 4 2 7)
    (5 8 4 1 3 6 2 7)
    (4 2 5 8 6 1 3 7)
    (4 6 1 5 2 8 3 7)
    (6 3 1 8 5 2 4 7)
    (5 3 1 6 8 2 4 7)
    (4 2 8 6 1 3 5 7)
    (6 3 5 7 1 4 2 8)
    (6 4 7 1 3 5 2 8)
    (4 7 5 2 6 1 3 8)
    (5 7 2 6 3 1 4 8)
    
  • 相关阅读:
    ExtJS5入门
    时间序列异常检测
    RNN实例
    数据清洗入门
    异常检测LOF
    sklearn异常检测demo
    孤立森林(Isolation Forest)
    WCF初见之SQL数据库的增删改查
    NHibernate与EF(Entity Framework)的区别
    解决IIS7虚拟目录出现HTTP 错误 500.19(由于权限不足而无法读取配置文件)的问题
  • 原文地址:https://www.cnblogs.com/battzion/p/4358171.html
Copyright © 2011-2022 走看看