采用广度优先搜索(BFS)、深度优先搜索(DFS)和启发式搜索算法(A/A*算法) 编程求解八数码问题(初始状态允许任意),找出一种从初始状态到目标状态 移动步数最少的步骤。
时间: 2023-05-25 14:04:38 浏览: 73
搜索算法-搜索之BFS算法
下面是Python代码实现:
```python
from queue import Queue, PriorityQueue
# 目标状态
target = [[1, 2, 3], [4, 5, 6], [7, 8, 0]]
# 移动方向
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]
def bfs(start):
# 初始化
q = Queue()
q.put((start, '', 0))
visited = set()
while not q.empty():
node, path, steps = q.get()
if node == target:
return path
# 找到0在九宫格中的位置
x, y = 0, 0
for i in range(3):
for j in range(3):
if node[i][j] == 0:
x, y = i, j
# 枚举所有可能的移动方向
for k in range(4):
nx, ny = x + dx[k], y + dy[k]
if nx < 0 or nx >= 3 or ny < 0 or ny >= 3:
continue
new_node = [[node[i][j] for j in range(3)] for i in range(3)]
new_node[x][y], new_node[nx][ny] = new_node[nx][ny], new_node[x][y]
# 判断是否已经访问过
state = tuple([tuple(row) for row in new_node])
if state in visited:
continue
visited.add(state)
q.put((new_node, path + str(k), steps + 1))
return ''
def dfs(node, path, steps, max_depth, visited):
if node == target:
return path
if steps > max_depth:
return ''
# 找到0在九宫格中的位置
x, y = 0, 0
for i in range(3):
for j in range(3):
if node[i][j] == 0:
x, y = i, j
# 枚举所有可能的移动方向
for k in range(4):
nx, ny = x + dx[k], y + dy[k]
if nx < 0 or nx >= 3 or ny < 0 or ny >= 3:
continue
new_node = [[node[i][j] for j in range(3)] for i in range(3)]
new_node[x][y], new_node[nx][ny] = new_node[nx][ny], new_node[x][y]
# 判断是否已经访问过
state = tuple([tuple(row) for row in new_node])
if state in visited:
continue
visited.add(state)
res = dfs(new_node, path + str(k), steps + 1, max_depth, visited)
if res:
return res
return ''
def iddfs(start):
visited = set()
# 最大搜索深度
depth = 0
while True:
res = dfs(start, '', 0, depth, visited)
if res:
return res
depth += 1
def heuristic(node):
# 最小曼哈顿距离
h = 0
for i in range(3):
for j in range(3):
if node[i][j] == 0:
continue
row, col = (node[i][j] - 1) // 3, (node[i][j] - 1) % 3
h += abs(row - i) + abs(col - j)
return h
def a_star(start):
# 初始化
q = PriorityQueue()
q.put((heuristic(start), start, '', 0))
visited = set()
while not q.empty():
_, node, path, steps = q.get()
if node == target:
return path
# 找到0在九宫格中的位置
x, y = 0, 0
for i in range(3):
for j in range(3):
if node[i][j] == 0:
x, y = i, j
# 枚举所有可能的移动方向
for k in range(4):
nx, ny = x + dx[k], y + dy[k]
if nx < 0 or nx >= 3 or ny < 0 or ny >= 3:
continue
new_node = [[node[i][j] for j in range(3)] for i in range(3)]
new_node[x][y], new_node[nx][ny] = new_node[nx][ny], new_node[x][y]
# 判断是否已经访问过
state = tuple([tuple(row) for row in new_node])
if state in visited:
continue
visited.add(state)
q.put((heuristic(new_node) + steps + 1, new_node, path + str(k), steps + 1))
return ''
if __name__ == '__main__':
# 输入初始状态
start = []
for i in range(3):
line = input().strip().split()
start.append([int(x) for x in line])
# 广度优先搜索
res_bfs = bfs(start)
print('BFS:', res_bfs)
# 深度优先搜索
res_dfs = iddfs(start)
print('DFS:', res_dfs)
# 启发式搜索
res_a_star = a_star(start)
print('A*:', res_a_star)
```
在输入初始状态后,分别采用BFS、DFS和A*算法进行求解,输出最短的移动步骤。
阅读全文