I am working on a project where I need to solve a maze using the minimum number of right turns and no left turns.
The distance travelled is irrelevant as long as right turns are minimized. We are asked to implement our program using both a backtracking algorithm and an optimal (time) one.
For the backtracking algorithm I was going use a stack. My algorithm would be something like:
I was wondering if anyone could point me in the direction of an optimal algorithm for this.
I'm having a tough time thinking of anything better than the backtracking one.
Backtracking Algorithm: Backtracking is an algorithmic-technique for solving problems recursively by trying to build a solution incrementally.
Trémaux's algorithm, invented by Charles Pierre Trémaux, is an efficient method to find the way out of a maze that requires drawing lines on the floor to mark a path, and is guaranteed to work for all mazes that have well-defined passages, but it is not guaranteed to find the shortest route.
If upon entering a maze, one immediately puts out one's right hand, touches the entryway wall and then faithfully follows the right wall, the exit will be found without fail.
I think you can do it by first finding all the points that are reachable with 0 right turns. Then with just 1 right turn, and so on. You can use a queue for doing that. Note that in the n-th phase you've got optimal solutions for all the points that can be reached with n right turns. More so - any not yet reached point is reachable with > n points or not reachable at all. In order to achieve optimal time complexity you have to use the fact that you need to search for new reachable points only from those reached points, which have an unreached neighbour in the appropriate direction. As every point has only 4 neighbours you will only search from it 4 times. You can implement it by maintaining a separate list for every direction D containing all the reached points with an unreached neighbour in that direction. This gives you a time complexity proportional to the area of the maze that is proportional to the size of your input data.
Below I present a graphical example:
. . . . . . (0) . . . . . 0 1 1 1 1 (1) 0 1 1 1 1 1
. ####### . . 0 ########## . 0 ########## . 0 ########## 2
. # . # . . 0 # . # . . 0 # . # . . 0 # . # . (2)
. # . . . . 0 # . . . . 0 # . . . . 0 # . . . (2)
. #### . # . 0 #### . # . 0 #### . # . 0 #### . # 2
(.) . . . . . (0) . . . . . 0 1 1 1 1 1 0 1 1 1 1 1
0 1 1 1 1 1 0 1 1 1 1 1
0 ########## 2 0 ########## 2
0 # . # 3 2 0 # 4 # 3 2
0 # (3) 3 3 2 0 # 3 3 3 2
0 #### . # 2 0 #### 4 # 2
0 1 1 (1) 1 1 0 1 1 1 1 1
( )
denote reached points with the appropriate neighbour unreached
Build a graph by constructing four nodes for every position in the maze. Every node will correspond to a particular direction: N, S, E, W.
There will be edges between every node and at most three of its adjacent neighbors: the ones to the "front", "back" and "right" (if they exist). The edge leading to the node in the "front" and "back" will have weight 0 (since the path length doesn't matter), whereas the edge to the node in the "right" will have weight 1 (this is what represents the cost of making a right turn).
Once the graph is set up (and probably the best way to do this is to reuse the original representation of the maze) a modified variant of the breadth-first search algorithm will solve the problem.
The trick to handle the 0/1 edge weights is to use a deque instead of the standard queue implementation. Specifically, nodes reached through 0 weight edges will be pushed in the front of the deque and the ones reached through edges of weight 1 will be pushed in the back.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With