Pygad优化遇局部最优:如何检测适应度饱和后重初始化种群?
在PyGad中实现停滞种群重启的方案
完全可以实现你需要的逻辑,核心是在on_generation回调中追踪适应度停滞情况,直接修改PyGad实例的population属性完成种群重置。以下是具体实现步骤和代码示例:
核心思路
- 追踪连续世代的适应度变化,统计停滞次数
- 当停滞次数达到设定阈值时,调用PyGad内置的种群初始化方法生成新种群,直接替换当前实例的
population属性 - 重置停滞统计,继续后续世代的进化
代码实现
import pygad import numpy as np # 全局变量记录停滞状态 stagnation_count = 0 best_fitness_history = [] # 自定义停滞阈值:连续N代适应度无有效提升则重启 STAGNATION_THRESHOLD = 5 # 适应度变化阈值:小于该值视为无有效提升 FITNESS_EPS = 1e-6 def fitness_func(solution, solution_idx): # 替换为你的实际适应度计算逻辑 return -np.sum(np.square(solution)) # 示例:求解最小值问题,返回负的平方和 def on_generation(pygad_instance): global stagnation_count, best_fitness_history # 获取当前世代的最优适应度 current_best_fitness = pygad_instance.best_solution()[1] best_fitness_history.append(current_best_fitness) # 检查是否出现停滞 if len(best_fitness_history) >= 2: fitness_diff = abs(current_best_fitness - best_fitness_history[-2]) if fitness_diff < FITNESS_EPS: stagnation_count += 1 else: # 适应度有提升,重置停滞计数 stagnation_count = 0 # 达到停滞阈值,执行种群重启 if stagnation_count >= STAGNATION_THRESHOLD: print(f"世代 {pygad_instance.generations_completed} 触发停滞,重启种群") # 用当前实例的参数重新初始化种群 new_population = pygad_instance.initialize_population() # 直接替换实例的population属性 pygad_instance.population = new_population # 重置停滞统计状态 stagnation_count = 0 best_fitness_history = [] # 初始化遗传算法实例 ga_instance = pygad.GA( num_generations=100, num_parents_mating=4, fitness_func=fitness_func, sol_per_pop=20, num_genes=5, gene_space=[-10, 10], # 替换为你的基因空间定义 on_generation=on_generation ) # 运行算法 ga_instance.run()
关键注意事项
- 适应度阈值调整:
FITNESS_EPS需要根据你的问题场景设置,确保能准确区分“真停滞”和“微小波动” - 自定义种群初始化:如果
initialize_population()的默认逻辑不符合需求,可以手动生成符合gene_space的种群数组,再赋值给pygad_instance.population - 全局变量替代:如果不想用全局变量,可以将停滞状态封装为类属性,或者通过PyGad实例的
user_data字段传递状态信息
内容的提问来源于stack exchange,提问作者Glen Eaton
相关产品推荐
相关产品推荐

