简体   繁体   English

如何在最短路径BFS中跟踪级别?

[英]How to track levels in shortest path BFS?

I'm coding a problem where I'm asked to find the least amount of steps between 2 points on an 8 by 8 chess board only using knight movement (L shaped movement). 我正在编码一个问题,要求我仅使用骑士动作(L型动作)在8 x 8的国际象棋棋盘上的2点之间找到最少的步数。

I am pretty sure my code is fine i just don't know where in the code I should track the number of steps. 我很确定我的代码很好,只是我不知道在代码中应该跟踪步骤数。

Here is the code. 这是代码。

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)

One possibility in BFS is to keep track of how you got to each vertex - so basically whenever we move to a new vertex we keep track of the "prior" vertex that led to the current one. BFS中的一种可能性是保持跟踪您到达每个顶点的方式-因此基本上,每当我们移至新顶点时,我们都会跟踪导致当前顶点的“先前”顶点。 When we've reached our goal vertex, we simply retrace our steps back using the list of "prior" vertices, and that gives us both the number of steps as well as the sequence. 到达目标顶点后,我们只需使用“在先”顶点列表来回溯步骤,这将为我们提供步骤数量和顺序。

Edit: looked closer at your code, and mbomb007 is right. 编辑:仔细查看您的代码,mbomb007是正确的。 Your code only calculates the next possible moves and adds them to the PQ. 您的代码仅计算下一个可能的移动并将它们添加到PQ中。 In order to calculate the number of moves, you need to find a way to track your knight's movements. 为了计算移动次数,您需要找到一种跟踪骑士移动的方法。

I'm pretty sure you need to keep track of the step-count along with the vertex in your queue. 我非常确定您需要跟踪步数以及队列中的顶点。 In other words, rather than queuing up just the vertex, include the number of steps taken to reach that vertex: 换句话说,不仅要排队,而且要包括到达顶点的步骤数:

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

Then, in the main loop: 然后,在主循环中:

(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...

EDIT: The stuff below about reproducing the sequence of steps...it isn't quite so simple. 编辑:下面关于重现步骤顺序的内容……不是那么简单。 The visited map could have a vertex in there multiple times, so there needs to be a way to know which is the right one. 访问过的地图可能在其中多次包含一个顶点,因此需要一种方法来知道哪个是正确的。 This could get messy. 这可能会变得混乱。 A better solution would probably be to keep track of the entire preceding sequence rather than just the previous vertex. 更好的解决方案可能是跟踪整个前面的序列,而不只是前面的顶点。

AdmiralWen has the right idea if you want the actual sequence of steps. 如果您需要实际的步骤顺序,AdmiralWen有一个正确的主意。 Instead of keeping the step count you keep the previous vertex. 而不是保留步数,而是保留先前的顶点。 Store the pair (vertex, prev-vertex) in your visited set so that you can retrace the sequence when you are done. 将对(顶点,上顶点)存储在访问集中,以便完成后可以追溯序列。 Note that rather than a set, visited should be a map in this case, where the key is a vertex and the value is the previous vertex. 请注意,在这种情况下,受访者应该是一个映射,而不是一个集合,其中键是一个顶点,值是上一个顶点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM