我编写了一些 python 代码来重现本文声称的结果。我的代码非常有效地优化了像碗这样的简单平滑函数,但没有接近重现论文声称的更复杂函数的结果,包括作者报告的参数。我认为,由于@Jairo 和我都无法独立地从论文中的信息中重现结果,因此论文很可能有问题。
可以使用py_swarm之类的库来重现论文声称的行为,但是论文使用的是萤火虫算法(已经是 PSO 的一种更罕见的形式),并且使用的是该算法的自制变体,所以我的猜测是正如我们俩一样,需要自己滚动。
此外,我发现这篇论文的说法不太可能。例如,在 4.1 节中,他们声称在 10 次迭代中收敛于具有许多局部最小值的函数的全局最小值。在我看来,大多数时候萤火虫会很快聚集在这个功能中的一个沟壑的底部,然后卡在那里。这也是我在复制中观察到的。我怀疑作者可能在没有报告的情况下从最佳运行中挑选了他们的结果,或者在论文中省略了一些关键细节。
这是我的复制代码,以防其他人想尝试复制:
from math import sin, pi, exp, sqrt
from random import random
from copy import deepcopy
def michalewiz_objective(x):
result = 0
for i, x_i in enumerate(x):
result -= sin(x_i)*(sin(i*(x_i**2)/pi))**20
return -result
def bowl_objective(x):
return -sum([x_i**2 for x_i in x])
pop_size = 40
max_generations = 10
alpha = 0.2
gamma = 1
beta_0 = 1
d = 2
I = michalewiz_objective
#I = bowl_objective
def move(firefly, other_firefly):
radius = sqrt(sum([(firefly[i] - other_firefly[i])**2 for i in range(0, len(firefly))]))
for i, value in enumerate(firefly):
firefly[i] += beta_0*exp(-gamma*radius**2)*(other_firefly[i] - firefly[i])
firefly[i] += alpha * (random() - 0.5)
# Using 4*random() to match Figure 3's apparent spread.
fireflies = [[4*random() for i in range(0, d)] for j in range(0, pop_size)]
for generation in range(0, max_generations):
new_fireflies = [deepcopy(firefly) for firefly in fireflies]
for index, firefly in enumerate(fireflies):
for other_firefly in fireflies:
if I(other_firefly) > I(firefly):
move(new_fireflies[index], other_firefly)
fireflies = new_fireflies
best = max([I(f) for f in fireflies])
mean = [sum([f[0] for f in fireflies]), sum([f[1] for f in fireflies])]
print(best)
print(mean)