Maze Generation - DFS


http://www.migapro.com/depth-first-search/
Basically, you start from a random point and keep digging paths in one of 4 directions(up, right, down, left) until you can’t go any further. Once you are stuck, you take a step back until you find an open path. You would continue digging from there. It’s just the repetition of these.
Create a 2-dimensional int array with odd row and column size. 0 represents paths(orange cell) and 1 would be walls(black cell).
Explanation 1
Set all cells to 1(wall). There are no paths right now.

Explanation 2
Next, let’s set the starting point. Generate odd numbers for row and col. Set that cell to 0. Use row and col variables to keep track of current location. On the picture above, it would be row = 3, col = 5. For clarity, I will be filling the current cell with red.
Explanation 3
Now, choose a random direction(up, right, down, or left) you are moving to. You will always be moving by 2 cells. The picture above illustrates the current cell moving down. There are couple things you need to check when you move. First, you need to check if 2 cells ahead of that direction is outside of the maze. Then, you check if 2 cells ahead is a path(0) or wall(1). If it’s a wall, you can move by setting these 2 cells to 0(path). Update your current location which is row=5, col=5 at this moment.
Explanation 4
As you keep digging as above, you notice that you get to a dead end. In this case, keep moving your current cell to previous cells until you are able to move to a new direction. This is called backtracking. Current location is at row=7, col=7, so you would be moving back to row=7, col=5 on the picture above. You can implement this logic using recursive method or stack.
Explanation 5
So you keep digging as the picture demonstrates. For better visual, I changed the color of arrow every time it hits a dead end.
Explanation 6
Lastly, this is the final result. With this size, it’s just natural that the maze gets too simple. The bigger the maze, the more complicated it will get.
After you choose your starting point, pass that information to the recursive method. In the recursive method, you can do the following…
  1. Generate an int array with 4 random numbers to represent directions.
  2. Start a for loop to go for 4 times.
  3. Set up a switch statement to take care of 4 directions.
  4. For that direction, check if the new cell will be out of maze or if it’s a path already open. If so, do nothing.
  5. If the cell in that direction is a wall, set that cell to path and call recursive method passing the new current row and column.
  6. Done.

 public int[][] generateMaze() {
    int[][] maze = new int[height][width];
    // Initialize
    for (int i = 0; i < height; i++)
        for (int j = 0; j < width; j++)
            maze[i][j] = 1;
 
     Random rand = new Random();
     // r for row、c for column
     // Generate random r
     int r = rand.nextInt(height);
     while (r % 2 == 0) {
         r = rand.nextInt(height);
     }
     // Generate random c
     int c = rand.nextInt(width);
     while (c % 2 == 0) {
         c = rand.nextInt(width);
     }
     // Starting cell
     maze[r][c] = 0;
 
     // Allocate the maze with recursive method
     recursion(r, c);
 
     return maze;
 }
 
 public void recursion(int r, int c) {
     // 4 random directions
     int[] randDirs = generateRandomDirections();
     // Examine each direction
     for (int i = 0; i < randDirs.length; i++) {
 
         switch(randDirs[i]){
         case 1: // Up
             // Whether 2 cells up is out or not
             if (r - 2 <= 0)
                 continue;
             if (maze[r - 2][c] != 0) {
                 maze[r-2][c] = 0;
                 maze[r-1][c] = 0;
                 recursion(r - 2, c);
             }
             break;
         case 2: // Right
             // Whether 2 cells to the right is out or not
             if (c + 2 >= width - 1)
                 continue;
             if (maze[r][c + 2] != 0) {
                 maze[r][c + 2] = 0;
                 maze[r][c + 1] = 0;
                 recursion(r, c + 2);
             }
             break;
         case 3: // Down
             // Whether 2 cells down is out or not
             if (r + 2 >= height - 1)
                 continue;
             if (maze[r + 2][c] != 0) {
                 maze[r+2][c] = 0;
                 maze[r+1][c] = 0;
                 recursion(r + 2, c);
             }
             break;
         case 4: // Left
             // Whether 2 cells to the left is out or not
             if (c - 2 <= 0)
                 continue;
             if (maze[r][c - 2] != 0) {
                 maze[r][c - 2] = 0;
                 maze[r][c - 1] = 0;
                 recursion(r, c - 2);
             }
             break;
         }
     }
 
 }
 
 /**
 * Generate an array with random directions 1-4
 * @return Array containing 4 directions in random order
 */
 public Integer[] generateRandomDirections() {
      ArrayList<Integer> randoms = new ArrayList<Integer>();
      for (int i = 0; i < 4; i++)
           randoms.add(i + 1);
      Collections.shuffle(randoms);
 
     return randoms.toArray(new Integer[4]);
 }
https://plaxdev.wordpress.com/2017/08/17/maze-generation-depth-first-search-part-1/

https://blog.csdn.net/juzihongle1/article/details/73135920
本文主要讲解的迷宫生成算法有三种:

1.Recursive backtracker ( 递归回溯,也是深度优先算法)

2.Randomized Prim's algorithm(随机Prim算法,让我想起了最小生成树的Prim算法)

3.Recursive division (递归分割算法)

首先,为了方便后续处理,默认的迷宫元素表示为[x,y,w]:

1.我们的迷宫为常规的矩形,因此可以用二维表示一个迷宫单元, 每个迷宫单元表示为一个二维数组元素[x,y]。

3.每个迷宫单元包含左上右下四个属性, 用w表示,分别表示迷宫单元四个面的墙,墙不占据迷宫单元。

首先是深度优先(递归回溯)算法,这个算法可以表示为(根据维基百科):

1.Make the initial cell the current cell and mark it as visited
2.While there are unvisited cells
1.If the current cell has any neighbours which have not been visited
1.Choose randomly one of the unvisited neighbours
2.Push the current cell to the stack
3.Remove the wall between the current cell and the chosen cell
4.Make the chosen cell the current cell and mark it as visited
2.Else if stack is not empty
1.Pop a cell from the stack
2.Make it the current cell
如果翻译一下,就是:
1.将起点作为当前迷宫单元并标记为已访问
2.当还存在未标记的迷宫单元,进行循环
1.如果当前迷宫单元有未被访问过的的相邻的迷宫单元
1.随机选择一个未访问的相邻迷宫单元
2.将当前迷宫单元入栈
3.移除当前迷宫单元与相邻迷宫单元的墙
4.标记相邻迷宫单元并用它作为当前迷宫单元
2.如果当前迷宫单元不存在未访问的相邻迷宫单元,并且栈不空
1.栈顶的迷宫单元出栈
2.令其成为当前迷宫单元


深度优先构建迷宫的思想就是,每次把新找到的未访问迷宫单元作为优先,寻找其相邻的未访问过的迷宫单元,直到所有的单元都被访问到。通俗的说,就是从起点开始随机走,走不通了就返回上一步,从下一个能走的地方再开始随机走。一般来说,深度优先法生成的迷宫极度扭曲,有着一条明显的主路。我们使用python语言+matplotlib生成的20*30的迷宫如图所示:



Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts