Visualizing Cycle Checking Strategies: Maze¶

Cycles are an issue with DFS.

Code¶

In [1]:
%run maze_helper.py
%matplotlib inline
%config InlineBackend.figure_format = 'retina'

import numpy as np


#f = open("small_maze.txt", "r")
#f = open("medium_maze.txt", "r")
#f = open("large_maze.txt", "r")    # this has only one solution!
f = open("open_maze.txt", "r")
#f = open("empty_maze.txt", "r")
#f = open("empty_maze_2.txt", "r")
#f = open("loops_maze.txt", "r")
#f = open("L_maze.txt", "r")

maze_str = f.read()
maze = parse_maze(maze_str)

show_maze(maze)
Helper functions for the Maze Assignment by M. Hahsler
Usage: 
  import maze_helper as mh
  mh.show_some_mazes()
  
Here is an example maze:

XXXXXXXXXXXXXXXXXXXXXX
X XX        X X      X
X    XXXXXX X XXXXXX X
XXXXXX     S  X      X
X    X XXXXXX XX XXXXX
X XXXX X         X   X
X        XXX XXX   X X
XXXXXXXXXX    XXXXXX X
XG         XX        X
XXXXXXXXXXXXXXXXXXXXXX

The goal is at (np.int64(8), np.int64(1)).
No description has been provided for this image
In [1]:
# tree_search_solution.py has my actual implementation (not published)
import tree_search_solution as ts

# order in which we add new states to the frontier
ts.set_order("NESW")
#ts.set_order(random=True)
Directions are checked in the order ['N', 'E', 'S', 'W']
Directions are checked in the order ['N', 'E', 'S', 'W']

DFS Cycle checking option 1: Check in the path + ignore the frontier¶

Ignoring the frontier is probably the easiest. We just check the path for cycles and add all non-cycle notes to the frontier. The issue is that we can end up with the same node multiple times in the frontier.

In [3]:
%time result = ts.DFS(maze, vis = False, animation = True, max_tries=500, frontier_option = 3)

ts.animate_maze(result)
CPU times: user 49.1 ms, sys: 8.18 ms, total: 57.3 ms
Wall time: 52.5 ms
No solution found.
Out[3]:
Your browser does not support the video tag.

The room looks solid red, but there are still some of the red points left in the frontier!

DFS Cycle checking option 2: Check in the path + don't add states that are already in the frontier a second time.¶

This unfortunately does not work and produces an infinite loop if there are any open spaces in the maze!

In [4]:
%time result = ts.DFS(maze, animation = True, max_tries = 500, frontier_option = 2)

ts.animate_maze(result)
CPU times: user 90.6 ms, sys: 8.14 ms, total: 98.7 ms
Wall time: 92.4 ms
No solution found.
Out[4]:
Your browser does not support the video tag.

Note that there are still frontier entires (orange squares) left when DFS removed a completed branch from memory (squares that turn white). This is a problem, since DFS will explore them again leading to an infinite loop.

DFS Cycle checking option 3: Check in the path + fix the frontier by moving found states to the top of the frontier stack¶

Increasing the priority of a frontier entry when we see it again solves this issue. Note that there are no orange squares left when DFS removes a path from memory so it knows that this part of the maze is done.

In [5]:
%time result = ts.DFS(maze, vis = False, animation = True, max_tries=500, frontier_option = 1)

ts.animate_maze(result)
CPU times: user 40.7 ms, sys: 19.9 ms, total: 60.5 ms
Wall time: 55.3 ms
Path length: 54
Reached squares: 0
Action sequence: ['W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'S', 'S', 'S']
Out[5]:
Your browser does not support the video tag.