I've been working on some introductory Graph Theory lately, and came across the following problem statement:
Given a 2D matrix as input, representing a maze (where 'E' is the start of the matrix and 'S' is the end), find the length of the shortest path from E to S. Walls in the maze are represented by '#', while accessible spaces are indicated with '.'. It's also a given that the outer edge of the matrix is covered with walls. If no path exists from E to S, return -1
.
Since the graph isn't weighted, I tried implementing a BFS algorithm, using deque. However, when the mazes start hitting around 500x500, execution time hits 10s, and when I try to go up to 1000x1000, it's obviously a lot worse.
Here's my code:
from collections import deque
def shortest_path_1(maze):
wall, clear, endchar, startchar = '#', '.', 'S', 'E'
height = len(maze)
width = len(maze[0])
def find_start(grid):
for y in range(1, height-1):
for x in range(1, width-1):
if grid[y][x] == startchar:
return tuple([x, y])
start = find_start(maze)
queue = deque([[start]])
seen = {start}
while queue:
path = queue.popleft()
x, y = path[-1]
if maze[y][x] == endchar:
return len(path)-1
for (x2, y2) in ((x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)):
if 0 < x2 < width-1 and 0 < y2 < height-1 and maze[y2][x2] != wall and (x2, y2) not in seen:
queue.append(path + [(x2, y2)])
seen.add((x2, y2))
return -1
I found some very useful answers on the site so far, but none of the current ones seem to give any other optimizations that I haven't implemented yet...
Thanks!
EDIT: Thanks to the lovely person who edited my question to make the key words pop :). Here's an example of a matrix that you can run the algorithm on:
#####
#E#S#
#.#.#
#...#
#####
This should return the value 6.
EDIT2: Fixed some small mistakes.