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
**How it works:** Maintain a priority queue of nodes by tentative distance. Always expand the closest unvisited node—with non-negative weights, this node's distance is final. Update neighbors and repeat until you reach the goal.
25
+
26
+
The key insight: if all edges are non-negative, the shortest path to the closest unexplored node can't possibly go through unexplored territory (that would only add distance). So we can "lock in" each node's distance as we visit it.
27
+
28
+
**Complexity:** O((V + E) log V) with a binary heap, where V = nodes, E = edges
25
29
**Guarantees:** Optimal for non-negative weights
26
30
27
31
## astar
@@ -72,7 +76,13 @@ result = bellman_ford(n_nodes=4, edges=edges, start=0)
72
76
print(result.solution) # Distances from node 0
73
77
```
74
78
75
-
**Complexity:** O(VE)
79
+
**How it works:** Relax all edges V−1 times (where V is the number of nodes). "Relaxing" an edge means: if going through this edge gives a shorter path, update the distance.
80
+
81
+
Each pass guarantees we've found shortest paths using at most k edges. After V−1 passes, we've found all shortest paths—because a simple path visits each node at most once, so it uses at most V−1 edges.
82
+
83
+
To detect negative cycles: do one more pass. If any distance still improves, there's a negative cycle—you can keep going around it forever, reducing the distance infinitely.
84
+
85
+
**Complexity:** O(V × E) where V = nodes, E = edges
Copy file name to clipboardExpand all lines: docs/algorithms/linear-programming/solve-lp-interior.md
+26-6Lines changed: 26 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -47,14 +47,34 @@ print(result.objective) # 12.0 approximately
47
47
48
48
## How It Works
49
49
50
-
Interior point methods maintain a point strictly inside the feasible region andmove toward optimality while staying interior. This implementation uses:
50
+
While simplex hops between vertices, interior point methods stay strictly inside the feasible region andapproach optimality along a curved path called the *central path*.
51
51
52
-
1. **Primal-dual formulation** — Solves primal and dual problems simultaneously
53
-
2. **Mehrotra predictor-corrector** — Two-step Newton method for faster convergence
54
-
3. **Normal equations** — Reduces the KKT system to a smaller symmetric system
55
-
4. **Cholesky decomposition** — Efficiently solves the symmetric linear system
52
+
**The barrier idea:** Add a logarithmic penalty for approaching boundaries:
56
53
57
-
Each iteration requires O(n³) work for the linear solve, but converges in O(√n) iterations.
54
+
```text
55
+
minimize c·x - μ Σ log(xᵢ)
56
+
```
57
+
58
+
As μ→0, the solution approaches the true optimum. But we don't solve this directly.
59
+
60
+
**Primal-dual formulation:** Instead of just the primal problem, we solve primal and dual simultaneously. The optimality conditions (KKT) are:
61
+
62
+
```text
63
+
Ax = b (primal feasibility)
64
+
A'y + z = c (dual feasibility)
65
+
xᵢzᵢ = 0 (complementarity)
66
+
x, z ≥ 0
67
+
```
68
+
69
+
We relax complementarity to xᵢzᵢ = μ and drive μ→0.
70
+
71
+
**Newton's method:** Each iteration solves a linear system (the KKT system) to find a direction, then takes a step while staying positive. The magic is that convergence is polynomial—typically 20-50 iterations regardless of problem size.
72
+
73
+
**Mehrotra predictor-corrector:** Two Newton steps per iteration. First a "predictor" step toward the boundary, then a "corrector" step that recenters. Nearly doubles the practical speed.
74
+
75
+
**Normal equations:** The 3×3 block KKT system reduces to a smaller m×m system (A D A'), solved via Cholesky decomposition.
76
+
77
+
For the theory, see [Interior Point Methods on Wikipedia](https://en.wikipedia.org/wiki/Interior-point_method) or Nocedal & Wright's *Numerical Optimization*.
Copy file name to clipboardExpand all lines: docs/algorithms/linear-programming/solve-lp.md
+31-2Lines changed: 31 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -60,10 +60,39 @@ result = solve_lp(c, [[-1, -1]], [-4])
60
60
result = solve_lp(c, [[1, 1], [-1, -1]], [4, -4])
61
61
```
62
62
63
+
## How It Works
64
+
65
+
The simplex algorithm exploits a key insight: the optimal solution to a linear program always occurs at a vertex (corner) of the feasible region. Instead of searching the entire space, we hop from vertex to vertex, always improving the objective.
66
+
67
+
**The geometry:** Your constraints define a convex polytope in n-dimensional space. Each vertex is where n constraints meet. The objective function defines a direction—we're looking for the vertex furthest in that direction.
68
+
69
+
**The algebra:** We convert to standard form with slack variables:
70
+
71
+
```text
72
+
minimize c·x
73
+
subject to Ax + s = b, x ≥ 0, s ≥ 0
74
+
```
75
+
76
+
Each vertex corresponds to a *basic feasible solution*—setting n variables to zero and solving for the rest. The algorithm:
77
+
78
+
1. Start at a vertex (basic feasible solution)
79
+
2. Look at adjacent vertices (one pivot away)
80
+
3. Move to a neighbor with better objective value
81
+
4. Repeat until no improvement possible → optimal
82
+
83
+
**The pivot:** Each iteration picks an entering variable (improves objective) and leaving variable (maintains feasibility), then updates the tableau. This is the "walking along edges" part.
84
+
85
+
**Two-phase method:** If the origin isn't feasible (some constraints violated), Phase I finds a feasible starting vertex using artificial variables. Phase II then optimizes.
86
+
87
+
**Bland's rule:** Prevents cycling (revisiting the same vertex) by always picking the smallest index when ties occur.
88
+
89
+
For the full algorithm, see [Linear Programming on Wikipedia](https://en.wikipedia.org/wiki/Simplex_algorithm) or the classic textbook by Chvátal.
90
+
63
91
## Complexity
64
92
65
-
-**Time:** O(exponential worst case, polynomial average case)
66
-
-**Guarantees:** Finds the exact optimum for LP problems
93
+
-**Time:** O(2^n) worst case, but O(n²m) average on random instances
94
+
-**Space:** O(nm) for the tableau
95
+
-**Guarantees:** Finds the exact global optimum (not approximate)
Copy file name to clipboardExpand all lines: docs/algorithms/metaheuristics/anneal.md
+19-6Lines changed: 19 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -76,12 +76,25 @@ result = anneal(initial, obj, neighbors, cooling=logarithmic_cooling(c=1.0))
76
76
77
77
## How It Works
78
78
79
-
1. Start with initial solution at high temperature
80
-
2. Generate random neighbor
81
-
3. If neighbor is better, accept it
82
-
4. If neighbor is worse, accept with probability exp(-delta/T)
83
-
5. Reduce temperature according to cooling schedule
84
-
6. Stop when temperature drops below `min_temp` or `max_iter` reached
79
+
**The metallurgy analogy:** In real annealing, you heat metal until atoms move freely, then cool slowly so atoms settle into a low-energy crystal structure. Cool too fast and you get brittle metal with defects (stuck in local minimum). The algorithm mimics this.
80
+
81
+
**The math:** Accept worse solutions with probability:
82
+
83
+
```text
84
+
P(accept) = exp(-Δcost / temperature)
85
+
```
86
+
87
+
At high temperature, this is near 1—accept almost anything. At low temperature, this approaches 0—only accept improvements. The exponential form comes from statistical mechanics (Boltzmann distribution).
88
+
89
+
**Why it works:** Early on, high temperature lets you escape local optima by accepting worse moves. As you cool, you become more selective, converging toward a good solution. The probability of accepting a bad move depends on *how bad*—small backward steps are more likely than large ones.
90
+
91
+
**The algorithm:**
92
+
93
+
1. Start at high temperature with initial solution
94
+
2. Pick a random neighbor
95
+
3. If better, accept. If worse, accept with probability exp(-Δ/T)
0 commit comments