Code created last time https://qiita.com/nmat0031785/items/ceea6f78ab71e9956fce
The previously used algorithms.eaSimple can only leave statistics for each generation.
Improve so that the design variables and fitness of all individuals can be retained.
First, the fitness is calculated only for the initial individual. After that, the design variable, fitness, generation (0 because it is the initial generation), and individual number are saved in pd.DataFrame.
sample_GA.py
#Generate an early population
pop = toolbox.population_guess()
#Evaluation of fitness of early individuals
fitnesses = toolbox.map(toolbox.evaluate, pop)
for ind, fit in zip(pop, fitnesses):
    ind.fitness.values = fit
fits = [ind.fitness.values[0] for ind in pop]
#Store initial individuals in logbook
logbook = pd.DataFrame([])
t1 = pd.DataFrame(pop)
t1.columns = ["x1", "x2"]
t1 = t1.assign(fits=fits, generation=0, ids=range(len(pop)))
logbook = logbook.append(t1)
Enter the evolution loop. With offspring = toolbox.select (pop, POP_SIZE) , the individuals for POP_SIZE``` are reselected from the initial population pop```. This makes it possible to change the number of initial populations and evolutionary loop populations.  Random numbers are given to individuals of each generation by for minutes, and individuals caught in `` CX_PB and `` `MUT_PB are crossed and targeted for mutation. After that, the fitness is re-evaluated for the new individual and added to pd.DataFrame.
sample_GA.py
#Parameters
N_GEN = 20       #Number of repeating generations
POP_SIZE = 100   #Population in the population
CX_PB = 0.8      #Crossing probability
MUT_PB = 0.05    #Mutation probability
#Evolution loop start
g = 0
while g < N_GEN:
    g = g + 1
    
    #Selection and replication of next-generation individuals
    offspring = toolbox.select(pop, POP_SIZE)
    offspring = list(map(toolbox.clone, offspring))
    #Crossing
    for child1, child2 in zip(offspring[::2], offspring[1::2]):
        #Select individuals to cross
        if random.random() < CX_PB:
            toolbox.mate(child1, child2)
            #Crossed individuals remove fitness
            del child1.fitness.values
            del child2.fitness.values
    #Mutation
    for mutant in offspring:
        #Select an individual to mutate
        if random.random() < MUT_PB:
            toolbox.mutate(mutant)
            #Mutant individuals remove fitness
            del mutant.fitness.values
    #Reassess the fitness of individuals whose fitness has been removed
    invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
    fitnesses = map(toolbox.evaluate, invalid_ind)
    for ind, fit in zip(invalid_ind, fitnesses):
        ind.fitness.values = fit
    
    #Update population with new generation population
    pop[:] = offspring
    #Extraction of fitness of all new generation individuals
    fits = [ind.fitness.values[0] for ind in pop]
    #Store in logbook
    t1 = pd.DataFrame(pop)
    t1.columns = ["x1", "x2"]
    t1 = t1.assign(fits=fits, generation=g, ids=range(POP_SIZE))
    logbook = logbook.append(t1)
    
    #debug
    print(t1)
terminal
・
・
・
-- Generation 20 --
          x1        x2        fits  generation  ids
0  -1.582142 -3.130247 -106.764537          20    0
1  -1.582142 -3.130247 -106.764537          20    1
2  -1.582142 -3.130247 -106.764537          20    2
3  -1.582142 -3.130247 -106.764537          20    3
4  -1.582142 -3.130247 -106.764537          20    4
..       ...       ...         ...         ...  ...
95 -1.582142 -3.130247 -106.764537          20   95
96 -1.582142 -3.130247 -106.764537          20   96
97 -1.582142 -3.130247 -106.764537          20   97
98 -1.582142 -3.130247 -106.764537          20   98
99 -1.582142 -3.130247 -106.764537          20   99
[100 rows x 5 columns]
Save the result as CSV.
sample_GA.py
logbook.to_csv("result.csv", sep=",", index=None, header=None)
Output of design variables and fitness of each individual. Next time until the visualization of the results.
Recommended Posts