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

DEAP框架下如何高效获取每一代最优个体以实现动画展示?

优化DEAP获取每代最优个体的方法

你的代码耗时的核心问题是重复计算了个体的适应度(tspDistance),而且自定义的过滤逻辑效率低下。以下是两种更高效的实现方式:

方法一:优化Statistics统计逻辑,复用已计算的适应度

利用DEAP内置的tools.selBest直接从种群中选择最优个体,避免重复计算适应度:

import numpy as np
from deap import tools, algorithms

# 初始化适应度统计
stats = tools.Statistics(lambda ind: ind.fitness.values)
stats.register('min', np.min)
stats.register('mean', np.mean)

# 初始化最优个体统计:用selBest直接选种群中最优的1个个体
history = tools.Statistics(lambda ind: ind)
# 注意:如果你的TSP是求最小距离,需确保适应度是负数(因为DEAP默认最大化适应度)
# 若适应度已经是最小化的(比如直接返回距离),则需要修改selBest的排序逻辑:
# history.register('best_ind', lambda pop: tools.selBest(pop, 1, fit_func=lambda ind: -ind.fitness.values[0])[0])
history.register('best_ind', lambda pop: tools.selBest(pop, 1)[0])

mstats = tools.MultiStatistics(fitness=stats, history=history)

hof = tools.HallOfFame(consts.HALL_OF_FAME_SIZE)

population, logbook = algorithms.eaSimple(population, toolbox,
                                          cxpb=consts.P_CROSSOVER, mutpb=consts.P_MUTATION,
                                          ngen=consts.MAX_GENERATIONS, stats=mstats,
                                          halloffame=hof, verbose=True)

# 从logbook中提取每一代的最优个体
best_individuals = [record['history']['best_ind'] for record in logbook]

方法二:利用HallOfFame+自定义钩子函数

HallOfFame会自动维护每一代的最优个体,你可以在每代结束后直接记录其中的最优个体:

from deap import tools, algorithms

hof = tools.HallOfFame(consts.HALL_OF_FAME_SIZE)
best_individuals = []

# 定义每代结束后的回调函数
def log_best(population, *args, **kwargs):
    # HallOfFame的第一个元素就是当前全局最优,若要每代的种群最优则用selBest
    best_individuals.append(hof[0])

# 自定义eaSimple的循环(替代原algorithms.eaSimple调用)
population = toolbox.population(n=consts.POPULATION_SIZE)
logbook = tools.Logbook()
logbook.header = ['gen', 'nevals'] + (stats.fields if stats else [])

for gen in range(consts.MAX_GENERATIONS):
    # 选择、交叉、变异
    offspring = algorithms.varAnd(population, toolbox, cxpb=consts.P_CROSSOVER, mutpb=consts.P_MUTATION)
    # 评估后代
    fits = toolbox.map(toolbox.evaluate, offspring)
    for fit, ind in zip(fits, offspring):
        ind.fitness.values = fit
    # 更新HallOfFame
    hof.update(offspring)
    # 记录当前最优
    log_best(offspring)
    # 替换种群
    population = offspring
    # 编译统计数据
    record = stats.compile(population) if stats else {}
    logbook.record(gen=gen, nevals=len(offspring), **record)
    if verbose:
        print(logbook.stream)

关键优化点

  1. 避免重复计算适应度:不要在统计函数中再次调用tspDistance,直接使用个体已存储的ind.fitness.values,这是最影响性能的点。
  2. 使用内置高效函数:tools.selBest是DEAP优化过的选择函数,比自定义的filter+lambda逻辑快得多。
  3. 合理利用HallOfFame:它会自动维护历史最优个体,无需手动遍历种群查找。

内容的提问来源于stack exchange,提问作者Vya4eslav

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 01:34:53