We should cherish now

python生成器2

  生成器的经典使用,八皇后算法,何谓八皇后,简单的说就是有一个棋盘和8个要放到上面的皇后,条件是,皇后之间不能形成威胁,解读不能形成威胁,就是皇后之间不能出现两两在同一水平线、同一竖直线、正对角的关系。

  在这里我们用元组的方式存储皇后的信息,每个元组中的元素,对应的是皇后的位置,index表示行,数值表示列,比如state[1]=2,表示,第一行的皇后在第三列这个位置上。这里我们是从0开始计数的,首先我们来看看限制条件,针对限制条件可以定义一个check函数:

1 def check(state,nextx):
2     nextY=len(state)
3     for i in range(nextY):
4         if abs(state[i]-nextx) in (0,nextY-i):
5             return  True
6     return False

  参数中nextX表示下一个皇后的位置,state是一个元组表示当前已经放上去的皇后信息,nextY表示列数,也就是一共已经放上去了多少个皇后,这里用排除法,将当前皇后的位置,依次与历史上放上去的皇后的位置做比较,如果她们的位置在同一水平距离也就是列相同,或者是在垂直对角的位置上,就返回True,表示nextX不是合适的位置,表示式:

abs(state[i]-nextx) in (0,nextY-i)
两皇后列的位置相比较,如果列位置为0,或者列位置比较值跟行位置比较值相同(正对角关系),就返回True,否则返回false
演算,我们先从最基本的完成开始,我们先从少的来,假设是四个皇后如果只剩下最后一个皇后还没有放进去,最后一个皇后能根据其他皇后的位置找到自己能占据的所有位置,也许会没有,我们用一个函数来找出:
1 def queens(num,state):
2     if len(state)==num-1:
3         for pos in range(num):
4             if not conflict(state,pos):
5                 yield pos

  我们假设前面三个皇后分别存放的位置是,1,3,0,那么state=(1,3,0),一个应该是四个皇后num=4,经过计算可以很快的找出第四个皇后的位置是2

  八皇后算法实现,结合递归使用,因为一开始我们并不知道有多少个皇后已经放上去了,程序从前面的皇后得到包含位置信息的元组,并且为后面的皇后提供当前皇后的位置信息,接下来我们要做的就是把当前的位置信息都添加到元组信息中,并传递给后面的皇后,所以要在以前的基础修改queens函数,代码实现:

1 def queens_new(num=8,state=()):
2     for pos in range(num):
3         if not conflict(state,pos):
4             if len(state)==num-1:
5                 yield (pos,)
6             else:
7                 for result in queens_new(num,state+(pos,)):
8                     yield (pos,)+result

  使用list(queens_new(8)),可以列表所有八皇后可以放置的解决方案。

  打印八皇后位置:

 

def printLocation(solution):
    def line(pos,length=len(solution)):
        return '. '*(pos)+'X'+'. '*(length-pos-1)
    for pos in solution:
        print line(pos)

import random
printLocation(random.choice(list(queens_new(8))))

  

posted on 2014-08-02 17:06  Alai@2014  阅读(196)  评论(0编辑  收藏  举报