Algorithm learned with Python 12th: Maze search

#Algorithm learned in Python

Introduction

Implement the basic algorithm in Python to deepen your understanding of the algorithm. Maze search is dealt with as the twelfth bullet.

Definition of the maze

Here, we deal with the following two-dimensional maze. maze_image.PNG S and G indicate the start and goal, respectively. Also, the black paint is the wall, and only the white paint can pass through. Furthermore, since it is handled by the program, numbers are associated with the start, goal, wall, and road as follows. maze_num.PNG In addition, the number is overwritten with 2 for the road passed during the search.

This time, a sentinel is used to search the maze using two methods, breadth-first search and depth-first search.

What is a sentinel?

** The sentinel is the data to be added to the list as a termination condition **. The sentinel in this case is the existence of an outer wall not shown in the above figure. It is a 10x10 maze, but when it is expressed in a program, it becomes a 12x12 maze in consideration of the outer wall. This makes it possible to determine where the vehicle cannot proceed without distinguishing between the inner wall and the outer wall. It is the effect of the sentinel that can be ** simplified ** in this way.

Implementation

A maze search is performed based on the above conditions. The program shows the code and output in the order of breadth-first search and depth-first search.

Code (breadth-first search)

maze1.py


"""
2020/12/30
@Yuya Shimizu

Guard
Maze search 1 (breadth-first search)
"""

#Search function: When the goal is reached, the position / movement number at that time is returned.
def Maze(start):
    #Start position (x coordinate,y coordinate,Number of moves)
    pos = start

    while len(pos) > 0:#True if searchable
        x, y, depth = pos.pop(0) #Get the position to search from the list

        #Ends when you reach the goal
        if maze[x][y] == 1:
            return [(x, y), depth]

        #Set as searched
        maze[x][y] = 2

        #Search up, down, left and right of the current position: 〇<2 indicates something that is neither a wall nor explored
        if maze[x-1][y] < 2:#left
            pos.append([x-1, y, depth + 1])
        if maze[x+1][y] < 2:#right
            pos.append([x+1, y, depth + 1])
        if maze[x][y-1] < 2:#Up
            pos.append([x, y-1, depth + 1])
        if maze[x][y+1] < 2:#under
            pos.append([x, y+1, depth + 1])
            
    return False

