人工知能コースのちょっとした宿題で 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()
グローバルを外部で定義するのではなく、メソッドに追加します。