棋盘上的最短路径,Python

时间:2017-01-19 11:03:57

标签: python python-3.x shortest-path

我有NxN棋盘。我有一个可以向上,向下,向右,向左移动1个盒子的棋子。有一个随机的退出点。我想要做的是计算从典当位置到退出位置的最短路径。

  • Pawn位于随机位置
  • 障碍物位于随机位置
  • 出口处位于随机位置

我已经为棋盘创建了adjaceny数组。我是用2D数组做的。例如,障碍物为0,其他为1.它看起来像2D阵列。 R是典当。 O是障碍。 X是机器人可以走的路。 E是出口点。

E X X O O

X X X X X

X X R O X

X X X X X

X X X X X

数组表示

1 1 1 0 0

1 1 1 1 1

1 1 1 0 1

1 1 1 1 1

1 1 1 1 1

我的问题是我应该从R遍历到E并创建Tree实现然后计算最小路径(DFS,BFS)?如果是这样我该怎么办?或者还有另一种方法吗?例如使用图表?

1 个答案:

答案 0 :(得分:0)

你是对的,你应该使用BFS(Breadth-first Search)。很容易看出DFS(Depth-first Search)不一定会返回最短的。但是,它仍会告诉您pawn和退出之间是否存在存在路径。

要应用BFS算法,您应该将问题视为图形而不更改问题的实际表示:

  • 图形的顶点是2D列表中的所有元组(x,y),而不是障碍物
  • 如果它们是2D数组中的“邻居”,则两个顶点通过边连接

这是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