Skip to content

Inconsistent Results in Genetic Programming with Global Random Seed #765

@angelo-xuang

Description

@angelo-xuang

Issue Description

Hi DEAP team,

I'm a beginner using DEAP for genetic programming and have encountered an issue where setting a global random seed (random.seed(1)) does not produce consistent results across multiple runs. Specifically, the results for generation 0 are identical, but starting from generation 1, metrics like average fitness, standard deviation, and number of evaluations differ. I suspect the issue may be related to the selection or crossover processes, as modifying the selRandom function to use a local seed fixed the issue in my tests.

Thank you in advance for your help and for maintaining this amazing library!

Steps to Reproduce

  1. Set up a genetic programming experiment with the following configuration:
    • Random seed: random.seed(1), np.random.seed(1), torch.manual_seed(1)
    • Population size: 1000
    • Generations: 3
    • Selection: tools.selTournament with tournsize=20
    • Crossover: gp.cxOnePoint with probability 0.8
    • Mutation: gp.mutUniform with probability 0.3
  2. Run the experiment multiple times and compare the output metrics (e.g., average fitness, standard deviation, number of evaluations).
  3. Observe that generation 0 metrics are consistent, but subsequent generations differ.

Code Example

Here is the relevant code snippet:

import random
import numpy as np
import torch
from deap import base, creator, tools, gp

# Set random seed
random_state = 1
random.seed(random_state)
np.random.seed(random_state)
torch.manual_seed(random_state)

# Define problem-specific primitives (omitted for brevity)
# Assume pset is a gp.PrimitiveSetTyped object

# Set up DEAP
creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", gp.PrimitiveTree, fitness=creator.FitnessMax)

toolbox = base.Toolbox()
toolbox.register("expr", gp.genHalfAndHalf, pset=pset, min_=1, max_=4)
toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.expr)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
toolbox.register("evaluate", calculate_fitness)  # Custom fitness function (deterministic)
toolbox.register("mate", gp.cxOnePoint)
toolbox.register("expr_mut", gp.genFull, min_=0, max_=2)
toolbox.register("mutate", gp.mutUniform, expr=toolbox.expr_mut, pset=pset)
toolbox.register("select", tools.selTournament, tournsize=20)

# Parameters
population_size = 1000
generations = 3
cxpb = 0.8
mutpb = 0.3
hall_of_fame_size = 10

# Run evolution (e.g., using eaSimple)
pop = toolbox.population(n=population_size)
hof = tools.HallOfFame(hall_of_fame_size)
stats = tools.Statistics(lambda ind: ind.fitness.values)
stats.register("avg", np.mean)
stats.register("std", np.std)
stats.register("min", np.min)
stats.register("max", np.max)
pop, logbook = algorithms.eaSimple(pop, toolbox, cxpb=cxpb, mutpb=mutpb, ngen=generations, stats=stats, halloffame=hof, verbose=True)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions