You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

遗传算法迭代后期适应度无提升问题排查求助

遗传算法优化震荡与停滞问题排查

我编写了一个简单的遗传算法,目标是最小化平方和形式的适应度函数,但运行后发现优化结果出现震荡,且迭代后期适应度分数无提升,代码如下,恳请帮忙排查问题:

适应度函数

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 15:40:23