Python广度优先搜索类型错误

时间:2017-01-27 09:39:17

标签: python breadth-first-search

在我的用于广度优先搜索的Python脚本中,我收到以下错误:

  

TypeError:'list'对象不可调用

以下是代码:

initialState = sys.argv[2]
initialState = [i for i in initialState.split(',')]
goalTest = ['0','1','2','3','4','5','6','7','8']

def bfs(initialState, goalTest):
    q = deque([])
    for item in initialState:
        q.appendleft(item)
        print q

    frontier = q
    explored = set()

    while not frontier <= len(frontier):
        state = frontier.pop()
        print state
        explored.add(state)

        if goalTest(state):
            return state

        for neighbor in state.neighbors():
            if neighbor not in frontier or explored:
                frontier.append(neighbor)

    return "FAILURE"

所以行if goalTest(state)抛出TypeError,为什么?

1 个答案:

答案 0 :(得分:0)

您的代码存在很多问题:

  • 如果您要将状态添加到set个访问状态,则必须为tuple,因为list无法播放
  • 不要将州内的个别项目添加到deque,只是整个州
  • 如果这应该是BFS,则必须使用deque.popleft,因此它的行为类似于FIFO队列;使用pop你有一个LIFO队列或堆栈,即DFS(深度优先搜索)
  • while not frontier <= len(frontier)没有意义;您可能需要while len(frontier) > 0while frontier
  • goalTest只是一个参考状态,因此您只需比较:if state == goalTest
  • neighbors不是state的方法(它只是一个列表或元组),但应该是一个函数,因此称之为neighbors(state)而不是state.neighbors() < / LI>
  • neighbor not in frontier or explored不检查这些列表中是否neighbor(neighbor not in frontier) or explored;此外,如果您立即将其添加到frontier,则无需检查它是否在explored
  • 而不是return "FAILURE",您应该return Falsereturn None

这是一个固定(但未经过彻底测试)的版本:

initialState = tuple(initialState.split(','))
goalTest = ('0','1','2','3','4','5','6','7','8')

def bfs(initialState, goalTest):
    frontier = collections.deque([initialState])
    explored = set()

    while frontier:
        state = frontier.popleft()
        print(repr(state), len(frontier), len(explored))

        if state == goalTest:
            return state

        for neighbor in neighbors(state):
            if neighbor not in explored:
                frontier.append(neighbor)
                explored.add(neighbor)
    return False

def neighbors(state):
    ...

实施neighbors留给读者练习。如果是,as you say8-puzzle,那么0应该是&#34;空白&#34;拼图中的空间。只需检查与其相邻的其他部分(提示:除法和模数是你的朋友)并交换这些部分,然后返回这些交换状态的列表。

另外,请注意BFS可能不是解决此问题的最佳算法,因为有很多状态,而不知情的搜索(如BFS)可能需要非常长的时间。使用例如A*更好地使用知情搜索。作为启发式的错位瓦片的数量。