Skip to content

Commit 0e2a367

Browse files
authored
Update backtracking.md
1 parent 9428e5f commit 0e2a367

File tree

1 file changed

+45
-45
lines changed

1 file changed

+45
-45
lines changed

notes/backtracking.md

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# Backtracking
1+
## Backtracking
22

33
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.
44

5-
## Recursive Functions
5+
### Recursive Functions
66

77
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.
88

@@ -11,7 +11,7 @@ Main idea:
1111
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.
1212
2. **Recursive Case** is the part of the function where it calls itself with a modified parameter, moving towards the base case.
1313

14-
### Mathematical Foundation
14+
#### Mathematical Foundation
1515

1616
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.
1717

@@ -29,7 +29,7 @@ where:
2929
- $g(n)$ is the base case value,
3030
- $h$ is a function that defines how to build the solution from the smaller instance.
3131

32-
### Example: Calculating Factorial
32+
#### Example: Calculating Factorial
3333

3434
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:
3535

@@ -50,7 +50,7 @@ def factorial(n):
5050
return n * factorial(n - 1) # Recursive case
5151
```
5252

53-
#### Detailed Computation for $n = 5$
53+
##### Detailed Computation for $n = 5$
5454

5555
Let's trace the recursive calls for `factorial(5)`:
5656

@@ -71,7 +71,7 @@ Now, we backtrack and compute the results:
7171

7272
Thus, $5! = 120$.
7373

74-
### Visualization with Recursion Tree
74+
#### Visualization with Recursion Tree
7575

7676
Each recursive call can be visualized as a node in a tree:
7777

@@ -97,7 +97,7 @@ The leaves represent the base case, and the tree unwinds as each recursive call
9797
- 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.
9898
- 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.
9999

100-
## Depth-First Search (DFS)
100+
### Depth-First Search (DFS)
101101

102102
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.
103103

@@ -107,7 +107,7 @@ Main idea:
107107
- **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.
108108
- **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.
109109

110-
### Algorithm Steps
110+
#### Algorithm Steps
111111

112112
- **Start at the root node** by marking it as visited to prevent revisiting it during the traversal.
113113
- **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):
123123
DFS(neighbor)
124124
```
125125

126-
### Example: Tree Traversal
126+
#### Example: Tree Traversal
127127

128128
Consider the following tree:
129129

@@ -182,14 +182,14 @@ Analysis:
182182
- 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.
183183
- 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.
184184

185-
### Applications
185+
#### Applications
186186

187187
- **Cycle detection** in directed and undirected graphs.
188188
- **Topological sorting** in directed acyclic graphs (DAGs).
189189
- **Solving mazes and puzzles** by exploring all possible paths.
190190
- Identifying **connected components** in a network or graph.
191191

192-
## Backtracking
192+
### Backtracking
193193

194194
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.
195195

@@ -199,7 +199,7 @@ Main Idea:
199199
- Early detection of invalid solutions to prune the search space.
200200
- When a partial solution cannot be extended to a complete solution, the algorithm backtracks to try different options.
201201

202-
### General Algorithm Framework
202+
#### General Algorithm Framework
203203

204204
1. Understand the possible configurations of the solution.
205205
2. Start with an empty solution.
@@ -209,7 +209,7 @@ Main Idea:
209209
6. If the partial solution is complete and valid, record or output it.
210210
7. If all options are exhausted at a level, remove the last component and backtrack to the previous level.
211211

212-
### N-Queens Problem
212+
#### N-Queens Problem
213213

214214
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.
215215

@@ -219,7 +219,7 @@ Objective:
219219
- Ensure that no two queens attack each other.
220220
- Find all possible arrangements that satisfy the above conditions.
221221

222-
#### Visual Representation
222+
##### Visual Representation
223223

224224
To better understand the problem, let's visualize it using ASCII graphics.
225225

@@ -262,13 +262,13 @@ One of the possible solutions for placing 4 queens on a $4 \times 4$ chessboard
262262
- `Q` represents a queen.
263263
- Blank spaces represent empty cells.
264264

265-
#### Constraints
265+
##### Constraints
266266

267267
- Only one queen per row.
268268
- Only one queen per column.
269269
- No two queens share the same diagonal.
270270

271-
#### Approach Using Backtracking
271+
##### Approach Using Backtracking
272272

273273
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.
274274

@@ -284,7 +284,7 @@ High-Level Steps:
284284
8. When $N$ queens have been successfully placed without conflicts, record the solution.
285285
9. Continue the process to find all possible solutions.
286286

