用python写一个简单的遗传算法的demo

bluesky1年前 ⋅ 791 阅读
# 遗传算法尝试解决最优化问题,用于解决有限解空间下的复杂问题。

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()

全部评论: 0

    相关推荐