python數據結構學習筆記-2016-11-12-03-八皇后問題

        10.5 八皇后問題

        問題描述

        在國際象棋8 × 8的棋盤上放置8個皇后,使得每一個皇后都不能被另一個皇后攻擊(皇后可在橫豎斜走任意多步)。

        10.5.1 解決四皇后問題

         先將問題規模縮小,我們先來解決四皇后問題。

         在4 × 4的棋盤上,皇后可以在橫豎斜三個方向上走任意多步,所以這四個皇后必然處於不同行、不同列。

         我們現在第一列放置皇后,先從(0, 0)開始:


         再在第二列放置第二個皇后,可供選擇的地方有(2, 1)和(3, 1)。放在(2, 1)和(3, 1)的結果如下所示:

     

        如果選擇(2, 1),則第三列根本就無法再放下一個皇后,從而使得剩下的兩個皇后就必須得在第四列,而這又會造成互相攻擊,所以不能放在(2, 1),選擇(3, 1)。

        第三個皇后就顯然只能是放在(1, 2)了,如下所示:


        這樣一來,又沒有辦法在第四列放置最後一個皇后了。所以,只能推到從來,從第一列開始,將第一個皇后放置在(1, 0)。


       之後還是一樣的過程。


       四皇后問題有兩個解。


       10.5.2 設計解決方案

        這個實現包括兩個方面,一個是棋盤,另外一個是尋找解決方法的遞歸函數

        棋盤定義

  • QueensBorad(n):創建n× n的空棋盤;
  • size():返回棋盤的大小;
  • numQueens():返回當前放置在棋盤的皇后數;
  • unguarded(row, col):返回該位置是否處於當前的所有皇后的攻擊 範圍;
  • placeQueen(row, col):在該位置上放置皇后;
  • removeQueen(row, col):將該位置上皇后移除;
  • reset():將所有皇后移除,使棋盤返回初始狀態;
  • draw():打印棋盤。
        函數的實現如下,它的目的是在一列中,找出皇后放置位置。先確定所有皇后是否都就位了。如果沒有,就繼續在col列找正確位置,如果與某個位置不處於當前所有皇后的攻擊範圍內,就將皇后放置在此處,再在下一列中找出正確放置位置,如果都處於當前所有皇后的攻擊範圍,則說明上一列的皇后放置位置有問題,返回上一列繼續尋找皇后的放置位置。
#-*-coding: utf-8-*-

# N皇后問題

def solveNQueens(board, col):
    if board.numQueens() == board.size(): # 確定所有皇后是否都放置好了
        return True
    else:
        # 在這一列找出正確的位置放置皇后
        for row in range(board.size()):
            if board.unguarded(row, col):
                board.placeQueen(row, col):
                if board.solveNQueens(board, col+1):
                    return True
                else:
                    boar.removeQueen(row, col)
        return False # 沒有找到正確位置,則會回溯到上一列的皇后放置上來。

          棋盤的實現

          棋盤的實現,可以使用二維數組,也可以使用一維數組。數組的索引就是每一列,而內容則是該列上的每一行,因此,其儲存的是皇后的放置位置。

          我們先保證了在豎直方向上,皇后不能攻擊。對於新的一列,我們可以查看在水平方向上是否有皇后存在,如果沒有就再在左上和左下方向上找。

      

        

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章