A mutation operator introduces random variation into an offspring’s encoded solution after crossover. In a genetic algorithm, it gives evolution a way to produce traits not directly inherited from either parent, while fitness evaluation determines whether those altered individuals remain useful in later generations. section 2.5.7 section 2.5.8
The simplest form works gene by gene: test each position against a mutation rate, then alter the selected value. For a binary encoding, alteration can mean flipping 0 to 1 or 1 to 0. A 50% rate is used to test the function, but practical rates are generally below 5%. Lower rates favor steadier progress that can get stuck; higher rates add randomness and may not stabilize. section 2.5.7
Mutating a binary individual
Loop through an individual’s genes. When a random draw falls below mutation_rate, replace each selected bit with 1 - bit. Apply the resulting individual as a child in the next generation, then inspect maximum, minimum, mean, and standard-deviation fitness across the population. section 2.5.7 section 2.5.8
Mutation must match the encoding. A simple life simulation perturbs numeric traits within a fixed range. For custom neural-network gene sequences, a custom operator can locate encoded layer blocks and change only their valid hyperparameters, such as filter counts, kernel sizes, or dropout values. Length checks and exceptions help detect corrupt blocks; adding or removing layer blocks is a further extension. section 2.4.1 section 7.4 section 8.3
Useful experiments include:
- Change the mutation rate and rerun evolution repeatedly to observe its effect on cell traits. section 2.4.2
- Modify a fitness equation or add an encoded attribute, then update mutation alongside initialization and evaluation. section 2.4.2
- Alter genetic-operator parameters and compare runs with fewer operators. section 4.1.2
Listing 7.16 EDL_7_4_Mutation_CNN.ipynb: A custom mutation operator
def mutation(ind):
if len(ind) > CONV_LAYER_LEN: #1
ind = mutate_layers(ind, CONV_LAYER, #2
CONV_LAYER_LEN) #2
ind = mutate_layers(ind, DENSE_LAYER, #2
DENSE_LAYER_LEN) #2
ind = mutate_layers(ind, POOLING_LAYER, #2
POOLING_LAYER_LEN) #2
return ind, #3
This custom CNN operator dispatches mutation across convolution, dense, and pooling layer groups, returning the modified individual in the DEAP-required tuple form. section 7.4

