A from-scratch implementation of a Genetic Algorithm (GA) for the 0/1 Knapsack Problem — one of Karp's original 21 NP-complete problems — demonstrating how biologically-inspired metaheuristics can efficiently approximate solutions to computationally intractable optimization landscapes.
- Problem Statement
- Why Genetic Algorithms?
- Algorithm Design
- Fitness Function & Selection Pressure
- Convergence Analysis
- Architecture
- Quick Start
- Configuration Space
- Theoretical Foundations
- Author
- License
The 0/1 Knapsack Problem is a cornerstone of combinatorial optimization:
Given a set of
$n$ items, each with a value$v_i$ and weight$w_i$ , determine the subset that maximizes total value while respecting a capacity constraint$W$ .
With n = 20 (default configuration), that's 1,048,576 candidate solutions. This implementation converges to a near-optimal solution by evaluating only a fraction of that space through evolutionary search.
Traditional exact methods (branch-and-bound, dynamic programming) guarantee optimality but scale poorly. Genetic Algorithms offer a fundamentally different paradigm:
| Property | Exact Methods | Genetic Algorithm |
|---|---|---|
| Optimality Guarantee | Yes | Approximate |
| Time Complexity |
|
|
| Parallelizable | Limited | Inherently parallel |
| Handles Noisy Objectives | No | Yes |
| Scalability | Degrades exponentially | Graceful degradation |
Where
This implementation follows the canonical GA pipeline with custom enhancements:
┌─────────────────────────────────────────────────────────────────┐
│ EVOLUTIONARY PIPELINE │
│ │
│ ┌──────────┐ ┌───────────┐ ┌──────────┐ ┌──────────┐ │
│ │ INIT │───▶│ SELECTION │───▶│CROSSOVER │───▶│ MUTATION │ │
│ │Population│ │ (Elitism) │ │(1-Point) │ │(Bit-Flip)│ │
│ └──────────┘ └───────────┘ └──────────┘ └──────────┘ │
│ │ │ │
│ │ ┌──────────────┐ │ │
│ │ │ EVALUATION │ │ │
│ └──────────────│ Fitness & │◀──────────────────┘ │
│ │ Constraint │ │
│ └──────┬───────┘ │
│ │ │
│ ┌──────▼───────┐ │
│ │ SURVIVOR │ │
│ │ SELECTION │──── Repeat g generations │
│ └──────────────┘ │
└─────────────────────────────────────────────────────────────────┘
| Operator | Strategy | Detail |
|---|---|---|
| Encoding | Binary chromosome | Each gene |
| Initialization | Constrained random | Only feasible, non-duplicate, non-empty solutions enter the initial pool |
| Crossover | Single-point (midpoint) | Offspring inherit the first half from one parent, second half from the other |
| Mutation | Adaptive bit-flip | Triggered by duplication, infeasibility, or stochastic mutation rate threshold |
| Selection | Parents and offspring compete; top |
|
| Elitism | Generational best | The fittest chromosome per generation is archived for analysis |
The fitness function goes beyond naive value summation. It introduces a capacity-proximity penalty that rewards solutions packing close to the knapsack limit:
Where:
-
$V = \sum v_i x_i$ — total value of selected items -
$W_{used} = \sum w_i x_i$ — total weight consumed -
$W_{max}$ — knapsack capacity (threshold)
This creates a dual selection pressure: maximize value while penalizing under-utilization of capacity. The penalty term
Empirical results demonstrate characteristic GA convergence behavior over 100 generations:
The monotonically non-decreasing step function confirms elitism preservation — the best solution is never lost. Rapid improvement occurs in the first ~20 generations (exploration phase), followed by plateau refinement (exploitation phase).
The smooth asymptotic curve shows healthy population convergence without premature stagnation. The gap between average and elite fitness narrows over time, indicating the entire population is being pulled toward high-quality regions of the search space.
The convergence of both curves toward ~830 absolute worth by generation 60-70 demonstrates the algorithm's ability to balance exploration and exploitation — a hallmark of well-tuned evolutionary strategies.
knapsack-problem-solved-with-evolutionary-strategy-Genetic-algorithm-in-python/
│
├── knapsack with GA.py # Core GA engine (single-file, zero dependencies beyond matplotlib)
├── docs/
│ └── ALGORITHM.md # Deep-dive: mathematical foundations & complexity analysis
├── requirements.txt # Python dependencies
├── LICENSE # Apache 2.0
└── README.md # You are here
class Chromosome:
"""Encapsulates a candidate solution as a binary vector with cached fitness metrics."""
solution: List[int] # Binary encoding [0,1,1,0,...]
value: int # Σ selected item values
weight: int # Σ selected item weights
absoluteWorth: float # Composite fitness score
class GeneticSolver:
"""Orchestrates the full evolutionary optimization loop."""
# Hyperparameters: populationSize, generationCount, mutationRate, itemCount, threshold
# Core methods: initialPopulation(), crossOver(), mutate(), lunchEvolution(), solve()# Clone the repository
git clone https://github.com/MohammadAsadolahi/knapsack-problem-solved-with-evolutionary-strategy-Genetic-algorithm-in-python.git
cd knapsack-problem-solved-with-evolutionary-strategy-Genetic-algorithm-in-python
# Install dependencies
pip install -r requirements.txt
# Run the optimizer
python "knapsack with GA.py"The solver will output generational statistics to the console and display three matplotlib visualizations upon completion.
Tune the GA by modifying the constructor parameters:
# GeneticSolver(populationSize, generationCount, mutationRate, itemCount, threshold)
GeneticSolver(10, 100, 20, 20, 400) # Default: balanced exploration/exploitation
GeneticSolver(6, 200, 10, 10, 100) # Small instance: fewer items, more generations
GeneticSolver(10, 80, 10, 25, 600) # Large instance: more items, higher capacity| Parameter | Symbol | Description | Trade-off |
|---|---|---|---|
populationSize |
Individuals per generation | Diversity ↔ Computation | |
generationCount |
Evolutionary iterations | Convergence quality ↔ Runtime | |
mutationRate |
Mutation probability (%) | Exploration ↔ Exploitation | |
itemCount |
Number of available items | Problem complexity ( |
|
threshold |
Knapsack weight capacity | Constraint tightness |
For a comprehensive treatment of the mathematical underpinnings, complexity analysis, and connections to the broader evolutionary computation literature, see docs/ALGORITHM.md.
Topics covered:
- Schema Theorem and Building Block Hypothesis
- Convergence guarantees under elitist selection
- Constraint handling in evolutionary optimization
- Connections to simulated annealing and particle swarm optimization
- Computational complexity of the 0/1 Knapsack Problem (Karp, 1972)
Mohammad Asadolahi — Senior Agentic AI Engineer
Focused on Agentic AI Architectures In The Wild.
This project is licensed under the Apache License 2.0 — see LICENSE for details.
Built with evolutionary principles. Optimized by nature.
this readme is AI assisted generated, so check for mistakes


