# 遗传算法尝试解决最优化问题,用于解决有限解空间下的复杂问题。 import random from collections import namedtuple # 定义遗传算法一般需要定义的变量 POP_SIZE = 10 GENERATIONS = 20 # 定义遗传算法一些参数 GeneSet = [1,0] # 可取值有[0,1] target = 15 # 要求得到的结果 # 定义运行单元population # population的参数分别是 genes(基因序列), fitness(个体适应度) class Individual(object): def __init__(self, genes): self.genes = genes self.fitness = self.cal_fitness() def cal_fitness(self): fitness = 0 for gene in self.genes: if gene == 1: fitness += 1 return fitness def generate_parent(): genes = [] for i in range(len(target)): gene = random.choice(GeneSet) genes.append(gene) parent = Individual(genes=genes) return parent # 多次交叉与变异 def mutate(parent): childGenes = parent.genes.copy() index = random.randrange(0, len(target)) newGene, alternate = random.choice(GeneSet) childGenes[index] = alternate if newGene == childGenes[index] else newGene child = Individual(genes=childGenes) return child def crossover(parent_a, parent_b): childGenes = [] for index in range(len(target)): prob = random.random() if prob < 0.45: gene = parent_a.genes[index] childGenes.append(gene) elif prob < 0.90: gene = parent_b.genes[index] childGenes.append(gene) else: gene = random.choice(GeneSet) childGenes.append(gene) child = Individual(genes=childGenes) return child def get_best(population): fitnesses = [individual.fitness for individual in population] best_fitness_index = fitnesses.index(max(fitnesses)) return population[best_fitness_index] # 主函数 def genetic_alg(): population = [generate_parent() for _ in range(POP_SIZE)] for generation in range(GENERATIONS): print("="*20) print("Generation {} :".format(generation)) population = sorted(population, key=lambda individual: individual.fitness) print("Best individual from current population : {}".format(population[-1].fitness)) for individual in population: print("Genes : {}, Fitness : {}".format(str(individual.genes),str(individual.fitness))) if population[-1].fitness >= target: break parents = population[:int(POP_SIZE/2)] # 选择后半部分个体作为父母 offsprings = [crossover(parent_a, parent_b) for parent_a, parent_b in zip(parents,parents[1:])] population = parents + offsprings population = [mutate(individual) for individual in population] population = sorted(population, key=lambda individual:individual.fitness,reverse=True)[:10] best_individual = get_best(population) print("\nSolution found : Genes :",str(best_individual.genes)) print("Fitness :",str(best_individual.fitness)) if __name__ == '__main__': genetic_alg()