第三章 萤火虫算法基础:灵感来源、数学模型与核心定义

各位同学,今天我们来聊聊萤火虫算法的基础。说实话,我第一次接触这个算法是在一个无人机编队项目里——当时需要解决多机协同定位的问题,试了好几种传统优化算法都不太理想。后来一个同事跟我说:「你不如看看萤火虫是怎么找同伴的。」嗯,这一看,就打开了新世界的大门。

3.1 算法灵感来源:大自然给的启发

萤火虫算法(Firefly Algorithm, FA)是2008年由剑桥大学的Xin-She Yang提出的。它的灵感来源,说白了就是夏夜里那些一闪一闪的小虫子。

你想想看,萤火虫发光是为了什么?

  • 求偶:雄性萤火虫通过特定频率的闪光吸引雌性
  • 捕食:有些种类的萤火虫会模仿其他种类的闪光信号来诱捕猎物
  • 警戒:闪光也可以警告捕食者「我有毒,别吃我」

在算法里,我们主要借鉴的是求偶行为。核心逻辑很简单:亮度越高的萤火虫,吸引力越强;距离越近,吸引力也越强。这就像在舞会上,最闪亮的那个人总是最吸引眼球——而且离得越近,效果越明显。

核心思想:每只萤火虫代表一个解,亮度代表解的优劣,吸引度决定移动方向。弱萤火虫会向强萤火虫移动,从而实现全局搜索。

3.2 数学模型:把自然现象翻译成公式

好,现在我们把萤火虫的行为翻译成数学语言。我个人习惯把数学模型拆成三个部分来讲:亮度、吸引度、移动公式

3.2.1 亮度定义

在算法里,萤火虫的亮度 I 通常直接等于目标函数值。对于最大化问题:

I(x) = f(x)

其中 f(x) 是目标函数,x 是萤火虫的位置向量。亮度越高,代表解越好。

但这里有个坑——光在传播过程中会衰减。距离越远,我们看到的光越暗。所以实际计算时,我们需要考虑距离因素:

I(r) = I₀ × e^(-γ × r²)

其中:

  • I₀:萤火虫自身的原始亮度(即 f(x))
  • γ:光吸收系数,控制衰减速度
  • r:两只萤火虫之间的距离

避坑指南:我曾经在项目中把 γ 设得太大,结果萤火虫之间几乎感受不到彼此的吸引力,算法变成了随机搜索。后来我总结了一个经验:γ 通常取 0.1 到 10 之间,具体要看你的搜索空间大小。空间越大,γ 应该越小。

3.2.2 吸引度定义

吸引度 β 和亮度直接相关。一只萤火虫对另一只的吸引度定义为:

β(r) = β₀ × e^(-γ × r²)

其中 β₀ 是 r=0 时的最大吸引度(通常取1)。

为什么用指数衰减?因为自然界的光强衰减就是这样的规律。而且指数函数在数学上性质很好——可导、光滑、计算方便。

参数 典型值 说明
β₀ 1.0 最大吸引度,通常固定
γ 0.1 ~ 10 光吸收系数,控制搜索范围
α 0.2 ~ 0.5 随机步长,控制探索能力

3.2.3 移动公式

当萤火虫 i 被萤火虫 j 吸引时,它会向 j 移动。移动公式是:

x_i(t+1) = x_i(t) + β₀ × e^(-γ × r²) × (x_j - x_i) + α × (rand - 0.5)

这个公式有三部分:

  1. 当前位置:x_i(t),萤火虫当前的位置
  2. 吸引项:β₀ × e^(-γ × r²) × (x_j - x_i),向更亮的萤火虫移动
  3. 随机项:α × (rand - 0.5),加入随机扰动,避免陷入局部最优

嗯,这里要注意:随机项不能太大也不能太小。太大了算法不稳定,太小了容易陷入局部最优。我一般建议 α 从 0.5 开始,随着迭代逐渐减小到 0.01 左右。

