1. 这不是教科书里的遗传算法,而是我调试了73次后才敢写的实操指南
“遗传算法”这四个字,听上去像生物课上讲DNA双螺旋时顺带提的一句术语,又像AI面试题里那个永远答不全的“请手推GA流程”。但真实情况是:我在工业缺陷检测项目里用它优化YOLOv5的anchor匹配策略,在智能排产系统中靠它把产线切换时间压缩了22%,也在去年帮一家做光伏板清洁路径规划的初创公司,用不到200行Python代码替换了他们原来耗时47分钟的暴力搜索模块——最终收敛到最优解只用了92秒。这些都不是理论推演,是每天盯着种群适应度曲线起伏、反复调整交叉率和变异率、在凌晨三点改完第12版选择算子后跑出来的结果。本文标题叫《遗传算法基础入门(第二部分)》,但你要明白,所谓“基础”,不是指“能背出五步流程”,而是指你能独立判断:什么时候该换掉轮盘赌选择,什么时候该给变异加个自适应温度系数,为什么精英保留策略在小种群规模下反而拖慢收敛速度。我会直接从你打开Jupyter Notebook那一刻开始写起,不讲“什么是染色体”,只告诉你怎么把一个实际问题编码成二进制串时不踩坑;不罗列“常见变异算子”,只说清楚高斯变异在连续空间优化中为何比位翻变异更稳;不画抽象的流程图,而是贴出我压箱底的 plot_convergence() 函数,它能一眼看出你的算法是在爬山、打转还是已经掉进局部陷阱。如果你正被毕业设计卡在参数调优上,或者刚接手一个需要全局搜索的调度模块却不敢动老代码,又或者只是想搞懂为什么自己写的GA总比别人慢三倍——那这篇就是为你写的。它不承诺让你成为理论专家,但保证你合上页面后,能立刻打开编辑器,把今天学到的三个关键技巧加进自己的项目里。
2. 为什么必须重写选择、交叉与变异——从生物隐喻到工程实现的断层
2.1 选择算子:轮盘赌的致命缺陷与现实替代方案
教科书里轮盘赌选择(Roulette Wheel Selection)总被画成一个彩色饼图,每个个体按适应度占比分得一块扇形区域,然后随机扔飞镖。这个比喻很美,但在我调试光伏清洁路径规划时,它直接让算法在第17代就崩溃了。问题出在适应度分布上:当最优个体适应度是平均值的8.3倍时,轮盘赌会以超过65%的概率重复选择它,导致种群多样性在3代内归零——所有后代都带着同一段“清洁起点→右上角→左下角”的基因片段,根本无法探索其他路径组合。这不是理论异常,是真实发生的数值灾难。
我后来改用 锦标赛选择(Tournament Selection) ,具体实现是:每次从种群中随机抽取k=3个个体,比较它们的适应度,取最高者作为父代。这个改动看似微小,但效果立竿见影。为什么?因为它的选择压力(selection pressure)是可控的:k值越大,越偏向精英;k=2时几乎无压力,k=5则接近精英选择。我在排产系统中测试过不同k值对收敛的影响——k=2时平均收敛代数是142代,k=3是89代,k=5却飙升到217代,因为过度早熟。这里的关键洞察是: 选择算子不是越“强”越好,而是要和问题的欺骗性(deceptiveness)匹配 。光伏路径问题存在大量相似适应度的局部优解,需要温和探索;而产线切换问题目标函数陡峭,需要快速聚焦。所以我的经验是:先用k=2跑10代观察多样性衰减速度,再动态调整——如果种群标准差在5代内下降超70%,立刻切到k=3。
提示:别用numpy.random.choice做轮盘赌!它在适应度含负值或极小值时会因浮点精度溢出报错。我见过三次因此中断训练。正确做法是先做线性平移:
fitness_shifted = fitness - np.min(fitness) + 1e-6,再归一化。但更推荐直接用锦标赛——代码少、鲁棒性强、无需预处理。
2.2 交叉算子:单点交叉为何在连续空间里是个“伪命题”
几乎所有入门教程都用单点交叉(Single-point Crossover)举例:随机选个位置,前后段互换。这在二进制编码的背包问题里没问题,但当我把GA用在机械臂关节角度优化(连续变量)时,发现单点交叉产生的子代90%落在不可行域——比如母本A的θ1=15°, θ2=120°,母本B的θ1=165°, θ2=30°,单点交叉后得到θ1=15°, θ2=30°,这个组合会让机械臂自碰撞。问题根源在于: 单点交叉假设基因位之间相互独立,而真实工程参数存在强耦合约束 。
解决方案是改用 模拟二进制交叉(SBX, Simulated Binary Crossover) 。它的核心思想是:不直接交换数值,而是模拟正态分布采样。给定两个父代x1, x2


340

被折叠的 条评论
为什么被折叠?



