如何在最短路径BFS中跟踪水平?

时间:2015-04-27 16:00:47

标签: python shortest-path breadth-first-search

我正在编码一个问题,我要求只使用骑士运动(L形运动)在8乘8棋盘上找到2点之间的最少步数。

我很确定我的代码很好,我只是不知道代码中应该跟踪步骤的数量。

这是代码。

start = tuple(map(int, raw_input().split()))
goal = tuple(map(int, raw_input().split()))
steps = 0
visited, queue = set(), [start]
while queue:
vertex = queue.pop(0)
    if vertex not in visited:
        visited.add(vertex)
        if vertex == goal:
            print steps
            break
        else:
            if vertex[0] >= 3 and vertex[1] >= 2:
                queue.append(tuple([(vertex[0] -2), (vertex[1]-1)]))

            if vertex[0] >= 2 and vertex[1] >= 3:
                queue.append(tuple([(vertex[0] -1), (vertex[1]-2)]))

            if vertex[0] >= 3 and vertex[1] <=7:
                queue.append(tuple([(vertex[0] -2), (vertex[1]+1)]))

            if vertex[0] >=2 and vertex[1] <= 6:
                queue.append(tuple([(vertex[0] -1), (vertex[1]+2)]))

            if vertex[0] <= 6 and vertex[1] >= 2:
                queue.append(tuple([(vertex[0] +2), (vertex[1]-1)]))

            if vertex[0] <= 7 and vertex[1] >=3:
                queue.append(tuple([(vertex[0] +1), (vertex[1]-2)]))

            if vertex[0] <= 7 and vertex[1] <= 6:
                queue.append(tuple([(vertex[0] +1), (vertex[1]+2)]))

            if vertex[0] <= 6 and vertex[1] <= 7:
                queue.append(tuple([(vertex[0] +2), (vertex[1]+1)]))
            queue.append(0)

2 个答案:

答案 0 :(得分:1)

BFS的一个可能性是跟踪你如何到达每个顶点 - 所以基本上每当我们移动到一个新的顶点时,我们都会跟踪导致当前顶点的“先前”顶点。当我们到达目标顶点时,我们只需使用“先前”顶点列表回溯我们的步骤,这样就可以得到步数和序列。

编辑:仔细查看代码,mbomb007是正确的。您的代码仅计算下一个可能的移动并将它们添加到PQ。为了计算移动次数,你需要找到一种方法来跟踪骑士的移动。

答案 1 :(得分:1)

我非常确定您需要跟踪队列中顶点的步数。换句话说,不是仅排队顶点,而是包括到达该顶点所采取的步骤数:

queue = [(start, 0)] #[ ((x, y), steps-so-far) ]

然后,在主循环中:

(vertex, steps) = queue.pop(0)
#...
    if vertex[0] >= 3 and vertex[1] >= 2:
        newVertex = (vertex[0] -2, vertex[1]-1) # No need to explicitly call tuple()
        queue.append( (newVertex, steps+1) )
    # And so on...
编辑:关于重现步骤顺序的下面的内容......它并非如此简单。被访问的地图可以在那里有多个顶点,因此需要有一种方法来知道哪一个是正确的。这可能会变得混乱。一个更好的解决方案可能是跟踪整个前面的序列而不仅仅是前一个顶点。

如果你想要实际的步骤顺序,AdmiralWen有正确的想法。不要保持步数,而是保留前一个顶点。将对(顶点,prev-vertex)存储在您访问的集合中,以便在完成后可以回溯序列。请注意,在这种情况下,访问应该是一个映射,而不是一个集合,其中键是一个顶点,值是前一个顶点。