您的位置:首页 > 编程语言 > Python开发

八皇后问题之python和scheme实现

2014-03-08 19:09 531 查看
今天看python的书籍,看到递归时又遇到递归中的一个老问题—八皇后问题,书里给出了python的实现版本,具体如下:

def conflict(state,nextX):

    nextY = len(state)

    for i in range(nextY):

        if abs(state[i]-nextX) in (0,nextY-i):

            return True

    return False

def queens(num,state):

    for pos in range(num):

        if not conflict(state,pos):

            if len(state) == num-1:

                yield (pos,)

            else:

                for result in queens(num,state + (pos,)):

                    yield (pos,) + result

这是我到现在为止看到的程序最简短的答案了,看来python的语言表达力果然了的,这里生成器的使用使得最终数据的收集工作变的很直接,生成器是逐渐产生结果的复杂递归算法的理想实现工具,使用生成器所有的递归调用只需要创建自己的yield部分。

学习SICP的时候,嵌套映射时候也提到了八皇后问题,文中给出了程序的模版,留了3个函数自己实现,主要时判断是否冲突,于上面conflict的功能时一样的,只是python这边因为以下标作为皇后所在的行,所以传递的参数只需要一个,而Scheme中由于时通过嵌套的map,所以构造的数据结构是一个两个元素组成的列表,程序也是全程操作所有的嵌套列表,这也就导致的搜索的空间很大,程序代码如下:

#!/usr/bin/guile -s

!#

(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))

 

 ; Adds a new row to the board (list)

 (define (adjoin-position new-row k rest-of-queens)

   (cons new-row rest-of-queens))

 

 (define empty-board '())

 

 ; current queen is at start of positions, check it against rest of the queens

 (define (safe? k positions)

   ; current queen is at start of positions list

   (define queenPos (car positions))

    

   ; top and bot are used to check for diagonal entries

   (define (safe-iter top bot remain)

     (cond ((null? remain)

            #t)

           ; Checks for same row and diagonals

           ((or (= (car remain) queenPos)

                (= (car remain) top)

                (= (car remain) bot))

            #f)

           (else

            (safe-iter (- top 1) (+ bot 1) (cdr remain)))))

   (safe-iter (- queenPos 1) (+ queenPos 1) (cdr positions)))

 

 ; Helper procedures

 (define (flatmap proc seq)

   (accumulate append '() (map proc seq)))

 

 (define (accumulate op init seq)

   (if (null? seq)

       init

       (op (car seq)

           (accumulate op init (cdr seq)))))

 

 (define (enumerate-interval low high)

   (if (> low high)

       '()

       (cons low (enumerate-interval (+ low 1) high))))

这里操作的数据结构确实没有python中选择的好,而且由于没有采用尾递归,都是函数调用,导致需要很大的栈空间,到数据给到8时就会出现Stack overflow。可能书上给的这个模版是为了说明嵌套映射吧,所以没有采用python解决问题上的思路,更是因为这里Scheme采用了函数式的编程思维,这里不采用赋值,任何有赋值的式子都是命令式的思维方式,而Scheme的思维方式导致程序最终是如此。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python 八皇后 scheme