优化算法笔记|飞蛾扑火优化算法理解及实现

一、飞蛾扑火算法背景知识

飞蛾扑火优化(Moth-flame optimization,MFO)是一种启发式搜索算法,由由Seyedali Mirjalili在2015年提出。该算法具有并行优化能力强,全局性优且不易落入局部极值的性能特征,逐渐引起了学术界和工程界的关注。
飞蛾在夜间有一种特殊的导航方式:横向定向。即它会与月亮(光源)保持一定的角度飞行,从而能够保持直线的飞行路径,但是,这种方式只在光源离飞蛾较远的情况下才有效。当有人造光源存在时,飞蛾会被人工灯光所欺骗,一直保持与人造灯光相同的角度飞行,由于它与光源的距离过近,它飞行的路径已经不是直线,而是一种螺旋的路径。
在这里插入图片描述
受这种自然现象的启发,Seyedali Mirjalili将飞蛾绕着光源螺旋飞行的过程抽象成为一个寻优的过程,飞蛾飞行的整个空间即是问题的解空间,一只飞蛾即是问题的一个解,而火焰(光源)即是问题的一个较优解,每一只飞蛾对应一个光源,避免了算法陷入局部最优;当飞蛾与火焰足够多的时候,飞蛾的飞行能够搜索解空间的绝大部分区域,从而保证了算法的探索能力;而在寻优的过程中,火焰数随着迭代次数的增加而减少,使飞蛾能够充分搜索更优解的邻域空间,保证了算法的利用能力。

基于以上特点,MFO在探索与利用之间找到了平衡,在算法优化问题中有一个较好的效果。

二、飞蛾扑火算法原理

MFO是一种基于种群的随机启发式搜索算法,它与PSO、GSA等算法最大的区别就在于其粒子搜索路径是螺旋形的,粒子围绕着更优解以一种螺旋的方式移动,而不是直线移动。
在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、算法流程总结

MFO 的过程如下:
1)初始化飞蛾种群。设置输入最优潮流控制变量维度 d,飞蛾种群搜索规模 n,最大迭代次数 T以及对数螺旋形状常数 b 等参数。
2)在搜索空间中随机生成飞蛾位置,对飞蛾种群中每只飞蛾进行适应度评价。
3)重复如下过程指导达到停止标准
3.1)自适应更新火焰个数n。将飞蛾空间位置以适应度值递增的顺序排序后赋值给火焰,作为第一代中火焰的空间位置。当迭代次数为1时,飞蛾个数即为火焰个数。
3.2)将更新后的火焰位置与飞蛾位置的适应度值重新排序,选取适应度值更优的空间位置更新为下一代火焰的位置。
3.3)自适应机制减少火焰数量,更新飞蛾的搜索参数。
3.4)更新飞蛾位置。根据每只飞蛾对应的火焰与飞行参数更新飞蛾的位置
4)输出所得最优解(火焰)

四、飞蛾扑火算法Python实现

# Moth-flame optimization algorithm
import random as rd
from math import exp, cos, pi
from copy import deepcopy

def ini(n, d):
    population, fitness = [], []
    for i in range(n):
        moth = []
        for j in range(d):
            moth.append(rd.uniform(-10, 10))
        population.append(moth)
    return population

def getFitness(moths):
    fitness = []
    for i in range(len(moths)):
        fitness.append(objFunction(moths[i]))
    return fitness

def objFunction(moth):
    objFunctionValue = 0
    for i in range(len(moth)):
        objFunctionValue += moth[i] ** 2
    return objFunctionValue

def run():
    number, dimension = 10, 10
    b = 1
    mothPopulation = ini(number, dimension)
    iterx, maxIterx = 0, 100
    while iterx < maxIterx:
        mothFitness = getFitness(mothPopulation)
        if iterx > 90:
            flameNumber = 1
        elif iterx == 0:
            flameNumber = 10
        else:
            flameNumber = int((maxIterx - iterx) / 10) + 1
        flamePopulation, flameFitness = getFlame(mothPopulation, mothFitness, flameNumber)

        for i in range(number):
            for j in range(dimension):
                r = -1 - 0.01 * iterx
                t = rd.uniform(r, 1)
                if i < len(flamePopulation):
                    distance = abs(flamePopulation[i][j] - mothPopulation[i][j])
                    mothPopulation[i][j] = distance * exp(b * t) * cos(2 * pi * t) + flamePopulation[i][j]
                    mothPopulation[i][j] = check(mothPopulation[i][j])
                else:
                    distance = abs(flamePopulation[0][j] - mothPopulation[i][j])
                    mothPopulation[i][j] = distance * exp(b * t) * cos(2 * pi * t) + flamePopulation[0][j]
                    mothPopulation[i][j] = check(mothPopulation[i][j])
        iterx += 1
    print(flamePopulation, flameFitness)

def getFlame(mothPopulation, mothFitness, flameNumber):
    flamePopulation, flameFitness = [], []
    fitness = deepcopy(mothFitness)
    fitness.sort()
    for i in range(flameNumber):
        flameFitness.append(fitness[i])
        flamePopulation.append(mothPopulation[mothFitness.index(fitness[i])])
    return flamePopulation, flameFitness

def check(x):
    if x < -10:
        return -10
    elif x > 10:
        return 10
    else:
        return x

if __name__ == '__main__':
    run()


运行结果显示:
输出所有火焰位置为:
在这里插入图片描述

参考:
Mirjalili S. Moth-flame optimization algorithm: A novel nature-inspired heuristic paradigm[J]. Knowledge-based systems, 2015, 89: 228-249.

参考1:https://blog.csdn.net/qq_40894102/article/details/107298522

参考2:https://blog.csdn.net/u011835903/article/details/107764895?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-2&spm=1001.2101.3001.4242

  • 7
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值