Write a program that generates mazes of arbitrary sizeusing the union-find algorithm. A simple algorithm to generate the maze is to start by creating an N x M grid of cells separated by walls on all sides, except for entrance and exit. Then continually choose a wall randomly, and knock it down if the cells are not already connected to each other. If we repeat the process until the starting and ending cells are connected, we have a maze. It is better to continue knocking down the walls until every cell is reachable from every cell as this would generate more false leads in the maze.
Test your algorithm by creating a 10 x 10 grid, and print all the walls that have been knocked down. Draw the resulting maze (hand-drawing is acceptable) andinclude the output of your program(see below).
- (If you don't include the output of your program, I won't be able to check that your drawing is correct, since your program will use random numbers.)
Solutions that do not use the union-find algorithm will receive 0 points.You can use the textbook code or implement union-find yourself, but I recommend using the textbook code. If you implement it yourself, any bugs in your implementation will affect your correctness grade.
Suggested strategy:
This is one way to approach this problem; you don't have to follow it, as long as you still make use of the union-find algorithm.
- One way to represent a maze is with a 2-dimensional array ("NxM grid" is a strong hint that you want to use a 2D array):Once you have this variable declared, maze[i][j] represents one square in the grid, assuming 0
- You can now think of the maze as a set of (i, j) pairs. A pair (i, j) represents the cell in row i and column j of your 2D array.
- Your sites for union-find consist of this set of (i, j) pairs. (You may want to define your own Pair class that has two int fields; or you can use an array of length 2.)
- When you call union() on two different sites, that corresponds to knocking down a wall.
- But you have to be careful to only knock down walls betweenadjacentcells! For example, (0,0) is adjacent to (0, 1) and (1, 0). It's not adjacent to (1, 1) or (4, 2).
- You can do some arithmetic to determine which cells are adjacent to each other. (You may want to define a helper method, adjacent(), that takes two Pairs and returns a boolean.)
- At this point, you might realize that you don't actually need the 2D array at all -- that's just useful for thinking about the problem. All you really need is the union-find data structure and some loops that initialize it with the right set of sites.
- You can use a random number generator (either the one built in to the Java standard library or the one from the textbook) to pick two random sites and knock down the wall between them.
- In a loop, you can knock down walls repeatedly until the starting cell (upper left corner) and ending cell (lower right corner) are connected. (Since you're representing the maze using a union-find data structure, you already have an easy way to know whether two cells in the maze / sites in union-find are connected.)
- To produce the maze drawing, set N to 10, set M to 10, and have your codeprint outthe coordinates for each pair of cells that has had its wall knocked down.
- For example, if your code has connected (0, 0) with (0, 1) and (0, 1) with (1, 1), the first two lines of output would be:
No need to print the actual maze but only the numbers like in the example above
UNION FIND ALGHORITHM RIGHT BELOW
public class UF {
private int[] id; // access to component id (site indexed) private
int count; // number of components
public UF(int N) { // Initialize component id
array. count = N; id = new int[N];
for (int i = 0; i
id[i] = i;
}
public int count() { return count; }
public boolean connected(int p, int q) {
return find(p) == find(q); }
public int find(int p) public void union(int p, int q) // See page 222 (quick-find),page 224 (quick-union) andpage 228 (weighted).
public static void main(String[] args) { // Solve dynamic connectivity problem on StdIn.
int N = StdIn.readInt(); // Read number of sites.
UF uf = new UF(N); // Initialize N components.
while (!StdIn.isEmpty()) {
int p = StdIn.readInt();
int q = StdIn.readInt(); // Read pair to connect.
if (uf.connected(p, q)) continue; // Ignore if connected.
uf.union(p, q); // Combine components
StdOut.println(p + " " + q); // and print connection.
}
StdOut.println(uf.count() + " components"); } }