来源:http://www.cnblogs.com/javado/archive/2013/05/19/3087765.html
--算法说明:荧火虫算法
-- ================================初始化开始================================
domx = { { -1, 2 }, { -1, 2 } }; -- 定义域
rho = 0.4 --荧光素挥发因子
gamma = 0.6 -- 适应度提取比例
beta = 0.08 -- 邻域变化率
nt = 5 -- 邻域阀值(邻域荧火虫数)
s = 0.3 -- 步长
s1 = 0.03 -- 局部最优扰动
iot0 = 5 -- 荧光素浓度
rs = 1.5 -- 感知半径
r0 = 1.5 -- 决策半径
-- ================================初始化结束================================
-- ===============================分配空间开始===============================
m = 2 -- 解空间维数
n = 30 -- 群规模
gaddress = {} -- 分配荧火虫地址空间
gvalue = {} -- 分配适应度存放空间
ioti = {} -- 分配荧光素存放空间
rdi = {} -- 分配荧火虫决策半径存放空间
-- ===============================分配空间结束===============================
-- ===================================函数===================================
sin = math.sin
sqrt = math.sqrt
pi = math.pi
random = math.random
-- 求解函数
function maxfun(x)
return 4 - (x[1] * sin( 4 * pi * x[1]) - x[2] * sin(4 * pi * x[2] + pi + 1))
end
-- 求2范数 维数相关
function norm(xi, xj)
return sqrt((xi[1] - xj[1]) ^ 2 + (xi[2] - xj[2]) ^ 2)
end
print(maxfun({1.88, 1.81}))
print(maxfun({1.8506610777502, 1.8685277417146})) -- 6.8987454465589
-- ===========================荧火虫常量初始化开始============================
math.randomseed(os.time())
-- 初始化个体
for i = 1, n do
gaddress[i] = {}
for j = 1, m do
gaddress[i][j] = domx[j][1] + (domx[j][2] - domx[j][1]) * random()
end
end
-- 初始化荧光素
for i = 1, n do
ioti[i] = iot0
end
-- 初始化决策半径
for i = 1, n do
rdi[i] = r0
end
-- ===========================荧火虫常量初始化结束============================
-- =============================iter_max迭代开始=============================
-- 最大迭代次数
iter_max = 20
for iter = 1, iter_max do
-- 下面我加了一个变异操作
j = 1
for i = 1, n do
gvalue[i] = maxfun(gaddress[i])
if gvalue[j] > gvalue[i] then
j = i
end
end
for k = 1, m do
gaddress[j][k] = domx[k][1] + (domx[k][2] - domx[k][1]) * random()
end
gvalue[j] = maxfun(gaddress[j])
-- 更新荧光素
for i = 1, n do
ioti[i] = (1 - rho) * ioti[i] + gamma * gvalue[i]
end
-- 各荧火虫移动过程开始
for i = 1, n do
-- 决策半径内找更优点
Nit = {} -- 存放荧火虫序号
for j = 1, n do
if j ~= i and ioti[i] < ioti[j] and norm(gaddress[j], gaddress[i]) < rdi[i] then
table.insert(Nit, j)
end
end
-- 找下一步移动的点开始
Nitnum = #Nit
if Nitnum > 0 then
-- 选出Nit荧光素之差及差的总和
Nitioti = {}
Denominator = 0
for k = 1, Nitnum do
Nitioti[k] = ioti[Nit[k]] - ioti[i]
Denominator = Denominator + Nitioti[k]
end
-- 求出各个选择概率
Nitioti[1] = Nitioti[1] / Denominator
for k = 2, Nitnum do
Nitioti[k] = Nitioti[k] / Denominator + Nitioti[k - 1]
end
-- 轮盘赌
rand = random()
idx = 1
for k = 1, Nitnum do
if rand < Nitioti[k] then
idx = Nit[k]
break
end
end
-- 移动
dist = norm(gaddress[idx], gaddress[i])
for k = 1, m do
gaddress[i][k] = gaddress[i][k] + s * (gaddress[idx][k] - gaddress[i][k]) / dist
if gaddress[i][k] < domx[k][1] then
gaddress[i][k] = domx[k][1]
elseif gaddress[i][k] > domx[k][2] then
gaddress[i][k] = domx[k][2]
end
end
-- 更新决策半径
rdi[i] = rdi[i] + beta * (nt - Nitnum)
if rdi[i] < 0 then
rdi[i] = 0
elseif rdi[i] > rs then
rdi[i] = rs
end
else
for k = 1, m do
gaddress[i][k] = gaddress[i][k] + s1 * (random() - 0.5) * (domx[k][2] - domx[k][1])
if gaddress[i][k] < domx[k][1] then
gaddress[i][k] = domx[k][1]
elseif gaddress[i][k] > domx[k][2] then
gaddress[i][k] = domx[k][2]
end
end
end
end
end
-- =============================iter_max迭代结束=============================
-- =============================输出最优结果开始=============================
-- 求各个荧火虫的值
j = 1
for i = 1, m do
gvalue[i] = maxfun(gaddress[i])
if gvalue[i] < gvalue[j] then
j = i
end
end
-- 最大值
BestAddress = gaddress[j]
print("(" .. BestAddress[1] .. ", " .. BestAddress[2] .. ")\t" .. gvalue[j])
-- =============================输出最优结果结束=============================