遗传算法迭代后期适应度无提升问题排查求助
遗传算法优化震荡与停滞问题排查
我编写了一个简单的遗传算法,目标是最小化平方和形式的适应度函数,但运行后发现优化结果出现震荡,且迭代后期适应度分数无提升,代码如下,恳请帮忙排查问题:
适应度函数
def fitness(a, b, c, d, e): return a**2 + b**2 + c**2 + d**2 + e**2
初始种群生成函数
def generate_pop(numInd, numGene): population = [] for i in range(numInd): individual = [random.uniform(-10, 10) for _ in range(numGene)] population.append(individual) return population
选择与交叉函数
def randomCrossover(population): offspring = [] for i in range(len(population)//2): Ind1_index = random.randint(0, len(population)-1) Ind2_index = random.randint(0, len(population)-1) while Ind2_index == Ind1_index: Ind2_index = random.randint(0, len(population)-1) Ind1 = population[Ind1_index] Ind2 = population[Ind2_index] crossPoint = random.randint(1, len(Ind1)) child1 = Ind1[:crossPoint] + Ind2[crossPoint:] child2 = Ind2[:crossPoint] + Ind1[crossPoint:] offspring.append(child1) offspring.append(child2) return offspring
主函数
def geneticAlgorithm(mutation=0.1, numGeneration=100): population = generate_pop(12, 5) maxFitnessScoreGen = [] minFitnessScoreGen = [] avgFitnessScoreGen = [] for _ in range(numGeneration): fitScore = [fitness(a, b, c, d, e) for a, b, c, d, e in population] maxFitnessScoreGen.append(max(fitScore)) minFitnessScoreGen.append(min(fitScore)) avgFitnessScoreGen.append(mean(fitScore)) # population = [population[i] for i in range(len(population)) if fitness[i] == min(fitness)] # should individual that have lowest fitness score offspring = randomCrossover(population) for i in range(len(offspring)): if random.uniform(0, 1) < mutation: offspring[i] = [random.uniform(-10, 10), random.uniform(-10, 10), random.uniform(-10, 10), random.uniform(-10, 10), random.uniform(-10, 10)] population = offspring # print(f'gen {_} maxScore = {maxFitnessScoreGen}, avgScore = {avgFitnessScoreGen}') # print(population) return maxFitnessScoreGen, minFitnessScoreGen ,avgFitnessScoreGen
适应度分数变化图

问题根源与修正建议
1. 核心问题:无适应度导向的选择机制
当前的randomCrossover完全随机挑选父代个体,完全不考虑个体的适应度好坏,本质是随机搜索而非遗传算法——优秀个体的基因没有被优先传递,种群无法朝着最优解收敛,自然会出现震荡。
2. 突变操作过于激进
现在的突变是直接生成全新的随机个体,彻底丢弃原个体的所有基因信息,相当于每次突变都引入完全随机的噪声源,破坏种群中积累的优良特性,导致震荡加剧,无法稳定收敛。
3. 无精英保留策略
每次迭代直接用后代替换全部父代,父代中适应度最低的优秀个体很容易被淘汰,优秀基因无法保留,种群失去进化的基础。
4. 未启用适应度选择逻辑
代码中注释了基于最小适应度的选择逻辑,但未实际启用,进一步导致种群进化失去方向。
具体修正方案
- 添加适应度导向的选择:比如用锦标赛选择,每次从种群中随机选3-5个个体,挑选适应度最低的作为父代;或者用轮盘赌选择(注意因为是最小化问题,需要将适应度取倒数转换为“收益”)。
- 修改突变逻辑:改为对个体的单个基因进行小幅扰动,而非生成全新个体:
if random.uniform(0, 1) < mutation: # 随机选一个基因进行小幅扰动 gene_idx = random.randint(0, len(offspring[i])-1) offspring[i][gene_idx] += random.uniform(-0.5, 0.5) # 限制基因在[-10,10]范围内 offspring[i][gene_idx] = max(min(offspring[i][gene_idx], 10), -10) - 加入精英保留:每次迭代保留父代中适应度最低的2-3个个体,加入到下一代种群中:
# 在生成后代后,保留父代精英 elite_num = 2 # 按适应度排序,取前elite_num个适应度最低的个体 sorted_pop = [ind for _, ind in sorted(zip(fitScore, population), key=lambda x: x[0])] elites = sorted_pop[:elite_num] # 替换后代中随机个体,保持种群规模 population = elites + offspring[elite_num:] - 启用选择逻辑:替换原有的随机交叉选择,用基于适应度的选择来挑选父代。
内容的提问来源于stack exchange,提问作者P.Chian
相关产品推荐
相关产品推荐

