Skip to content
Snippets Groups Projects
Commit 9db4f73b authored by Romain Vuillemot's avatar Romain Vuillemot
Browse files

Create 11-graphs-matrix-exercises.ipynb

parent 9a5a27f0
No related branches found
No related tags found
No related merge requests found
%% Cell type:markdown id:5a451b18 tags:
NAME:
%% Cell type:markdown id:5112bda3-5774-4eee-9dcb-5893136ac5dc tags:
# UE5 Fundamentals of Algorithms
# Lab 11: Graphs/Matrix
%% Cell type:markdown id:3054b63b-5b4a-4b07-a129-71951eaee576 tags:
---
%% Cell type:markdown id:6892d60b-b418-486b-a1db-008652e04457 tags:
## How to Get Out of a Maze?
In this exercise, you will write an algorithm to navigate out of a maze. The maze will be represented as a 2D matrix (discrete coordinates), which will serve as the data structure for storage and traversal. The starting point of the traversal will always be at the coordinates `(0, 0)` in the top-left corner, and the endpoint will be the bottom-right corner (in the case of the example below, `(9, 9)`). Walls with a value of `1` are impassable, and you also cannot move outside the matrix. Movement is possible in 8 directions: up, down, left, right, and their corresponding diagonals. In this exercise, you will explore three traversal methods. Note that there can be multiple different, but all valid, solutions.
%% Cell type:markdown id:56b3cb10-e5e1-4c1e-8a38-948b97b2ad47 tags:
**Question 1.1 -** Run the program below, which loads the maze and includes a display function. Identify one of the paths leading to the exit. Modify the code to display walls using `#` instead of `1`.
%% Cell type:code id:5de72656-1ea0-4662-afd7-7d3c60c77612 tags:
``` python
maze = [[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
def display_maze(l):
print('\n'.join([''.join(["# " if item == 1 else str(item) + " " for item in row])
for row in l]))
display_maze(maze)
```
%% Cell type:markdown id:d56f24af-bf15-488c-8439-4a02b183964a tags:
Give a valid path (that links the top left corner with the bottom-right corner) using the cell coordinates. E.g. `(0, 0), (1, 0) ... (9, 9)`
```
* 0 0 0 1 0 0 0 0 0
* 0 0 0 1 0 0 0 0 0
* 0 0 0 1 0 0 0 0 0
* 0 0 0 1 0 0 0 0 0
* 0 0 0 1 0 0 0 0 0
* * * * * * 0 0 0 0
0 0 0 0 1 * 0 0 0 0
0 0 0 0 1 * 0 0 0 0
0 0 0 0 1 * 0 0 0 0
0 0 0 0 0 * * * * *
```
%% Cell type:code id:480e043f-9041-4462-a2b8-cdfd0b5a9253 tags:
``` python
path = [
# YOUR CODE HERE
raise NotImplementedError()
]
```
%% Cell type:markdown id:4b8613a0-7a9d-40b3-9786-33811bb079fc tags:
Write an algorithm that draws the path on a given maze (using `*`). Make sur you coupy the maze values using `[row[:] for row in maze]`.
%% Cell type:code id:82eb2cca-bc6b-46b0-8bb6-867023701fe0 tags:
``` python
def display_path_on_maze(maze, path):
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:code id:3e47e24b-7c77-4a73-b793-7294058f966d tags:
``` python
display_path_on_maze(maze, path)
```
%% Cell type:markdown id:10287b07-ed9e-4a62-844f-1831d1be46a5 tags:
Write a function that checks if a path is valid for the maze given previously.
1. The path must start at (0, 0) and end at (n-1, m-1).
2. Each cell in the path must be accessible (value 0).
3. The movement between consecutive cells must be valid (one of 8 directions).
4. The next cell must be within bounds and accessible.
5. The final cell must be accessible.
%% Cell type:code id:3968dce5-9ed6-45f9-8814-c097851c9291 tags:
``` python
def is_valid_path(maze, path):
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:code id:27c1fa22-bfa1-4c10-820c-13b3ffc35f1d tags:
``` python
assert is_valid_path(maze, path)
assert not is_valid_path(maze, [(0, 0)])
assert not is_valid_path(maze, [(-1, -1)])
```
%% Cell type:markdown id:3887d798-7d13-4bfd-9d5b-e9357e998bca tags:
**Question 1.2 -** Write a function `neighbors` that returns all the neighbors of a cell (i.e., all other cells accessible from this cell).
%% Cell type:code id:2363dbae-a62e-4f3a-b399-c8f172b6bd09 tags:
``` python
def neighbors(maze, x, y):
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:code id:9554f674-f8c2-4784-9de0-7f553db68802 tags:
``` python
assert set(neighbors(maze, 0, 0)) == {(1, 0), (1, 1), (0, 1)} # the top left cell has 3 neighbors
assert set(neighbors(maze, 1, 1)) == {(0, 0), (0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1), (2, 2)}
```
%% Cell type:code id:c08bf511-16e4-4d7e-9641-9e6aec991cc9 tags:
``` python
neighbors(maze, 4, 5)
```
%% Cell type:markdown id:a8290326-ce83-4824-b7eb-22b45983032d tags:
Write a function that calls the `neighbors` and returns all the values from a given point, make sure they are all zeros.
%% Cell type:code id:1048003e-f4e2-4ace-a953-818750f36934 tags:
``` python
def neighbor_values_from_point(maze, x, y):
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:code id:1285617c-f3c8-4c03-a002-2e18bb8efc00 tags:
``` python
assert all(v == 0 for v in neighbor_values_from_point(maze, 4, 5))
```
%% Cell type:markdown id:7b0c72c0-c1bc-4783-8ea9-e83860763070 tags:
Propose an algorithm to determine if there is a path connecting the entry and the exit. In this question, you will use a depth-first search (DFS) approach with a recursive implementation. The stopping condition for your search algorithm is reached if you are on the exit cell or if all neighbors have been visited. The algorithm should return `True` if a path exists, or `False` if it does not. You may use the `neighbors` function written previously.
%% Cell type:code id:5c839ee8-6339-4235-975a-fdc0190e5821 tags:
``` python
def exist_dfs(maze, x0=0, y0=0, visited=None):
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:markdown id:995d1bf9-5fd1-4011-828f-26044ee8a184 tags:
Write tests.
%% Cell type:code id:23e09473-c451-43fe-aa63-c8151c1ce01b tags:
``` python
assert exist_dfs(maze)
assert not exist_dfs([[0, 1], [1, 1]])
assert exist_dfs([[0, 1], [0, 0]])
```
%% Cell type:markdown id:db449e33-b3b2-4525-a8fe-cd5fffa0bb23 tags:
**Exercise 1.3 -** We now use a _breadth-first search (BFS)_ algorithm with an _iterative_ implementation to determine if an exit exists.
%% Cell type:code id:b4ca764e-e1f7-4e17-9b03-dcadde3434c9 tags:
``` python
def exist_bfs(maze):
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:markdown id:1a131d46-7f70-4c3d-b8c3-4df7c6f8ce1e tags:
Compare to the dfs.
%% Cell type:code id:8380bc3a-fbd6-4405-a08d-1770af316bf8 tags:
``` python
assert exist_bfs(maze)
assert exist_bfs([[0, 1], [1, 1]]) == exist_dfs([[0, 1], [1, 1]])
assert exist_bfs([[0, 1], [0, 0]]) == exist_dfs([[0, 1], [0, 0]])
```
%% Cell type:markdown id:10e47cd3-948e-44a5-9172-9ad540978310 tags:
Now implement a backtracking approach to provide the path to the exit. To achieve this use a dictionnary to store the `previous` step before processing the node.
1. If no path exists (`previous` is empty), return None.
2. Initialize the path with the end position: `path = [end]`.
3. While the current position is not the start, set `(x, y) = previous[y][x]` and append `(x, y)` to the path.
4. Reverse the path to get it from start to end.
%% Cell type:code id:5f54b7dc-4a6a-4382-9c0e-eb57bbd38dc1 tags:
``` python
def path_bfs(maze):
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:markdown id:327f6930-2a62-4b38-a5a4-8f53f3a360a1 tags:
# Bonus questions
%% Cell type:markdown id:03a90755-ff99-4839-a0be-ab09854f340e tags:
Write a function that generates an empty maze:
%% Cell type:code id:4ef141a5-e2fb-4fd4-b186-6e5bd1f0f463 tags:
``` python
def generate_empty_maze(rows, cols):
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:code id:f19ddefd-b4e8-497d-a704-97a3e0c3de6b tags:
``` python
```
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment