import random from deap import creator, base, tools, algorithms import numpy as np creator.create("FitnessMax", base.Fitness, weights=(1.0,)) creator.create("Individual", np.ndarray, fitness=creator.FitnessMax) toolbox = base.Toolbox() #toolbox.register("attr_bool", random.randint, 0, 1) # non-numpy non-float version toolbox.register("attr_float", random.random) toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_float, n=100) toolbox.register("population", tools.initRepeat, list, toolbox.individual) def linearFitness(individual): '''selection pressure for genome values to be numpy.arange(start=0.0, stop=1.0, step=1/len(genome))''' import numpy as np a = np.arange(0, 1, 1.0/len(individual)) b = np.array(individual) return 1.0-np.sum(np.abs(a-b))/(len(individual)*0.5), def cxTwoPointCopy(ind1, ind2): """Execute a two points crossover with copy on the input individuals. The copy is required because the slicing in numpy returns a view of the data, which leads to a self overwriting in the swap operation. It prevents :: >>> import numpy as np >>> a = np.array((1,2,3,4)) >>> b = np.array((5,6,7,8)) >>> a[1:3], b[1:3] = b[1:3], a[1:3] >>> print(a) [1 6 7 4] >>> print(b) [5 6 7 8] """ size = len(ind1) cxpoint1 = random.randint(1, size) cxpoint2 = random.randint(1, size - 1) if cxpoint2 >= cxpoint1: cxpoint2 += 1 else: # Swap the two cx points cxpoint1, cxpoint2 = cxpoint2, cxpoint1 ind1[cxpoint1:cxpoint2], ind2[cxpoint1:cxpoint2] = ind2[cxpoint1:cxpoint2].copy(), ind1[cxpoint1:cxpoint2].copy() return ind1, ind2 toolbox.register("evaluate", linearFitness) #toolbox.register("mate", tools.cxTwoPoint) # non-numpy non-float version toolbox.register("mate", cxTwoPointCopy) #toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) # non-numpy non-float version toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=0.2, indpb=0.05) toolbox.register("select", tools.selTournament, tournsize=3) # evolution loop population = toolbox.population(n=100) NGEN=500 for gen in range(NGEN): offspring = algorithms.varAnd(population, toolbox, cxpb=0.5, mutpb=0.1) # constrain genome values to [0,1] for offspring_i,individual in enumerate(offspring): np.clip(np.array(offspring[offspring_i]), 0.0, 1.0) # Evaluate the individuals with an invalid fitness (not yet evaluated) invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit population = toolbox.select(offspring, k=len(population)) # post-evolution analysis fitnesses = toolbox.map(toolbox.evaluate, population) sortedFitnesses = sorted(fitnesses) bestFitness, worstFitness = sortedFitnesses[0], sortedFitnesses[-1] print(bestFitness, worstFitness) bestGenome = tools.selBest(population, k=1) print(bestGenome)