Overview of Genetic Algorithms

Hello, this is the live document on genetic algorithms. I plan to edit this post as I gather more information about it.

This post was last updated September 23rd 2025.

What is a Genetic Algorithm

A genetic algorithm (GA) is a type of search based algorithm where solutions ‘evolve’ towards an optimal or sub-optimal solution using a simplified model of natural evolution. A genetic algorithm starts by randomly generating a set (“population”) of potential solutions (“individuals” or “chromosomes”) and evaluating how well they preform based on some “fitness function.” During each step (“generation”) of the algorithm, individuals from the population are randomly chosen as “parents” weighted by their fitness using a selection function (higher fitness individuals are chosen at a higher rate then less fit individuals). These parents are randomly modified (“mutated”) and combined (“cross-over”) to produce “children” that are added to the population to be chosen as parents for the next generation. Overtime the population consists of more fit individuals, due to high fitness individuals being chosen at a higher rate.

Terms

Here are the key terms that are used in Genetic Algorithms

Fundamental Example

In this section I will go into depth on a simple example genetic algorithm to demonstrate the key concepts. Note that most GAs are more complex than this example, and GA should only be implemented for more complex problem spaces.

Problem Space

For this example we will look at evolving bit strings to maximize the number of 1s in the string.

Algorithms

Below I will provide pseudo-code for the algorithms used in this example

Generate Random

def generate():
    str = "" 
    for i in range(N):
        char = choose(from =[0, 1], weights=[0.5, 0.5])
        str += char 
    return str 

Mutation

def mutate(individual, mut_rate): 
    child = ""
    for char in individual: 
        if coin_flip(mut_rate): 
           char = flip(char)
        
        child += char 
    return child

Cross Over

def cross_over(parent1, parent2): 
    i = random_integer(0, N-1)
    child1 = parent1[0, i] + parent2[i + 1, N -1]
    child2 = parent1[0, i] + parent2[i + 1, N -1]

    return child1, child2 

Fitness

def fitness(individual):
    fit = 0 
    for char in individual: 
        if char == 1: 
            fit += 1 
    
    return fit 

Selection

def select(population):
    total = sum(i.fitness for i in population)
    for i in population: 
        i.weight = i.fitness / total 

    return choose(from=population, weights = [i.weight for i in population]) 

** Genetic Algorithm**

def evolve(gens, popsize, mut_rate, x_rate):
    population = [generate() for i in range(popsize)]

    for gen in gens:
        new_pop = []
        while length(new_pop)  < popsize:
            parent1 = select(population)
            parent2 = select(population)

            if coin_flip(x_rate):
                child1, child2 = cross_over(parent1, parent2)
            else: 
                child1, child2 = parent1, parent2
            new_pop += [child1, child2]

        population = new_pop 
    return population  
        

Genetic Algorithm Variations

There are many different ways to modify this basic version of a genetic algorithm to be better suited for different needs. All parts of the genetic algorithm can be adjusted depending on the problem space you are working in. Here are some example of the most common variations for GAs. Note that many of these variations can, and have, been combined to serve different purposes.

Modifying the Population Structure

Modifying the Individual Representation

Modifying the Fitness Function

MSC.

Read More

Here I will collect valuable citations if you want to learn more about Genetic Algorithms