3.3 算法伪代码:把公式变成步骤

理论说完了,我们来看看实际怎么操作。下面是我常用的伪代码版本:

算法:萤火虫算法 (Firefly Algorithm)

输入:种群大小 n,最大迭代次数 MaxGen,参数 β₀, γ, α
输出:最优解 x_best

1. 初始化 n 只萤火虫的位置 x_i (i=1,2,...,n)
2. 计算每只萤火虫的亮度 I_i = f(x_i)
3. 找到当前最亮萤火虫 x_best

4. for t = 1 to MaxGen:
5.     for i = 1 to n:
6.         for j = 1 to n:
7.             if I_j > I_i:
8.                 // 计算距离
9.                 r = ||x_i - x_j||
10.                // 计算吸引度
11.                β = β₀ × exp(-γ × r²)
12.                // 移动萤火虫 i 向 j
13.                x_i = x_i + β × (x_j - x_i) + α × (rand - 0.5)
14.                // 边界处理
15.                将 x_i 限制在搜索空间内
16.            end if
17.        end for
18.    end for
19.    // 更新亮度
20.    重新计算所有萤火虫的亮度
21.    更新全局最优 x_best
22.    // 衰减随机步长(可选)
23.    α = α × 0.97
24. end for

25. return x_best

重要提醒:第7行的判断条件「I_j > I_i」意味着每只萤火虫只向比自己亮的个体移动。如果所有萤火虫亮度相同,它们就只会随机游走。我曾经遇到过这种情况——目标函数太平坦,导致算法收敛极慢。解决办法是适当增加随机项 α 的值。

3.4 知识体系结构图

下面我用一张SVG图来总结本章的核心逻辑:

萤火虫算法知识体系 灵感来源 萤火虫求偶行为 亮度越高 → 吸引力越强 距离越近 → 吸引力越强 数学模型 亮度 I(r) = I₀ × e^(-γr²) 吸引度 β(r) = β₀ × e^(-γr²) 移动公式(三部分) 算法实现 初始化种群 迭代更新位置 输出最优解 核心参数 β₀(最大吸引度) | γ(光吸收系数) | α(随机步长) | n(种群大小) 应用场景 无人机编队 | 传感器网络定位 | 路径规划 | 图像处理

3.5 一个简单的例子

为了让你更直观地理解,我们来看一个一维的例子。假设我们要最大化函数 f(x) = -x² + 4x,搜索范围 [0, 4]。

初始化3只萤火虫:

  • 萤火虫A:x=1.0,亮度 f(1)=3
  • 萤火虫B:x=2.5,亮度 f(2.5)=3.75
  • 萤火虫C:x=3.5,亮度 f(3.5)=1.75

设置参数:β₀=1,γ=1,α=0.2

第一轮迭代:

  • 萤火虫A(亮度3)看到B更亮(3.75),向B移动。距离 r=1.5,吸引度 β=exp(-1×1.5²)=0.105。新位置 x_A = 1.0 + 0.105×(2.5-1.0) + 0.2×(rand-0.5) ≈ 1.16
  • 萤火虫C(亮度1.75)看到A和B都更亮,选择向最亮的B移动。距离 r=1.0,吸引度 β=exp(-1)=0.368。新位置 x_C = 3.5 + 0.368×(2.5-3.5) + 0.2×(rand-0.5) ≈ 3.13
  • 萤火虫B最亮,不移动,只做随机扰动

你看,经过几轮迭代,所有萤火虫都会聚集到最优解 x=2 附近。这就是萤火虫算法的核心逻辑——弱者向强者学习,强者保持探索

个人经验:在实际项目中,我通常会把种群大小设为20-50之间。太小了容易早熟收敛,太大了计算量吃不消。另外,我建议每轮迭代后都检查一下种群多样性——如果所有萤火虫都挤在一起了,适当增大随机步长 α 可以帮它们「散开」。

专注资料整理