287-
#### Python Implementation
287+
##### Python Implementation
288288

289289
Below is a Python implementation of the N-Queens problem using backtracking.
290290

@@ -330,15 +330,15 @@ for index, sol in enumerate(solutions):
330330
print(' '.join(line))
331331
```
332332

333-
#### Execution Flow
333+
##### Execution Flow
334334

335335
1. Try placing a queen in columns `0` to `N - 1`.
336336
2. For each valid placement, proceed to row `1`.
337337
3. At each row, attempt to place a queen in a safe column.
338338
4. If no safe column is found, backtrack to the previous row.
339339
5. When a valid placement is found for all $N$ rows, record the solution.
340340

341-
#### All Solutions for $N = 4$
341+
##### All Solutions for $N = 4$
342342

343343
There are two distinct solutions for $N = 4$:
344344

@@ -376,7 +376,7 @@ Board Representation: [2, 0, 3, 1]
376376
+---+---+---+---+
377377
```
378378

379-
#### Output of the Program
379+
##### Output of the Program
380380

381381
```
382382
Number of solutions for N=4: 2
@@ -394,7 +394,7 @@ Q . . .
394394
. Q . .
395395
```
396396

397-
#### Visualization of the Backtracking Tree
397+
##### Visualization of the Backtracking Tree
398398

399399
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.
400400

@@ -404,7 +404,7 @@ The algorithm explores the solution space as a tree, where each node represents
404404

405405
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.
406406

407-
#### Analysis
407+
##### Analysis
408408

409409
I. The **time complexity** of the N-Queens problem is $O(N!)$ as the algorithm explores permutations of queen placements across rows.
410410

@@ -413,23 +413,23 @@ II. The **space complexity** is $O(N)$, where:
413413
- The `board` array stores the positions of the $N$ queens.
414414
- The recursion stack can go as deep as $N$ levels during the backtracking process.
415415

416-
#### Applications
416+
##### Applications
417417

418418
- **Constraint satisfaction problems** often use the N-Queens problem as a classic example to study and develop solutions for placing constraints on variable assignments.
419419
- In **algorithm design**, the N-Queens problem helps illustrate the principles of backtracking and recursive problem-solving.
420420
- In **artificial intelligence**, it serves as a foundational example for search algorithms and optimization techniques.
421421

422-
#### Potential Improvements
422+
##### Potential Improvements
423423

424424
- Implementing more efficient conflict detection methods.
425425
- Using heuristics to choose the order of columns to try first.
426426
- Converting the recursive solution to an iterative one using explicit stacks to handle larger values of $N$ without stack overflow.
427427

428-
### Example: Maze Solver
428+
#### Example: Maze Solver
429429

430430
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.
431431

432-
#### Maze Representation
432+
##### Maze Representation
433433

434434
**Grid Cells:**
435435

@@ -441,7 +441,7 @@ Given a maze represented as a 2D grid, find a path from the starting point to th
441441
- Up, down, left, right.
442442
- No diagonal movement.
443443

444-
#### ASCII Representation
444+
##### ASCII Representation
445445

446446
Let's visualize the maze using ASCII graphics to better understand the problem.
447447

@@ -489,7 +489,7 @@ Objective:
489489

490490
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.
491491

492-
#### Python Implementation
492+
##### Python Implementation
493493

494494
```python
495495
def solve_maze(maze, start, goal):
@@ -544,7 +544,7 @@ else:
544544
print("No path found.")
545545
```
546546

547-
#### Recursive Function `explore(x, y)`
547+
##### Recursive Function `explore(x, y)`
548548

549549
I. **Base Cases:**
550550

@@ -569,7 +569,7 @@ III. **Backtracking:**
569569
- Unmark the cell by setting `maze[x][y] = '.'`.
570570
- Return `False` to indicate that this path does not lead to the goal.
571571

572-
#### Execution Flow
572+
##### Execution Flow
573573

574574
I. **Start at `(0, 0)`**:
575575

@@ -595,12 +595,12 @@ V. **Reaching the Goal**:
595595
- Eventually, the algorithm reaches the goal `(5, 5)` if a path exists.
596596
- The function returns `True`, and the full path is constructed via the recursive calls.
597597

598-
#### Output
598+
##### Output
599599

600600
- If a path is found, it prints "Path to goal:" followed by the list of coordinates in the path.
601601
- If no path exists, it prints "No path found."
602602

603-
#### Final Path Found
603+
##### Final Path Found
604604

605605
The path from start to goal:
606606

