简体   繁体   中英

Shortest Path on Chessboard , Python

I have NxN chessboard. I have a pawn that can move 1 box up,down,right,left. 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. I did it with 2D array. For instance, obstacles are 0 where others are 1. It looks like 2D array. R is pawn. O is obstacle. X are ways that robot can go. E is exit point.

EXXOO

XXXXX

XXROX

XXXXX

XXXXX

Array representation is

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

My question is should I traverse from R to E and create Tree implementation then calculate the minimum path (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 ). It is easy to see that DFS ( Depth-first Search ) would not necessarily return the shortest. 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:

  • vertices of the graphs are all tuples (x, y) that are in your 2D list and are not obstacles
  • two vertices are connected by an edge if they are "neighbors" in the 2D array

Here's a standard implementation of BFS in which we replace the vertices and edges as explained above.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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