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

Python实现遗传算法精英保留(Elitism)的字典逻辑问题

遗传算法精英保留逻辑修正

核心问题定位

  • 原代码拼写错误的eletism函数未实现实际精英提取逻辑,仅做了无意义的排序和打印操作
  • 生成下一代种群的逻辑未将当代最优个体纳入下一代,会导致最优解被交叉、变异操作破坏
  • 适应度函数为最小值优化目标,sort_population_by_fitness按升序排列后,最优个体位于列表索引0位置,原代码末尾取[-1]实际拿到的是当代最差个体
  • 原mutate函数边界校验循环的初始标记值设为0,导致边界判断逻辑永远不会触发,变异后坐标可能超出[-2,2]的设定范围
  • Python字典为引用类型,直接赋值会导致精英个体和原种群个体指向同一块内存,后续操作可能意外篡改精英值

具体修正方案

  • 重写精英保留函数,直接从排序后的种群中提取适应度最优的个体,生成独立副本返回
  • 调整下一代生成逻辑:原逻辑固定生成9个新个体(种群总规模为10),在新个体生成完成后将精英个体直接加入下一代列表
  • 修正变异函数的边界校验循环初始标记值,保证变异后坐标始终落在设定边界内
  • 修正迭代结束后全局最优个体的取值索引

修正后完整代码

import random

def generate_population(size, x_boundaries, y_boundaries):
    lower_x_boundary, upper_x_boundary = x_boundaries
    lower_y_boundary, upper_y_boundary = y_boundaries

    population = []
    for i in range(size):
        individual = {
            'x': random.uniform(lower_x_boundary, upper_x_boundary),
            'y': random.uniform(lower_y_boundary, upper_y_boundary),
        }
        population.append(individual)

    return population

def fitness(individual):
    x = individual['x']
    y = individual['y']
    # Rosenbrock函数,最小值为0,在(1,1)处取得
    return abs((-(100*(x*x - y)*(x*x - y) + (1 - x)*(1-x))))

def sort_population_by_fitness(population):
    return sorted(population, key=fitness)
    
def choice_by_roulette(sorted_population, fitness_sum):
    drawn = random.uniform(0, 1)
    accumulated = 0
    
    for individual in sorted_population:
        fitnessX = fitness(individual)
        probability = fitnessX / fitness_sum
        accumulated += probability
        
        if drawn <= accumulated:
            return individual
        
def crossover(choice_a, choice_b):
    xa = choice_a['x']
    ya = choice_a['y']
    
    xb = choice_b['x'] 
    yb = choice_b['y'] 
    
    return {'x': xa+0.01, 'y': ya+0.01}      

def mutate(new_individual):
    x = new_individual['x']
    y = new_individual['y']
    
    # 修正初始标记值,首次进入循环做边界校验
    flagx = 1
    flagy = 1
    
    new_x = x*(1+random.uniform(-0.01/2, 0.01/2))
    new_y = y*(1+random.uniform(-0.01/2, 0.01/2))
    
    while flagx == 1:
        if (new_x > 2) or (new_x < -2):
            new_x = x*(1+random.uniform(-0.01/2, 0.01/2))
            flagx = 1
        else:
            flagx = 0
    
    while flagy == 1:
        if (new_y > 2) or (new_y < -2):
            new_y = y*(1+random.uniform(-0.01/2, 0.01/2))
            flagy = 1
        else:
            flagy = 0
    return {'x': new_x, 'y': new_y}
    
def elitism(sorted_population):
    # 提取升序排列后的第一个个体(适应度最小,即最优),生成副本避免引用篡改
    best_individual = sorted_population[0].copy()
    return best_individual

def make_next_gen(population):
    next_gen = []
    
    sorted_population = sort_population_by_fitness(population)
    soma_fitness = sum(fitness(individual)for individual in population)
    
    # 生成9个新个体,留1个位置给精英
    for i in range(9):
        first_choice = choice_by_roulette(sorted_population, soma_fitness)
        second_choice = choice_by_roulette(sorted_population, soma_fitness)
        
        new_individual = crossover(first_choice, second_choice)
        
        drawn = random.randint(1,5)
        
        if drawn == 1:
            new_individual = mutate(new_individual)
        next_gen.append(new_individual)
    
    # 加入当代精英个体,直接进入下一代
    next_gen.append(elitism(sorted_population))
    return next_gen
        
generations = 100

population = generate_population(size=10, x_boundaries=(-2, 2), y_boundaries=(-2, 2))

i = 0
while i!= generations:
    print(f"=== 第{i}代 ===")
    for individual in population:
        print(individual, fitness(individual))
    
    population = make_next_gen(population)
    i += 1

# 修正最优个体取值:升序排列第一个为最优
best_individual = sort_population_by_fitness(population)[0]
print("=== 迭代结束最优个体 ===")
print(best_individual, fitness(best_individual))

效果说明

修正后每一代的最优个体都会完整保留到下一代,不会被交叉、变异操作丢失,算法会稳定向(1,1)的全局最优解收敛,最终适应度会无限趋近于0。


内容的提问来源于stack exchange,提问作者João Vitor Detoni

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 18:06:18