@@ -610,7 +610,7 @@ The path from start to goal:
610610
(5, 5)]
611611
```
612612

613-
#### Visual Representation of the Path
613+
##### Visual Representation of the Path
614614

615615
Let's overlay the path onto the maze for better visualization. We'll use `*` to indicate the path.
616616

@@ -638,78 +638,78 @@ Legend:
638638
. - Open path
639639
```
640640

641-
#### Advantages of Using Backtracking for Maze Solving
641+
##### Advantages of Using Backtracking for Maze Solving
642642

643643
- Ensures that all possible paths are explored until the goal is found.
644644
- Only the current path and visited cells are stored, reducing memory usage compared to storing all possible paths.
645645
- Recursive implementation leads to clean and understandable code.
646646

647-
#### Potential Improvements
647+
##### Potential Improvements
648648

649649
- This algorithm finds a path but not necessarily the shortest path.
650650
- To find the shortest path, algorithms like Breadth-First Search (BFS) are more suitable.
651651
- Modify the code to collect all possible paths by removing early returns when the goal is found.
652652
- Allowing diagonal movements would require adjusting the `explore` function to include additional directions.
653653

654-
## List of Problems
654+
### List of Problems
655655

656-
### Permutations
656+
#### Permutations
657657

658658
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.
659659

660660
* [C++ Solution](https://github.com/djeada/Algorithms-And-Data-Structures/tree/master/src/backtracking/cpp/all_permutations)
661661
* [Python Solution](https://github.com/djeada/Algorithms-And-Data-Structures/tree/master/src/backtracking/python/all_permutations)
662662

663-
### Combinations
663+
#### Combinations
664664

665665
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.
666666

667667
* [C++ Solution](https://github.com/djeada/Algorithms-And-Data-Structures/tree/master/src/backtracking/cpp/all_combinations)
668668
* [Python Solution](https://github.com/djeada/Algorithms-And-Data-Structures/tree/master/src/backtracking/python/all_combinations)
669669

670-
### String Pattern
670+
#### String Pattern
671671

672672
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.
673673

674674
* [C++ Solution](https://github.com/djeada/Algorithms-And-Data-Structures/tree/master/src/backtracking/cpp/string_pattern)
675675
* [Python Solution](https://github.com/djeada/Algorithms-And-Data-Structures/tree/master/src/backtracking/python/string_pattern)
676676

677-
### Generating Words
677+
#### Generating Words
678678

679679
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.
680680

681681
* [C++ Solution](https://github.com/djeada/Algorithms-And-Data-Structures/tree/master/src/backtracking/cpp/generating_words)
682682
* [Python Solution](https://github.com/djeada/Algorithms-And-Data-Structures/tree/master/src/backtracking/python/generating_words)
683683

684-
### Hamiltonian Path
684+
#### Hamiltonian Path
685685

686686
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.
687687

688688
* [C++ Solution](https://github.com/djeada/Algorithms-And-Data-Structures/tree/master/src/backtracking/cpp/hamiltonian_paths)
689689
* [Python Solution](https://github.com/djeada/Algorithms-And-Data-Structures/tree/master/src/backtracking/python/hamiltonian_paths)
690690

691-
### K-Colorable Configurations
691+
#### K-Colorable Configurations
692692

693693
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.
694694

695695
* [C++ Solution](https://github.com/djeada/Algorithms-And-Data-Structures/tree/master/src/backtracking/cpp/k_colorable_configurations)
696696
* [Python Solution](https://github.com/djeada/Algorithms-And-Data-Structures/tree/master/src/backtracking/python/k_colorable_configurations)
697697

698-
### Knight Tour
698+
#### Knight Tour
699699

700700
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.
701701

702702
* [C++ Solution](https://github.com/djeada/Algorithms-And-Data-Structures/tree/master/src/backtracking/cpp/knight_tour)
703703
* [Python Solution](https://github.com/djeada/Algorithms-And-Data-Structures/tree/master/src/backtracking/python/knight_tour)
704704

705-
### Topological Orderings
705+
#### Topological Orderings
706706

707707
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.
708708

709709
* [C++ Solution](https://github.com/djeada/Algorithms-And-Data-Structures/tree/master/src/backtracking/cpp/topological_sort)
710710
* [Python Solution](https://github.com/djeada/Algorithms-And-Data-Structures/tree/master/src/backtracking/python/topological_sort)
711711

712-
### Tic-Tac-Toe (Minimax)
712+
#### Tic-Tac-Toe (Minimax)
713713

714714
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.
715715

0 commit comments

Comments
 (0)