python8皇后不攻击问题_Python八皇后问题(落最后一颗子)
最近在看Python基礎,遇到了八皇后問題,看得整個人暈暈乎乎,甚至開始懷疑人生。
問題是在一個8*8的國際象棋棋盤上擺放8個皇后,問題一是找出一個解,問題二是問有多少個解。這里我把我自己的理解寫出來,只針對最后一個落子的情況,不涉及遞歸,希望能有所幫助。
首先定義沖突函數:
def conflict(state,nextQueenColumnIndex):
#state是當前已經放置的皇后在棋盤上面的列索引組成的元組,nextQueenColumnIndex是將要放置的下一個皇后(簡稱A)的列索引,這里關鍵問題在于要將A與之前放置的皇后一一比對,找出是否會被吃掉(存在沖突),因此需要做循環,之前已經放置的皇后個數當然是len(state),因為索引是從0開始算的,所以已經放置的最后一個皇后的行索引為len(state)-1,因此A的行索引為len(state)。
nextQueenRowIndex=len(state)
for everyqueen in range(nextQueenRowIndex):
#注意range右邊是開區間,取出每一行等行索引。
if abs(state[everyqueen]-nextQueenColumnIndex) in (0,nextQueenRowIndex-everyqueen):
#,這里需要明白的是,假如state為(0,1,2,3),那么代表的是第一行皇后列索引為0,第二行皇后列索引為1,以此類推。那么state[everyqueen]實際上就是取出了每一行皇后的列索引。
return True
return False
#這里有兩個關鍵點,第一、是abs(state[everyqueen]-nextQueenColumn)==0檢查A是否與其他皇后在同一列,abs(state[everyqueen]-nextQueenColumn)==nextQueenRowIndex-everyqueen檢查A是否與其他皇后在一條斜線上(對角線),其實就是行索引-行索引==列索引-列索引就代表在一條斜線上面。第二、注意return False是與for對齊的,因為只要存在沖突就會return True,當for循環執行完后都沒有return的話,那么就會執行到return False,也即不存在沖突,那么A落在這個棋盤點就是對的!
以上,沖突函數就寫完了。
然后,我們來寫主函數
def MyQueen(state,queencount):
#state依然代表當前已經放置的皇后在棋盤上面的列索引組成的元組,queencount代表皇后的總數(包括已有的和準備下的),下面討論的是最簡單的一種情況,就是已知棋盤的狀態,需要下最后一顆子。
if len(state)==queencount-1#len(state)代表已落子的個數,如果與總數-1相等的話,那么我們要下的必然是最后一顆子。這最后一顆子怎么下?當然是要與前面的每一行的皇后做沖突比對,好在我們的沖突函數已經寫好了,可以直接用。
for n in range(queencount):取出每一列的列索引,其實就是說在當前棋盤狀態下,落子第一列行不行?落子第二列行不行?。。。落子最后一列行不行?其實這里的range(queencount)只是方便我們按次序取出1,2,3,4,5。。。,因為要注意這道題的前提是棋盤是真方形,是在N*N的棋盤上面放置N個皇后,因此我們這里直接用queencount比較方便,當然如果你已經知道棋盤大小為8或者16直接用range(8)或者range(16)也行。
if not conflict(state,n):#n就是要落子的列索引
print(n)
#輸出的n就是A的列索引了,也即最后一個皇后落子的棋盤列索引位置。
Over,上面就討論了八皇后問題中落最后一顆子的簡單情況,當然是用這個函數的前提是要知道棋盤的當前落子狀態及皇后的總數,我目前剛把這個看懂,寫出來,也為自己加深印象,后面的還要繼續學習。。。
總結
以上是生活随笔為你收集整理的python8皇后不攻击问题_Python八皇后问题(落最后一颗子)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一般将来时语法课教案_速看,如何在考场写
- 下一篇: python下载matplotlib.f