简体   繁体   English

棋盘上的最短路径

[英]Shortest Path on Chessboard , Python

I have NxN chessboard. 我有NxN棋盘。 I have a pawn that can move 1 box up,down,right,left. 我有一个可以向上,向下,向右,向左移动1个框的棋子。 There is a random exit point. 有一个随机的出口点。 What I want to do is calculate the shortest path from pawn location to exit location. 我想做的是计算从典当位置到出口位置的最短路径。

  • Pawn is located at random place 典当位于随机位置
  • Obstacles are located at random place 障碍物位于随机位置
  • Exit place is located at random place 出口处位于随机位置

I already created adjaceny array for chessboard. 我已经为棋盘创建了adjaceny数组。 I did it with 2D array. 我用2D阵列做到了。 For instance, obstacles are 0 where others are 1. It looks like 2D array. 例如,障碍物为0,其他障碍物为1。它看起来像2D数组。 R is pawn. R是典当。 O is obstacle. O是障碍。 X are ways that robot can go. X是机器人可以走的路。 E is exit point. E是出口点。

EXXOO EXXOO

XXXXX XXXXX

XXROX XXROX

XXXXX XXXXX

XXXXX XXXXX

Array representation is 数组表示为

1 1 1 0 0 1 1 1 0 0

1 1 1 1 1 1 1 1 1 1

1 1 1 0 1 1 1 1 0 1

1 1 1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 1 1 1

My question is should I traverse from R to E and create Tree implementation then calculate the minimum path (DFS, BFS) ? 我的问题是我应该从R遍历到E并创建Tree实现,然后计算最小路径(DFS,BFS)吗? If so how should I do it ?. 如果是这样,我该怎么办? Or is there another method for that ? 还是有另一种方法? For instance using graphs ? 例如使用图形?

You are right, you should use BFS ( Breadth-first Search ). 没错,您应该使用BFS( 广度优先搜索 )。 It is easy to see that DFS ( Depth-first Search ) would not necessarily return the shortest. 不难发现,DFS( 深度优先搜索 )不一定会返回最短的。 However, it will still tell you whether there exists a path between your pawn and the exit. 但是,它仍然会告诉您在典当和出口之间是否存在路径。

To apply the BFS algorithm you should think of your problem as a graph without changing the actual representation of the problem: 要应用BFS算法,您应该将问题视为图表而不改变问题的实际表示形式:

  • vertices of the graphs are all tuples (x, y) that are in your 2D list and are not obstacles 图的顶点都是二维列表中的所有元组(x,y),而不是障碍
  • two vertices are connected by an edge if they are "neighbors" in the 2D array 如果两个顶点是2D数组中的“邻居”,则两个顶点由一条边连接

Here's a standard implementation of BFS in which we replace the vertices and edges as explained above. 这是BFS的标准实现,其中我们如上所述替换了顶点和边。

def BFS(board, start):
  queue = list()
  queue.append(start)
  visited = set()

  # this keeps track of where did we get to each vertex from
  # so that after we find the exit we can get back
  parents = dict()
  parents[start] = None

  while queue:
    v = queue[0]
    if board[v[0]][v[1]] == 'E':
      break
    queue = queue[1:]   # this is inefficient, an actual queue should be used 
    visited.add(v)
    for u in neighbors(board, v):
      if u not in visited:
        parents[u] = v
        queue.append(u)

  # we found the exit, now we have to go through the parents 
  # up to the start vertex to return the path
  path = list()
  while v != None:
    path.append(v)
    v = parents[v]

  # the path is in the reversed order so we reverse it 
  path = reverse(path)
  return path

def neighbors(board, v):
  diff = [(0, 1), (0, -1), (1, 0), (-1, 0)]
  retval = list()
  for d in diff:
    newr = d[0] + v[0]
    newc = d[1] + v[1]
    if newr < 0 or newr >= len(board) or newc < 0 or newc >= len(board[0]):
      continue
    if board[newr][newc] == 'X':
      continue
    retval.append((newr, newc))
  return retval

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

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