兩種方法python
第二種方法解釋
第一層for表示第一個皇后的位置,而後第二層for表示,循環8次,表示其餘皇后的位置,最後限制次數,是if判斷app
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())))