以宽度优先结合A*算法解决8数码问题
import heapq
# 初始状态和目标状态
# 定义初始状态和目标状态
initial_state = [[1, 3, 4], [8, 2, 0], [7, 6, 5]]
target_state = [[1, 2, 3], [8, 0, 4], [7, 6, 5]]
# 宽度优先搜索算法
def astar(initial_state, target_state):
queue = [(0, initial_state, [])] # 记录步数
visited = set([tuple(map(tuple, initial_state))]) #以套娃的形式添加到了集合中,以记录已经扩展过的状态避免重复
while queue:
__, state, path = heapq.heappop(queue) #依据优先级弹出
if state == target_state:
return path #返回正确的路径
for move, delta in [('Up', (-1, 0)), ('Down', (1, 0)), ('Left', (0, -1)), ('Right', (0, 1))]:
new_state = [[state[i][j] for j in range(3)] for i in range(3)]
row, col = find_zero(new_state)
new_row, new_col = row + delta[0], col + delta[1]
if 0 <= new_row < 3 and 0 <= new_col < 3:
new_state[row][col], new_state[new_row][new_col] = new_state[new_row][new_col], new_state[row][col]
if tuple(map(tuple, new_state)) not in visited:
cost = len(path) + manhattan_distance(new_state, target_state)
heapq.heappush(queue, (cost, new_state, path + [move]))
visited.add(tuple(map(tuple, new_state)))
return None
# 找到0的位置
def find_zero(state):
for i in range(3):
for j in range(3):
if state[i][j] == 0:
return i, j
# 计算距离
def manhattan_distance(state, target_state):
distance = 0
for i in range(3):
for j in range(3):
if state[i][j] != 0:
if state[i][j] != target_state[i][j]:
distance = distance + 1
return distance
# 测试
path = astar(initial_state, target_state)
if path:
print(' -> '.join(path))
else:
print('No solution.')
Up -> Left -> Down