一、群智能优化算法
群智能优化算法的灵感来自于自然界中的群体行为的研究,它是一种在自然界自然现象表现出的智能现象启发下提出的一种智能方法。这类算法具有自组织,自学习以及自适应等特性,并且相较于传统的纯数学方法相比,具有自然界“物竞天择,适者生存”的法则来求解问题。
二、萤火虫算法
1.算法渊源
萤火虫算法( Firefly Algorithm,FA) 最初是由剑桥大学的 Yang Xin-She 教授受萤火虫的闪烁求偶行为启发进而提出的一种群智能算法。由于萤火虫算法的概念简单、易于实现、并且具有较好优化性能,因而被广泛地应用于各种优化问题的求解。
2.算法原理
萤火虫算法的搜索依靠个体之间的吸引而产生移动,尾部较亮的萤火虫对较暗的萤火虫具有较大的吸引力,并使其向其移动。
为了构造萤火虫算法,提出了三种假设:
- 萤火虫不分性别,即对于任何萤火虫来说都能被更亮的萤火虫所吸引。
- 萤火虫吸引力与尾部亮度成正比,对于任何两个萤火虫,较差(较暗) 的萤火虫由于被吸引而向较亮的移动。
- 如果没有比一个给定的萤火虫更好,它将会随机移动。
通过观察假设可以知道,亮度和吸引度这两个要素非常重要。亮度指引萤火虫前进方向,吸引度代表萤火虫前进动力。
1.对于某只萤火虫来说,其它萤火虫对该萤火虫的吸引力为
β
(
r
i
j
)
\beta(r_{ij})
β(rij) =
β
0
\beta_0
β0
e
−
γ
r
i
j
2
e^{-\gamma r_{ij}^2}
e−γrij2
其中
r
i
j
r_{ij}
rij为两只萤火虫之间的距离,
β
0
\beta_0
β0是距离为0时的吸引度。这在程序开头已被定义。
γ
\gamma
γ是光吸收系数。
2.求完吸引力后,萤火虫i被萤火虫j吸引后的位置更新为:
x
i
(
t
+
1
)
x_{i}(t+1)
xi(t+1) =
x
i
(
t
)
x_{i}(t)
xi(t) +
β
(
r
i
j
)
\beta(r_{ij})
β(rij)
(
x
j
(
t
)
−
x
i
(
t
)
)
(x_{j}(t) - x_{i}(t))
(xj(t)−xi(t)) +
α
\alpha
α
ε
\varepsilon
ε
其中t为先前位置对应的迭代次数,
ε
\varepsilon
ε代表在[-0.5 ,0.5]之间的随机数,
α
\alpha
α代表步长因子,范围是[0 , 1]。
3.代码实现
import numpy as np
from numpy.random import default_rng
class FireflyAlgorithm:
def __init__(self, pop_size=20, alpha=1.0, betamin=1.0, gamma=0.01, seed=None):
self.pop_size = pop_size
self.alpha = alpha
self.betamin = betamin
self.gamma = gamma
self.rng = default_rng(seed)
def run(self, function, dim, lb, ub, max_evals):
fireflies = self.rng.uniform(lb, ub, (self.pop_size, dim))
intensity = np.apply_along_axis(function, 1, fireflies)
best = np.min(intensity)
evaluations = self.pop_size
new_alpha = self.alpha
search_range = ub - lb
while evaluations <= max_evals:
new_alpha *= 0.97
for i in range(self.pop_size):
for j in range(self.pop_size):
if intensity[i] >= intensity[j]:
r = np.sum(np.square(fireflies[i] - fireflies[j]), axis=-1)
beta = self.betamin * np.exp(-self.gamma * r)
steps = new_alpha * (self.rng.random(dim) - 0.5) * search_range
fireflies[i] += beta * (fireflies[j] - fireflies[i]) + steps
fireflies[i] = np.clip(fireflies[i], lb, ub)
intensity[i] = function(fireflies[i])
evaluations += 1
best = min(intensity[i], best)
return best