You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: notes/backtracking.md
+45-45Lines changed: 45 additions & 45 deletions
Original file line number
Diff line number
Diff line change
@@ -1,8 +1,8 @@
1
-
# Backtracking
1
+
##Backtracking
2
2
3
3
Backtracking is a systematic method for solving problems that incrementally build candidates to the solutions and abandons a candidate ("backtracks") as soon as it determines that the candidate cannot possibly be completed to a valid solution. This approach is often used for constraint satisfaction problems, combinatorial optimization, and puzzles like the N-Queens problem or Sudoku.
4
4
5
-
## Recursive Functions
5
+
###Recursive Functions
6
6
7
7
Recursive functions are functions that call themselves directly or indirectly to solve a problem by breaking it down into smaller, more manageable subproblems. This concept is fundamental in computer science and mathematics, as it allows for elegant solutions to complex problems through repeated application of a simple process.
8
8
@@ -11,7 +11,7 @@ Main idea:
11
11
1.**Base Case (Termination Condition)** is the condition under which the recursion stops. It prevents infinite recursion by providing an explicit solution for the simplest instance of the problem.
12
12
2.**Recursive Case** is the part of the function where it calls itself with a modified parameter, moving towards the base case.
13
13
14
-
### Mathematical Foundation
14
+
####Mathematical Foundation
15
15
16
16
Recursion closely relates to mathematical induction, where a problem is solved by assuming that the solution to a smaller instance of the problem is known and building upon it.
17
17
@@ -29,7 +29,7 @@ where:
29
29
- $g(n)$ is the base case value,
30
30
- $h$ is a function that defines how to build the solution from the smaller instance.
31
31
32
-
### Example: Calculating Factorial
32
+
####Example: Calculating Factorial
33
33
34
34
The factorial of a non-negative integer $n$ is the product of all positive integers less than or equal to $n$. Mathematically, it is defined as:
35
35
@@ -50,7 +50,7 @@ def factorial(n):
50
50
return n * factorial(n -1) # Recursive case
51
51
```
52
52
53
-
#### Detailed Computation for $n = 5$
53
+
#####Detailed Computation for $n = 5$
54
54
55
55
Let's trace the recursive calls for `factorial(5)`:
56
56
@@ -71,7 +71,7 @@ Now, we backtrack and compute the results:
71
71
72
72
Thus, $5! = 120$.
73
73
74
-
### Visualization with Recursion Tree
74
+
####Visualization with Recursion Tree
75
75
76
76
Each recursive call can be visualized as a node in a tree:
77
77
@@ -97,7 +97,7 @@ The leaves represent the base case, and the tree unwinds as each recursive call
97
97
- Be mindful of **stack depth**, as each recursive call adds a new frame to the call stack. Too many recursive calls, especially in deep recursion, can result in a stack overflow error.
98
98
- Consider **efficiency** when choosing a recursive approach. While recursive solutions can be elegant and clean, they may not always be optimal in terms of time and space, particularly when dealing with large input sizes or deep recursive calls.
99
99
100
-
## Depth-First Search (DFS)
100
+
###Depth-First Search (DFS)
101
101
102
102
Depth-First Search is an algorithm for traversing or searching tree or graph data structures. It starts at a selected node and explores as far as possible along each branch before backtracking.
103
103
@@ -107,7 +107,7 @@ Main idea:
107
107
-**Implementation** of DFS can be achieved either through recursion, which implicitly uses the call stack, or by using an explicit stack data structure to manage the nodes.
108
108
-**Applications** of DFS include tasks such as topological sorting, identifying connected components in a graph, solving puzzles like mazes, and finding paths in trees or graphs.
109
109
110
-
### Algorithm Steps
110
+
####Algorithm Steps
111
111
112
112
-**Start at the root node** by marking it as visited to prevent revisiting it during the traversal.
113
113
-**Explore each branch** by recursively performing DFS on each unvisited neighbor, diving deeper into the graph or tree structure.
@@ -123,7 +123,7 @@ DFS(node):
123
123
DFS(neighbor)
124
124
```
125
125
126
-
### Example: Tree Traversal
126
+
####Example: Tree Traversal
127
127
128
128
Consider the following tree:
129
129
@@ -182,14 +182,14 @@ Analysis:
182
182
- The **time complexity** of Depth-First Search (DFS) is $O(V + E)$, where $V$ represents the number of vertices and $E$ represents the number of edges in the graph.
183
183
- The **space complexity** is $O(V)$, primarily due to the space used by the recursion stack or an explicit stack, as well as the memory required for tracking visited nodes.
184
184
185
-
### Applications
185
+
####Applications
186
186
187
187
-**Cycle detection** in directed and undirected graphs.
188
188
-**Topological sorting** in directed acyclic graphs (DAGs).
189
189
-**Solving mazes and puzzles** by exploring all possible paths.
190
190
- Identifying **connected components** in a network or graph.
191
191
192
-
## Backtracking
192
+
###Backtracking
193
193
194
194
Backtracking is an algorithmic technique for solving problems recursively by trying to build a solution incrementally, removing solutions that fail to satisfy the constraints at any point.
195
195
@@ -199,7 +199,7 @@ Main Idea:
199
199
- Early detection of invalid solutions to prune the search space.
200
200
- When a partial solution cannot be extended to a complete solution, the algorithm backtracks to try different options.
201
201
202
-
### General Algorithm Framework
202
+
####General Algorithm Framework
203
203
204
204
1. Understand the possible configurations of the solution.
205
205
2. Start with an empty solution.
@@ -209,7 +209,7 @@ Main Idea:
209
209
6. If the partial solution is complete and valid, record or output it.
210
210
7. If all options are exhausted at a level, remove the last component and backtrack to the previous level.
211
211
212
-
### N-Queens Problem
212
+
####N-Queens Problem
213
213
214
214
The N-Queens problem is a classic puzzle in which the goal is to place $N$ queens on an $N \times N$ chessboard such that no two queens threaten each other. In chess, a queen can move any number of squares along a row, column, or diagonal. Therefore, no two queens can share the same row, column, or diagonal.
215
215
@@ -219,7 +219,7 @@ Objective:
219
219
- Ensure that no two queens attack each other.
220
220
- Find all possible arrangements that satisfy the above conditions.
221
221
222
-
#### Visual Representation
222
+
#####Visual Representation
223
223
224
224
To better understand the problem, let's visualize it using ASCII graphics.
225
225
@@ -262,13 +262,13 @@ One of the possible solutions for placing 4 queens on a $4 \times 4$ chessboard
262
262
-`Q` represents a queen.
263
263
- Blank spaces represent empty cells.
264
264
265
-
#### Constraints
265
+
#####Constraints
266
266
267
267
- Only one queen per row.
268
268
- Only one queen per column.
269
269
- No two queens share the same diagonal.
270
270
271
-
#### Approach Using Backtracking
271
+
#####Approach Using Backtracking
272
272
273
273
Backtracking is an ideal algorithmic approach for solving the N-Queens problem due to its constraint satisfaction nature. The algorithm incrementally builds the solution and backtracks when a partial solution violates the constraints.
274
274
@@ -284,7 +284,7 @@ High-Level Steps:
284
284
8. When $N$ queens have been successfully placed without conflicts, record the solution.
285
285
9. Continue the process to find all possible solutions.
286
286
287
-
#### Python Implementation
287
+
#####Python Implementation
288
288
289
289
Below is a Python implementation of the N-Queens problem using backtracking.
290
290
@@ -330,15 +330,15 @@ for index, sol in enumerate(solutions):
330
330
print(''.join(line))
331
331
```
332
332
333
-
#### Execution Flow
333
+
#####Execution Flow
334
334
335
335
1. Try placing a queen in columns `0` to `N - 1`.
336
336
2. For each valid placement, proceed to row `1`.
337
337
3. At each row, attempt to place a queen in a safe column.
338
338
4. If no safe column is found, backtrack to the previous row.
339
339
5. When a valid placement is found for all $N$ rows, record the solution.
The algorithm explores the solution space as a tree, where each node represents a partial solution (queens placed up to a certain row). The branches represent the possible positions for the next queen.
400
400
@@ -404,7 +404,7 @@ The algorithm explores the solution space as a tree, where each node represents
404
404
405
405
The backtracking occurs when a node has no valid branches (no safe positions in the next row), prompting the algorithm to return to the previous node and try other options.
406
406
407
-
#### Analysis
407
+
#####Analysis
408
408
409
409
I. The **time complexity** of the N-Queens problem is $O(N!)$ as the algorithm explores permutations of queen placements across rows.
410
410
@@ -413,23 +413,23 @@ II. The **space complexity** is $O(N)$, where:
413
413
- The `board` array stores the positions of the $N$ queens.
414
414
- The recursion stack can go as deep as $N$ levels during the backtracking process.
415
415
416
-
#### Applications
416
+
#####Applications
417
417
418
418
-**Constraint satisfaction problems** often use the N-Queens problem as a classic example to study and develop solutions for placing constraints on variable assignments.
419
419
- In **algorithm design**, the N-Queens problem helps illustrate the principles of backtracking and recursive problem-solving.
420
420
- In **artificial intelligence**, it serves as a foundational example for search algorithms and optimization techniques.
421
421
422
-
#### Potential Improvements
422
+
#####Potential Improvements
423
423
424
424
- Implementing more efficient conflict detection methods.
425
425
- Using heuristics to choose the order of columns to try first.
426
426
- Converting the recursive solution to an iterative one using explicit stacks to handle larger values of $N$ without stack overflow.
427
427
428
-
### Example: Maze Solver
428
+
####Example: Maze Solver
429
429
430
430
Given a maze represented as a 2D grid, find a path from the starting point to the goal using backtracking. The maze consists of open paths and walls, and movement is allowed in four directions: up, down, left, and right (no diagonal moves). The goal is to determine a sequence of moves that leads from the start to the goal without crossing any walls.
431
431
432
-
#### Maze Representation
432
+
#####Maze Representation
433
433
434
434
**Grid Cells:**
435
435
@@ -441,7 +441,7 @@ Given a maze represented as a 2D grid, find a path from the starting point to th
441
441
- Up, down, left, right.
442
442
- No diagonal movement.
443
443
444
-
#### ASCII Representation
444
+
#####ASCII Representation
445
445
446
446
Let's visualize the maze using ASCII graphics to better understand the problem.
447
447
@@ -489,7 +489,7 @@ Objective:
489
489
490
490
Find a sequence of moves from `S` to `G`, navigating only through open paths (`.`) and avoiding walls (`#`). The path should be returned as a list of grid coordinates representing the steps from the start to the goal.
491
491
492
-
#### Python Implementation
492
+
#####Python Implementation
493
493
494
494
```python
495
495
defsolve_maze(maze, start, goal):
@@ -544,7 +544,7 @@ else:
544
544
print("No path found.")
545
545
```
546
546
547
-
#### Recursive Function `explore(x, y)`
547
+
#####Recursive Function `explore(x, y)`
548
548
549
549
I. **Base Cases:**
550
550
@@ -569,7 +569,7 @@ III. **Backtracking:**
569
569
- Unmark the cell by setting `maze[x][y] = '.'`.
570
570
- Return `False` to indicate that this path does not lead to the goal.
571
571
572
-
#### Execution Flow
572
+
#####Execution Flow
573
573
574
574
I. **Start at `(0, 0)`**:
575
575
@@ -595,12 +595,12 @@ V. **Reaching the Goal**:
595
595
- Eventually, the algorithm reaches the goal `(5, 5)` if a path exists.
596
596
- The function returns `True`, and the full path is constructed via the recursive calls.
597
597
598
-
#### Output
598
+
#####Output
599
599
600
600
- If a path is found, it prints "Path to goal:" followed by the list of coordinates in the path.
601
601
- If no path exists, it prints "No path found."
602
602
603
-
#### Final Path Found
603
+
#####Final Path Found
604
604
605
605
The path from start to goal:
606
606
@@ -610,7 +610,7 @@ The path from start to goal:
610
610
(5, 5)]
611
611
```
612
612
613
-
#### Visual Representation of the Path
613
+
#####Visual Representation of the Path
614
614
615
615
Let's overlay the path onto the maze for better visualization. We'll use `*` to indicate the path.
616
616
@@ -638,78 +638,78 @@ Legend:
638
638
. - Open path
639
639
```
640
640
641
-
#### Advantages of Using Backtracking for Maze Solving
641
+
#####Advantages of Using Backtracking for Maze Solving
642
642
643
643
- Ensures that all possible paths are explored until the goal is found.
644
644
- Only the current path and visited cells are stored, reducing memory usage compared to storing all possible paths.
645
645
- Recursive implementation leads to clean and understandable code.
646
646
647
-
#### Potential Improvements
647
+
#####Potential Improvements
648
648
649
649
- This algorithm finds a path but not necessarily the shortest path.
650
650
- To find the shortest path, algorithms like Breadth-First Search (BFS) are more suitable.
651
651
- Modify the code to collect all possible paths by removing early returns when the goal is found.
652
652
- Allowing diagonal movements would require adjusting the `explore` function to include additional directions.
653
653
654
-
## List of Problems
654
+
###List of Problems
655
655
656
-
### Permutations
656
+
####Permutations
657
657
658
658
Develop an algorithm to generate all possible permutations of a given list of elements. This problem requires creating different arrangements of the elements where the order matters.
Design an algorithm to generate all possible combinations of 'k' elements selected from a given list of elements. This involves selecting elements where the order does not matter, but the selection size does.
Create a solution to determine whether a given string adheres to a specified pattern, where the pattern may include letters and wildcard characters that represent any character. This problem often involves checking for matches and handling special pattern symbols.
Generate all possible words that can be formed from a given list of characters and match a specified pattern. The pattern can contain letters and wildcard characters, requiring the algorithm to account for flexible matching.
Create an algorithm that identifies whether a simple path exists within a provided undirected or directed graph. This path should visit every vertex exactly once. Known as the "traveling salesman problem," it can be addressed using depth-first search to explore possible paths.
Develop an algorithm to find all possible ways to color a given graph with 'k' colors such that no two adjacent vertices share the same color. This graph coloring problem requires ensuring valid color assignments for all vertices.
Create an algorithm to find all potential paths a knight can take on an 'n' x 'n' chessboard to visit every square exactly once. This classic chess problem involves ensuring the knight moves in an L-shape and covers all board positions.
Determine a topological ordering of the vertices in a given directed graph, if one exists. This involves sorting the vertices such that for every directed edge UV from vertex U to vertex V, U comes before V in the ordering.
Develop an algorithm to determine the optimal move for a player in a game of tic-tac-toe using the minimax algorithm. This requires evaluating possible moves to find the best strategy for winning or drawing the game.
0 commit comments