# 遗传算法尝试解决最优化问题,用于解决有限解空间下的复杂问题。
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()