使用PyGAD时自定义罚函数生效、幂次罚函数失效的原因是什么?
罚函数生效与失效原因分析
1. 自定义lgt罚函数生效原理
PyGAD的遗传算法默认执行适应度最大化策略,会优先保留适应度得分更高的解进入下一代,你的lgt罚函数恰好匹配了这个逻辑,核心有两点:
- 足够强的区分度:所有落在[14,99]区间外的解,返回值为
-10000 + x,这个值最高也只有当x无限接近99时的-10000 + 99 = -9901,远低于区间内解的最低返回值14,所以区间外的解天然就会在选择阶段被优先淘汰,筛选压力足够大。 - 带方向的梯度引导:惩罚值和x本身线性相关,比如x=12(小于14)的罚后值是
-9988,x=13(更接近区间下界)的罚后值是-9987,后者得分更高,算法会明确知道“x增大”是更优的调整方向;你设置的初始种群范围是[-50,50],几乎不会出现x超过99的情况,因此这个线性引导在你的测试场景下完全匹配优化方向。
你提到的罚值越负收敛越快,本质是增大了区间内外解的得分差距,筛选压力更高,不符合要求的解几乎没有概率进入下一代,收敛速度自然提升。
2. 其他罚函数失效原因
2.1 (x+100)^4类罚函数失效原因
这个罚函数完全违背了适应度最大化的优化方向:
- 如果你直接用
(x+100)^4作为惩罚值,x越小这个值越大,反而会让区间外的解得分比区间内的解高得多,算法会优先保留更小的x,完全和优化目标相反。 - 就算你加了负号改成
-(x+100)^4,也会出现x越接近区间下界、惩罚后得分越低的情况:比如x=13的罚后值是-(113)^4 ≈ -1.6e8,x=10的罚后值是-(110)^4 ≈ -1.46e8,反而x越小得分越高,引导方向完全错误,自然无法生效。
2.2 符合返回x否则返回0的罚函数失效原因
这类罚函数没有提供梯度引导信息:所有落在区间外的解,不管是x=-50还是x=13,得分都是0,没有任何得分差异,算法无法判断往哪个方向调整才能得到更高的分数,也就无法引导种群向目标区间迁移,自然没有效果。
额外注意
你提供的代码里有一处错误:适应度函数中用到的function_inputs变量没有定义,你要计算平均值的话直接用numpy.average(solution)即可,否则代码无法正常运行。
内容的提问来源于stack exchange,提问作者Roi
相关产品推荐
相关产品推荐

