How to Implement Genetic Algorithms in Python: A Beginner's Guide to AI Optimization

The microsoft/AI-For-Beginners repository provides a complete, NumPy-based genetic algorithm implementation in pure Python that teaches evolutionary optimization through interactive Jupyter notebooks covering the full pipeline from population generation to convergence visualization.

The microsoft/AI-For-Beginners curriculum offers a hands-on approach to learning artificial intelligence concepts through executable code examples. When you want to implement genetic algorithms for Python optimization, the repository's dedicated lesson in lessons/6-Other/21-GeneticAlgorithms/ delivers a modular, beginner-friendly framework using only standard library and NumPy dependencies.

Genetic Algorithm Architecture in the AI-For-Beginners Repository

The genetic algorithm implementation follows a layered architecture that separates theoretical concepts from practical execution. According to the source code in lessons/6-Other/21-GeneticAlgorithms/Genetic.ipynb, the system consists of four tightly coupled functional layers: population generation, fitness evaluation, genetic operators, and evolutionary selection.

Core Components and File Structure

The lesson organizes its resources across three primary files:

  • lessons/6-Other/21-GeneticAlgorithms/README.md — Contains the narrative overview, theoretical background on evolutionary computation, and terminology definitions (genes, chromosomes, crossover, mutation).
  • lessons/6-Other/21-GeneticAlgorithms/Genetic.ipynb — Houses the complete executable implementation, including the genetic() and evolve() driver functions, helper utilities, and matplotlib visualizations.
  • lessons/6-Other/21-GeneticAlgorithms/Diophantine.ipynb — Provides an assignment applying the framework to solve Diophantine equations, demonstrating extensibility.

Step-by-Step Implementation of the Genetic Algorithm Pipeline

The repository teaches genetic algorithms through six discrete stages that mirror biological evolution. Each stage maps to specific Python functions within the notebook.

Population Initialization with generate and generate_one

The algorithm begins by creating random candidate solutions. The generate_one(N) function produces a random permutation of integers from 1 to N, serving as the gene sequence for problems like the N-Queens puzzle. The generate(N) utility creates multiple candidates by repeated invocation.

import numpy as np, random

def generate_one(N):
    """Create a random permutation of 1..N."""
    x = np.arange(1, N + 1)
    np.random.shuffle(x)
    return x

Fitness Evaluation Using fit

Every candidate requires a quantitative quality measure. The fit(L) function evaluates the N-Queens problem by counting attacking queen pairs, returning lower values for better solutions.

def fit(L):
    """Count the number of attacking queen pairs."""
    attacks = 0
    for i1, j1 in enumerate(L, 1):
        for i2, j2 in enumerate(L, 1):
            if i2 > i1:
                if j2 == j1 or abs(j2 - j1) == i2 - i1:
                    attacks += 1
    return attacks

Selection Strategies with choose and choose_rand

Selection pressure drives evolution toward optimal solutions. The repository implements two fitness-proportionate selectors that compute normalized weight vectors from inverse fitness values:

  • choose_rand — Probability-weighted random selection
  • choose — Deterministic fitness-proportionate selection

Both functions calculate selection probabilities using [1 / (f + 1) for _, f in P] to favor lower fitness scores (minimization problems).

Genetic Operators: mutate and xover

Variation introduces genetic diversity. The mutate(G) function randomly replaces a single gene value, while xover(G1, G2) performs single-point crossover by concatenating slices from two parent chromosomes.

def mutate(G):
    """Replace a random gene with a random value."""
    idx = random.randint(0, len(G) - 1)
    G[idx] = random.randint(1, len(G))
    return G

def xover(G1, G2):
    """Single-point crossover."""
    cut = random.randint(0, len(G1))
    return np.concatenate((G1[:cut], G2[cut:]))

The Evolution Loop: genetic, evolve, and nxgeneration

The genetic(N, pop_size=100) function orchestrates the evolutionary process alongside the evolve() helper. It initializes the population, then iteratively applies selection, crossover, and mutation until reaching a fitness of zero or exhausting the generation limit. The nxgeneration helper manages population replacement between iterations.

def genetic(N, pop_size=100):
    # initialise population

    P = [(generate_one(N), fit(generate_one(N))) for _ in range(pop_size)]
    while min(f for _, f in P) > 0:
        # create next generation

        new_pop = []
        for _ in range(pop_size):
            i, j = np.random.choice(len(P), 2, replace=False,
                                   p=[1 / (f + 1) for _, f in P])
            child = xover(P[i][0], P[j][0])
            if random.random() < 0.1:
                child = mutate(child)
            new_pop.append((child, fit(child)))
        P = new_pop
    # return the best solution

    return min(P, key=lambda x: x[1])

Visualizing Convergence and Results

After execution, the notebook plots optimization progress using matplotlib. The history tracking reveals convergence speed and population diversity over time.

import matplotlib.pyplot as plt

solution, history = genetic(8)
plt.plot(history)
plt.title('Best fitness per generation')
plt.xlabel('Generation')
plt.ylabel('Fitness')
plt.show()

Extending the Framework for Custom Optimization Problems

The modular design in Genetic.ipynb allows beginners to adapt the engine for various domains. By swapping the fitness function in fit(), changing the gene representation in generate_one(), or adjusting the mutation probability (currently set to 0.1), learners can tackle scheduling problems, knapsack optimization, or Sudoku solving. The Diophantine.ipynb notebook demonstrates this extensibility by applying the same pipeline to find integer solutions to polynomial equations.

Summary

  • The microsoft/AI-For-Beginners repository provides a complete genetic algorithm implementation in lessons/6-Other/21-GeneticAlgorithms/Genetic.ipynb using pure Python and NumPy.
  • The pipeline consists of six stages: encoding (generate, generate_one), fitness evaluation (fit), selection (choose_rand, choose), crossover (xover), mutation (mutate), and replacement (nxgeneration).
  • The genetic() and evolve() functions serve as the main entry points, running the evolution loop until convergence or generation limits.
  • Visualization utilities track fitness history to confirm optimization progress.
  • The framework requires no external dependencies beyond NumPy, making it accessible for beginners experimenting with AI optimization.

Frequently Asked Questions

What makes the AI-For-Beginners genetic algorithm implementation suitable for beginners?

The implementation uses only Python standard library and NumPy, with explicit function names like generate_one, mutate, and xover that correspond directly to genetic algorithm theory. The Jupyter notebook format allows interactive execution and immediate visualization of results, while the modular structure lets learners modify individual components without breaking the entire pipeline.

How does the selection mechanism work in this genetic algorithm?

The selection process uses fitness-proportionate probability calculated via inverse fitness values [1 / (f + 1) for _, f in P]. The np.random.choice() function samples parent indices based on these weights, ensuring higher-fitness (lower numerical value) individuals have greater reproductive probability while maintaining population diversity through probabilistic selection.

Can this code solve optimization problems other than N-Queens?

Yes. The repository includes Diophantine.ipynb which adapts the same framework to solve Diophantine equations. By modifying the fit() function to return a different metric and adjusting generate_one() to produce valid candidate structures, you can apply this genetic algorithm to scheduling, routing, bin packing, or constraint satisfaction problems.

What is the time complexity of the genetic algorithm implementation?

The complexity depends on the fitness function and population parameters. For the N-Queens implementation, each fitness evaluation runs in O(N²) time due to the pairwise comparison loop. With population size P and generation count G, the total complexity is O(G × P × N²). The algorithm terminates early if it finds a perfect solution (fitness = 0) before reaching the generation limit.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →