You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python BFS实现八数码问题时遭遇哈希错误求助

解决八数码BFS代码中的TypeError: unhashable type: 'list'错误

错误原因

你遇到的TypeError: unhashable type: 'list'是因为列表(list)是可变类型,无法被哈希计算,而集合(set)要求存储的元素必须是可哈希的(不可变类型)。你的代码中child.state是二维列表,直接将其加入visited集合就会触发这个错误。

解决方案

把所有表示状态的二维列表转换成元组(tuple)——元组是不可变类型,支持哈希计算,可以正常存入集合。需要修改以下几个部分:

1. 初始化状态改用元组

将初始状态和目标状态从列表嵌套改为元组嵌套:

initial_state = ((1, 2, 3),
                (4, 5, 0),
                (7, 8, 6))

goal_state = ((1, 2, 3),
              (4, 5, 6),
              (7, 8, 0))

2. 修改子状态生成逻辑

在get_children函数中,生成新状态时先将元组转成可修改的列表嵌套,修改后再转回元组:

# 以向下移动为例,其他方向同理
if i != 2:           
    # 把元组状态转成可修改的列表的列表
    state_list = [list(row) for row in node.state]
    state_list[i][j], state_list[i+1][j] = state_list[i+1][j], state_list[i][j]
    # 修改完成后转回元组
    new_state = tuple(tuple(row) for row in state_list)
    children.append(Node(new_state, node))

3. 优化BFS的访问判断逻辑(可选)

原代码中在添加子节点时判断是否已访问,可能导致重复入队。建议改为取出节点时判断是否已访问,避免无效操作:

while queue:
    node = queue.pop(0)
    if node.state == goal_state:
        return node
    # 若已访问过,直接跳过
    if node.state in visited:
        continue
    visited.add(node.state)
    
    for child in get_children(node):
        queue.append(child)

修改后的完整代码

class Node:
    def __init__(self, state, parent):
        self.state = state
        self.parent = parent


def get_children(node):
    children = []

    for i in range(3):
        for j in range(3):
            if node.state[i][j] == 0:
                # 向下移动
                if i != 2:           
                    state_list = [list(row) for row in node.state]
                    state_list[i][j], state_list[i+1][j] = state_list[i+1][j], state_list[i][j]
                    new_state = tuple(tuple(row) for row in state_list)
                    children.append(Node(new_state, node))

                # 向上移动
                if i != 0:           
                    state_list = [list(row) for row in node.state]
                    state_list[i][j], state_list[i-1][j] = state_list[i-1][j], state_list[i][j]
                    new_state = tuple(tuple(row) for row in state_list)
                    children.append(Node(new_state, node))

                # 向右移动
                if j != 2:           
                    state_list = [list(row) for row in node.state]
                    state_list[i][j], state_list[i][j+1] = state_list[i][j+1], state_list[i][j]
                    new_state = tuple(tuple(row) for row in state_list)
                    children.append(Node(new_state, node))

                # 向左移动
                if j != 0:           
                    state_list = [list(row) for row in node.state]
                    state_list[i][j], state_list[i][j-1] = state_list[i][j-1], state_list[i][j]
                    new_state = tuple(tuple(row) for row in state_list)
                    children.append(Node(new_state, node))

    return children


def bfs(initial_state, goal_state):
    queue = [Node(initial_state, None)]
    visited = set()

    while queue:
        node = queue.pop(0)
        if node.state == goal_state:
            return node

        if node.state in visited:
            continue
        visited.add(node.state)

        for child in get_children(node):
            queue.append(child)

    return None


initial_state = ((1, 2, 3),
                (4, 5, 0),
                (7, 8, 6))

goal_state = ((1, 2, 3),
              (4, 5, 6),
              (7, 8, 0))

solution = bfs(initial_state, goal_state)

if solution is not None:
    print("找到解")
    path = []
    node = solution
    while node is not None:
        path.append(node.state)
        node = node.parent

    path.reverse()
    for state in path:
        for row in state:
            print(row)
        print("---")
else:
    print("无解")

内容的提问来源于stack exchange,提问作者Shrey Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 06:04:54