Python は 8 クイーン問題と発生する問題を実装します (深さ優先 bfs と幅優先 dfs を使用)

人工知能コースのちょっとした宿題で Python に慣れていないので、午後いっぱい書いたのでここで共有します。その中で dfs は再帰を使用します。
C++ または Java を使用すると、より高速になるはずですが、Python を使用すると多くの落とし穴に遭遇します

1. コードの実装

print("===============================================")




class Point:
    def __init__(self, x, y, board):
        self.x=x
        self.y=y
        self.board=board


def BFS(n):
    n=int(n)
    queue = []
    for i in range(n):
        board = initBoard(n)
        board[0][i]=1
        point = Point(0,i,board)
        queue.append(point)
    res = 0
    while(len(queue) != 0):
        point = queue.pop(0)
        row=point.x
        col=point.y

        if(row==n-1): #已经最后一行,直接输出
            res += 1
            print("---------------------------")
            print("第", res, "种结果如下:")
            print(point.board)
        else:
            for j in range(n):
                if(check(point.board, row + 1, j, n)):
                    #这个点可以加入到队列之中
                    board=copy.deepcopy(point.board)
                    board[row+1][j] = 1
                    temp = Point(row + 1, j, board)
                    queue.append(temp)
    print("当输入为", n, "时,共计", res, "种方式")
    return



def DFS(n):
    n=int(n)
    print("DFS")
    board = initBoard(n)
    print("打印初始化棋盘")


    print(board)
    print("---------------------------------------")



    for i in range(n):
        board[0][i]=1
        dp(n, 1, board)
        board[0][i]=0
    print("当输入为", n, "时,共计", cnt, "种方式")
    return

def dp(n, row, board): #print("调用dp函数")
    if(row == n):
        #能够完成
        global cnt
        cnt+=1
        print("第", cnt, "种结果如下:")
        print(board)
        print("-----------------------------------")
        return
    for j in range(n):
        if(check(board, row, j, n)):
            #print("成功",row, " " ,j)
            #修改棋盘
            board[row][j]=1
            row += 1
            dp(n, row, board)
            row -= 1
            board[row][j]=0
    return


def initBoard(n):
    #初始化全0的2维数组,1代表选择,0代表未被选
    board = np.zeros((n,n),dtype=int)
    return board

#检测新添加的棋子是否合法
def check(board, row, col, n): #向上寻找是否合规
    temp_x=row #行数
    temp_x-=1
    while(temp_x>=0):
        for j in range(n):
            if(board[temp_x][j]==1):
                # print("检测到1的位置",temp_x,",",j)
                # print("原始位置",row,",",col)
                if(j==col or abs(j-col)==abs(temp_x-row)):
                    return False
        temp_x-=1
    return True




while(True):
    choice = input("请选择BFS或者DFS实现(按0代表BFS,按1代表DFS,按q离开):")
    if (choice == '0'):
        n=input("请输入棋盘大小:")
        BFS(n)
    elif (choice == '1'):
        # global cnt
        cnt = 0
        n=input("请输入棋盘大小:")
        DFS(n)
    elif (choice == 'q'):
        break
    else:
        print("请重新输入!")

2. 遭遇した落とし穴 (主に Python 構文に慣れていないため)

2.1 割り当ては浅いコピーである

バグが発生し、どのように代入しても代入が失敗しましたが、後に問題は浅いコピーであることが判明し、その後ディープコピーを使用すると成功しました。

2.2 or 演算子は or です

最初は C++ と同じで、 || を使用して結果がエラーを報告したことを示し、 | に変更するとエラーは報告されませんでしたが、プログラムの実行結果は間違っていたと思いました。問題

2.3 グローバル変数

Pythonにはポインタがなく、再帰を書くときにポインタを使って値を渡す方法がないので、グローバル変数を考えましたが、グローバル変数はC++のように外部に記述できるものではなく、globalキーワードを使用する必要があります。 . global キーワードの使用方法も非常に複雑なので、ここで一度記録します。

global g
g = 0
def p1():
    c = g+1
    print(c)
def p2():
    g+=1
    print(g)
p1()
p2()

アピールコード p1 は実行できますが、p2 は実行できません。結果は次のようになります。理由は明確ではありません。誰かが説明してくれることを願っています
ここに画像の説明を挿入
が、再帰を記述するときは、このグローバル変数を更新する必要があります。このグローバル変数の正しい使用方法は次のとおりです。

g = 0
def p1():
    c = g+1
    print(c)
def p2():
    global g
    g+=1
    print(g)
p1()
p2()

グローバルを外部で定義するのではなく、メソッドに追加します。

おすすめ

転載: blog.csdn.net/qq_43471945/article/details/127855564