第2章 全局优化算法基础:GA、PSO、SA原理

全局优化算法,说白了就是一群「不撞南墙不回头」的搜索策略。它们的目标很明确——在巨大的搜索空间里,找到那个全局最优解。我做了这么多年优化,见过太多人一上来就调参,结果连算法原理都没搞明白。今天咱们就把遗传算法、粒子群优化、模拟退火这三个老大哥讲透。

核心认知:这三种算法都不是「万能钥匙」。GA擅长离散组合优化,PSO在连续空间里跑得快,SA适合跳出局部陷阱。选对工具比调好参数重要十倍。

2.1 遗传算法(GA)——进化论的工程实现

遗传算法的灵感来自达尔文的自然选择。我当年第一次看到这个算法时,心里想的是:「这不就是代码版的物种进化吗?」

2.1.1 核心流程

  1. 编码:把问题的解表示成「染色体」。二进制编码最常见,但实数编码在连续问题上更直接。
  2. 初始化种群:随机生成N个个体。N太小容易早熟,N太大计算量爆炸。我个人习惯取50-200之间。
  3. 适应度评估:算每个个体的好坏。适应度函数就是你的目标函数,但要注意——GA默认找最大值,如果是最小化问题,得做个变换。
  4. 选择:优胜劣汰。轮盘赌、锦标赛、排名选择,各有各的脾气。
  5. 交叉:两个父代交换基因片段。单点交叉、多点交叉、均匀交叉,交叉概率一般设0.7-0.9。
  6. 变异:随机改变基因。变异概率通常很小,0.01-0.1。太大了就变成随机搜索了。
  7. 迭代:重复3-6步,直到满足终止条件。
我曾经踩过的坑:有一次做车间调度优化,我把变异概率设成了0.3,结果算法跑了100代还在震荡,根本收敛不了。后来改成0.05,效果立竿见影。记住——变异是「扰动」,不是「主引擎」。

2.1.2 关键参数速查表

参数 典型范围 我的建议
种群大小 20-200 问题维度高就取大值
交叉概率 0.6-0.95 别低于0.6,否则搜索太慢
变异概率 0.01-0.1 先试0.05,再微调
精英保留数 1-5 保留最优个体,防止退化

2.1.3 代码骨架

def genetic_algorithm(fitness_func, dim, pop_size=100, max_gen=500):
    # 初始化种群
    pop = np.random.uniform(low, high, (pop_size, dim))
    
    for gen in range(max_gen):
        # 评估适应度
        fitness = np.array([fitness_func(ind) for ind in pop])
        
        # 选择(锦标赛)
        new_pop = []
        for _ in range(pop_size):
            i, j = np.random.choice(pop_size, 2, replace=False)
            winner = pop[i] if fitness[i] > fitness[j] else pop[j]
            new_pop.append(winner)
        
        # 交叉(模拟二进制交叉)
        # 变异(多项式变异)
        # 精英保留
        
    return best_individual

2.2 粒子群优化(PSO)——鸟群的数学建模

PSO是我个人最喜欢的算法之一。为什么?因为它简单、参数少、收敛快。你想想看,一群鸟在找食物,每只鸟既记得自己找到过的最好位置,也参考同伴们发现的最好位置。这不就是分布式智能吗?

2.2.1 核心公式

每个粒子有两个属性:位置 x 和速度 v。更新规则就两条:

v[i] = w * v[i] + c1 * r1 * (pbest[i] - x[i]) + c2 * r2 * (gbest - x[i])
x[i] = x[i] + v[i]

这里:

  • w:惯性权重。控制全局搜索和局部搜索的平衡。我习惯从0.9线性递减到0.4。
  • c1, c2:学习因子。一般取2.0,但也可以调。
  • r1, r2:[0,1]的随机数。
  • pbest:个体历史最优。
  • gbest:全局最优。
小技巧:速度一定要限幅!我见过有人没加速度上限,结果粒子直接飞出天际,解的质量一塌糊涂。一般设位置范围的10%-20%作为速度上限。

2.2.2 PSO vs GA

对比维度 PSO GA
信息共享 单向(gbest引导) 双向(交叉交换)
参数数量 3-4个 5-7个
收敛速度 快,但易早熟 慢,但更稳健
适用场景 连续优化 离散/组合优化

2.3 模拟退火(SA)——炼钢工人的智慧

模拟退火的物理背景很有意思。金属加热后慢慢冷却,原子会排列成能量最低的晶体结构。算法就是模仿这个过程——高温时允许「坏解」,低温时只接受「好解」。

2.3.1 核心机制

  1. 初始温度T₀:设得足够高,保证初期能接受大部分差解。
  2. 扰动:在当前解附近随机生成一个新解。
  3. 接受准则(Metropolis准则):
    • 如果新解更好,直接接受。
    • 如果新解更差,以概率 exp(-ΔE/T) 接受。
  4. 降温:T = α * T,α通常取0.85-0.99。
  5. 终止:温度降到接近0,或者连续多次没有改进。
我曾经犯过的错:有一次做旅行商问题,我把降温系数设成了0.95,结果跑了2万次迭代还没收敛。后来改成0.99,虽然迭代次数多了,但解的质量明显提升。记住——降温越慢,搜索越充分,但时间成本也越高。

2.3.2 参数设置指南

参数 作用 经验值
初始温度T₀ 控制初期接受概率 使接受概率≈0.8
降温系数α 控制降温速度 0.85-0.99
每个温度迭代次数 平衡搜索充分性 100-1000
终止温度 停止条件 1e-5 或更小

2.4 三种算法的知识图谱

下面这张图把GA、PSO、SA的核心逻辑串起来了。你仔细看,它们其实都在做同一件事——「探索 vs 利用」的权衡。

全局优化算法知识图谱 全局优化算法核心逻辑 全局优化问题 遗传算法 (GA) 粒子群优化 (PSO) 模拟退火 (SA) 选择 + 交叉 + 变异 种群进化 速度 + 位置更新 群体协作 Metropolis准则 概率接受 探索 vs 利用 的平衡 三种算法本质相同:用随机性探索全局,用选择/记忆/降温机制收敛到局部最优

2.5 选型建议

到底用哪个?我个人的经验是:

  • 离散组合问题(排班、路径规划、调度):优先GA。它的交叉操作天然适合组合结构。
  • 连续函数优化(参数调优、神经网络训练):优先PSO。收敛快,代码简单。
  • 解空间极其崎岖(多峰函数、能量景观复杂):优先SA。它的概率接受机制不容易被困住。
  • 时间充裕、追求高质量解:混合策略。比如先用GA跑几代,再用PSO精调,最后用SA跳出局部。
我的一个实战案例:去年做天线阵列优化,搜索空间有50个维度,而且是个多峰问题。我试了纯PSO,早熟严重;纯GA,收敛太慢。最后用GA做全局探索(50代),再用PSO做局部精化(100代),效果比单独用任何一个都好。这就是协同策略的价值。