if __name__ == '__main__':
    #Maze creation
    maze = [
                [9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9],
                [9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 9],
                [9, 0, 9, 0, 0, 0, 9, 9, 0, 9, 0, 9],
                [9, 0, 9, 9, 0, 9, 0, 0, 0, 9, 0, 9],
                [9, 0, 0, 0, 9, 0, 0, 9, 9, 0, 9, 9],
                [9, 9, 9, 0, 0, 9, 0, 9, 0, 0, 0, 9],
                [9, 0, 0, 0, 9, 0, 9, 0, 0, 9, 1, 9],
                [9, 0, 9, 0, 0, 0, 0, 9, 0, 0, 9, 9],
                [9, 0, 0, 9, 0, 9, 0, 0, 9, 0, 0, 9],
                [9, 0, 9, 0, 9, 0, 9, 0, 0, 9, 0, 9],
                [9, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 9],
                [9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
                ]
    start = [[1, 1, 0]]     #Start position
    
    result = Maze(start)  #search

    print(result)
output
[(6, 10), 28]

The output is the (x, y) coordinates and the number of moves.

Next, the code that outputs the state of the search is shown. Since the output will be very long, only a part is shown.

Code (visualization)

maze1_1.py


"""
2020/12/30
@Yuya Shimizu

Guard
Maze search 1 (breadth-first search)
"""
from time import sleep

#Function that tracks the state of search (outputs maze updates)
def track(maze, start, depth):
    draw = f"{depth}Hands\n"
    for x in range(len(maze)):
        for y in range(len(maze[x])):
            if x == start[0][0] and y == start[0][1]:
                draw += "S  "   #Start position
            elif maze[x][y] > 2:
                draw += "■ "    #wall
            elif maze[x][y] == 2:
                draw += "*  "    #The road that has been explored
            elif maze[x][y] == 1:
                draw += "G  "   #Goal position
            else:
                draw += "  "    #Unexplored road
                
        draw += "\n"
    print(draw)
                
#Search function: When the goal is reached, the position / movement number at that time is returned.
def Maze(start):
    #Start position (x coordinate,y coordinate,Number of moves)
    pos = start.copy()

    while len(pos) > 0:#True if searchable
        x, y, depth = pos.pop(0) #Get the position to search from the list
        #Ends when you reach the goal
        if maze[x][y] == 1:
            return [(x, y), depth]

        #Set as searched
        maze[x][y] = 2
        #Figure update every second
        sleep(1)
        track(maze, start, depth)

        #Search up, down, left and right of the current position: 〇<2 indicates something that is neither a wall nor explored
        if maze[x-1][y] < 2:#left
            pos.append([x-1, y, depth + 1])
        if maze[x+1][y] < 2:#right
            pos.append([x+1, y, depth + 1])
        if maze[x][y-1] < 2:#Up
            pos.append([x, y-1, depth + 1])
        if maze[x][y+1] < 2:#under
            pos.append([x, y+1, depth + 1])
            
    return False


if __name__ == '__main__':
    #Maze creation
    maze = [
                [9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9],
                [9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 9],
                [9, 0, 9, 0, 0, 0, 9, 9, 0, 9, 0, 9],
                [9, 0, 9, 9, 0, 9, 0, 0, 0, 9, 0, 9],
                [9, 0, 0, 0, 9, 0, 0, 9, 9, 0, 9, 9],
                [9, 9, 9, 0, 0, 9, 0, 9, 0, 0, 0, 9],
                [9, 0, 0, 0, 9, 0, 9, 0, 0, 9, 1, 9],
                [9, 0, 9, 0, 0, 0, 0, 9, 0, 0, 9, 9],
                [9, 0, 0, 9, 0, 9, 0, 0, 9, 0, 0, 9],
                [9, 0, 9, 0, 9, 0, 9, 0, 0, 9, 0, 9],
                [9, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 9],
                [9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
                ]
    start = [[1, 1, 0]]     #Start position
    
    result = Maze(start)  #search

    print(result)
output
12th move
■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■
■ S * * ■ * * * * * * ■
■ * ■ * * * ■ ■ * ■   ■
■ * ■ ■ * ■     * ■   ■
■ * * * ■     ■ ■   ■ ■
■ ■ ■ * * ■   ■       ■
■ * * * ■ * ■     ■ G ■
■ * ■ * * * * ■     ■ ■
■ * * ■ * ■ *   ■     ■
■ * ■   ■   ■     ■   ■
■             ■       ■ 
■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ 

Due to differences in the environment and line breaks, it looks a little vertically long, but when the program is actually executed, it looks a little better. For reference, the screenshot at that time is shown below. s_c.png

Code (depth-first search)

maze2.py


"""
2020/12/30
@Yuya Shimizu

Guard
Maze search 2 (simple depth-first search)
"""

#Search function: When the goal is reached, the position / movement number at that time is returned.
def Maze(x, y, depth):
    #Ends when you reach the goal
    if maze[x][y] == 1:
        print([(x, y), depth])
    
    #Set as searched
    maze[x][y] = 2
        
    #Search up, down, left and right of the current position: 〇<2 indicates something that is neither a wall nor explored
    if maze[x-1][y] < 2:#left
        Maze(x-1, y, depth + 1)
    if maze[x+1][y] < 2:#right
        Maze(x+1, y, depth + 1)
    if maze[x][y-1] < 2:#Up
        Maze(x, y-1, depth + 1)
    if maze[x][y+1] < 2:#under
        Maze(x, y+1, depth + 1)

    #Return to before exploration
    maze[x][y] = 0

if __name__ == '__main__':
    #Maze creation
    maze = [
                [9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9],
                [9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 9],
                [9, 0, 9, 0, 0, 0, 9, 9, 0, 9, 0, 9],
                [9, 0, 9, 9, 0, 9, 0, 0, 0, 9, 0, 9],
                [9, 0, 0, 0, 9, 0, 0, 9, 9, 0, 9, 9],
                [9, 9, 9, 0, 0, 9, 0, 9, 0, 0, 0, 9],
                [9, 0, 0, 0, 9, 0, 9, 0, 0, 9, 1, 9],
                [9, 0, 9, 0, 0, 0, 0, 9, 0, 0, 9, 9],
                [9, 0, 0, 9, 0, 9, 0, 0, 9, 0, 0, 9],
                [9, 0, 9, 0, 9, 0, 9, 0, 0, 9, 0, 9],
                [9, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 9],
                [9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
                ]

    result = Maze(1, 1, 0)  #search
output
[(6, 10), 28]

The output is the (x, y) coordinates and the number of moves.

Next, the code that outputs the state of the search is shown. Since the output will be very long, only a part is shown.

Code (visualization)

maze2_1.py


"""
2020/12/30
@Yuya Shimizu

Guard
Maze search 2 (simple depth-first search)
"""
from time import sleep

#Function that tracks the state of search (outputs maze updates)
def track(maze, depth):
    draw = f"{depth}Hands\n"
    for x in range(len(maze)):
        for y in range(len(maze[x])):
            if maze[x][y] > 2:
                draw += "■ "    #wall
            elif maze[x][y] == 2:
                draw += "*  "    #The road that has been explored
            elif maze[x][y] == 1:
                draw += "G  "   #Goal position
            else:
                draw += "  "    #Unexplored road

        draw += "\n"
    print(draw)
    
#Search function: When the goal is reached, the position / movement number at that time is returned.
def Maze(x, y, depth):
    #Ends when you reach the goal
    if maze[x][y] == 1:
        print([(x, y), depth])
        exit()
    
    #Set as searched
    maze[x][y] = 2
    #Figure update every second
    sleep(1)
    track(maze, depth)
        
    #Search up, down, left and right of the current position: 〇<2 indicates something that is neither a wall nor explored
    if maze[x-1][y] < 2:#left
        Maze(x-1, y, depth + 1)
    if maze[x+1][y] < 2:#right
        Maze(x+1, y, depth + 1)
    if maze[x][y-1] < 2:#Up
        Maze(x, y-1, depth + 1)
    if maze[x][y+1] < 2:#under
        Maze(x, y+1, depth + 1)

    #Return to before exploration
    maze[x][y] = 0

if __name__ == '__main__':
    #Maze creation
    maze = [
                [9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9],
                [9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 9],
                [9, 0, 9, 0, 0, 0, 9, 9, 0, 9, 0, 9],
                [9, 0, 9, 9, 0, 9, 0, 0, 0, 9, 0, 9],
                [9, 0, 0, 0, 9, 0, 0, 9, 9, 0, 9, 9],
                [9, 9, 9, 0, 0, 9, 0, 9, 0, 0, 0, 9],
                [9, 0, 0, 0, 9, 0, 9, 0, 0, 9, 1, 9],
                [9, 0, 9, 0, 0, 0, 0, 9, 0, 0, 9, 9],
                [9, 0, 0, 9, 0, 9, 0, 0, 9, 0, 0, 9],
                [9, 0, 9, 0, 9, 0, 9, 0, 0, 9, 0, 9],
                [9, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 9],
                [9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
                ]

    result = Maze(1, 1, 0)  #search
output
27th move
■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ 
■ *     ■             ■ 
■ * ■       ■ ■   ■   ■ 
■ * ■ ■   ■       ■   ■ 
■ * * * ■     ■ ■   ■ ■ 
■ ■ ■ *   ■   ■ * * * ■ 
■     * ■   ■   * ■ G ■ 
■   ■ * * * * ■ * * ■ ■ 
■     ■   ■ * * ■ * * ■ 
■   ■   ■   ■ * * ■ * ■ 
■             ■ * * * ■ 
■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ 

[(6, 10), 28]

Similarly, due to differences in the environment and line breaks, it looks a little vertically long, but when the program is actually executed, it looks a little better. For reference, the screenshot at that time is shown below. s2_c.png

Impressions

I learned maze exploration. I thought this when I was studying that there was something that could lead to searching in mobile robots. This book also describes the right method. I did not describe the right method this time, but I could understand it. Also, since it is one of the previous examples of tree structures, I think that a deeper understanding was gained through the application of the tree structure search. We will touch on some more examples of search. This time was the first one.

References

Introduction to algorithms starting with Python: Standards and computational complexity learned with traditional algorithms Written by Toshikatsu Masui, Shoeisha

Recommended Posts

Algorithm learned with Python 12th: Maze search
Algorithm learned with Python 10th: Binary search
Algorithm learned with Python 9th: Linear search
Algorithm learned with Python 5th: Fibonacci sequence
Algorithm learned with Python 4th: Prime numbers
Search the maze with the python A * algorithm
Algorithm learned with Python 19th: Sorting (heapsort)
Algorithm learned with Python 11th: Tree structure
Algorithm learned with Python 16th: Sorting (insertion sort)
Algorithm learned with Python 14th: Tic-tac-toe (ox problem)
Algorithm learned with Python 15th: Sorting (selection sort)
Algorithm learned with Python 17th: Sorting (bubble sort)
Algorithm learned with Python 18th: Sorting (stack and queue)
Algorithm learned with Python 2nd: Vending machine
Binary search with python
Binary search with Python3
Search algorithm using word2vec [python]
Algorithm in Python (binary search)
Full bit search with Python
[Python3] Dijkstra's algorithm with 14 lines
Search engine work with python
Search twitter tweets with python
Streamline web search with python
Algorithm in Python (breadth-first search, bfs)
[Python] Object-oriented programming learned with Pokemon
Learn search with Python # 2bit search, permutation search
Algorithm in Python (depth-first search, dfs)
Perceptron learning experiment learned with Python
Python data structures learned with chemoinformatics
Efficient net pick-up learned with Python
1. Statistics learned with Python 1-1. Basic statistics (Pandas)
Implementation of Dijkstra's algorithm with python
Python algorithm
[Python] Reactive Extensions learned with RxPY (3.0.1) [Rx]
1. Statistics learned with Python 1-3. Calculation of various statistics (statistics)
Let's develop an investment algorithm with Python 1
[What is an algorithm? Introduction to Search Algorithm] ~ Python ~
FizzBuzz with Python3
Csv output from Google search with [Python]! 【Easy】
Automatically search and download YouTube videos with Python
Scraping with Python
Statistics with python
Scraping with Python
Twilio with Python
Integrate with Python
Play with 2016-Python
AES256 with python
1. Statistics learned with Python 1-2. Calculation of various statistics (Numpy)
python starts with ()
Bingo with python
Zundokokiyoshi with python
I tried it with SymPy Live, Wolfram Alpha and google with reference to "Algorithm learned with Python 4th: Prime numbers".
Use Python and word2vec (learned) with Azure Databricks
1. Statistics learned with Python 2-1. Probability distribution [discrete variable]
Find the shortest path with the Python Dijkstra's algorithm
Solving the Python knapsack problem with the greedy algorithm
Excel with Python
Microcomputer with Python
"Principle of dependency reversal" learned slowly with Python
Cast with python
[Python] Try optimizing FX systole parameters with random search