python八皇后問題

兩種方法python

第二種方法解釋
第一層for表示第一個皇后的位置,而後第二層for表示,循環8次,表示其餘皇后的位置,最後限制次數,是if判斷app

python八皇后問題

def conflict(state,nextx):
    '定義衝突函數,state爲元組,nextx爲下一個皇后的水平位置,nexty爲下一個皇后的垂直位置'
    nexty = len(state)
    for i in range(nexty):
        if abs(state[i]-nextx) in (0,nexty-i):#若下一個皇后和前面的皇后列相同或者在一條對角線上,則衝突
            return True
    return False

def queens(num=8,state=()):
    '八皇后問題,這裏num表示規模'
    for pos in range(num):
        if not conflict(state,pos ):#位置不衝突
            if len(state) == num - 1:#如果最後一個皇后,則返回該位置
                yield (pos,)
            else:#若不是最後一個皇后,則將該位置返回到state元組並傳給後面的皇后
                for result in queens(num,state + (pos,)):
                    yield (pos,) + result

l = 0
for i in queens(num=8,state=()):
    print i
    l += 1
print l
from itertools import permutations
for vec in permutations(range(8)):
    if (8 == len(set(vec[i]+i for i in range(8)))== len(set(vec[i]-i for i in range(8)))):
        print vec

global col                                  #定義一些全局變量
global row
global pos_diag
global nag_diag
global count

def output():   
    ''' 輸出一種有效結果
    '''
    global count
    print row
    count += 1

def do_queen(i):
    ''' 生成全部正確解
    @param i: 皇后的數目
    '''
    for j in range(0, 8):                   #依次嘗試0~7位置
        if col[j] == 1 and pos_diag[i-j+7] == 1 and nag_diag[i+j] == 1:
            #若該行,正對角線,負對角線上都沒有皇后,則放入i皇后
            row[i] = j
            col[j] = 0                      #調整各個列表狀態
            pos_diag[i-j+7] = 0
            nag_diag[i+j] = 0
            if i < 7:
                do_queen(i+1)               #可遞增或遞減
            else:
                output()                    #產生一個結果,輸出
            col[j] = 1                      #恢復各個列表狀態爲以前的
            pos_diag[i-j+7] = 1
            nag_diag[i+j] = 1

if __name__ == '__main__':
    col = []                                #矩陣列的列表,存儲皇后所在列,若該列沒有皇后,則相應置爲1,反之則0
    row = []                                #矩陣行的列表,存放每行皇后所在的列位置,隨着程序的執行,在不斷的變化中,之間輸出結果
    pos_diag = []                           #正對角線,i-j恆定,-7~0~7,而且b(i)+7統一到0~14
    nag_diag = []                           #負對角線,i+j恆定,0~14
    count = 0
    for index in range(0, 8):               #一些初始化工做
        col.append(1)
        row.append(0)
    for index in range(0, 15):
        pos_diag.append(1)
        nag_diag.append(1)
    do_queen(0)
    #開始遞歸,先放一個,依次遞增,反過來,從7開始遞減也可
    print 'Totally have %d solutions!' % count

import random
#衝突檢查,在定義state時,採用state來標誌每一個皇后的位置,其中索引用來表示橫座標,基對應的值表示縱座標,例如: state[0]=3,表示該皇后位於第1行的第4列上
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

#爲了直觀表現棋盤,用X表示每一個皇后的位置
def prettyprint(solution):
    def line(pos, length=len(solution)):
        return '. ' * (pos) + 'X ' + '. '*(length-pos-1)
    for pos in solution:
        print line(pos)

if __name__ == "__main__":
    prettyprint(random.choice(list(queens(8))))

def queens(num=8, state=()):
    for pos in range(num):        
        if not conflict((), pos):
            queens(num, state+(pos,)) #遞歸調用,將此行展開

def conflict(state,nextx):
    '定義衝突函數,state爲元組,nextx爲下一個皇后的水平位置,nexty爲下一個皇后的垂直位置'
    nexty = len(state) 
    for i in range(nexty):
        if abs(state[i]-nextx) in (0,nexty-i):#若下一個皇后和前面的皇后列相同或者在一條對角線上,則衝突
            return True
    return False

def queens(num=8,state=()):
    '八皇后問題,這裏num表示規模'
    for pos in range(num):
        if not conflict(state,pos):#位置不衝突
            if len(state) == num - 1:#如果最後一個皇后,則返回該位置
                yield (pos,)
            else:#若不是最後一個皇后,則將該位置返回到state元組並傳給後面的皇后
                for result in queens(num,state + (pos,)):
                    yield (pos,) + result

def prettyp(solution):
    '打印函數'
    def line(pos,length = len(solution)):
        '打印一行,皇后位置用X填充,其他用0填充'
        return 'O'*(pos)+'X'+'O'*(length-pos-1)
    for pos in solution:
        print(line(pos))                   

import random
#隨機打印一種
prettyp(random.choice(list(queens(8))))

# -*- coding: utf-8 -*-
#python默認爲ascii編碼,中文編碼能夠用utf-8
import random
#隨機模塊

def conflict(state,col):
    #衝突函數,row爲行,col爲列
    row=len(state)
    for i in range(row):
        if abs(state[i]-col) in (0,row-i):#重要語句
            return True
    return False

def queens(num=8,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

def queenprint(solution):
    #打印函數
    def line(pos,length=len(solution)):
        return '. '*(pos)+'X '+'. '*(length-pos-1)
    for pos in solution:
        print line(pos)

for solution in list(queens(8)):
    print solution

print '  total number is '+str(len(list(queens())))
print '  one of the range is:\n'
queenprint(random.choice(list(queens())))
相關文章
相關標籤/搜索