前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >智能优化算法

智能优化算法

作者头像
美小妮
发布2023-10-06 09:25:20
2370
发布2023-10-06 09:25:20
举报
文章被收录于专栏:美小妮

智能优化算法

  • 神经网络算法利用的是目标函数导数信息去迭代更新参数,选找目标函数最优值。
  • 智能优化算法是一种收索算法,也是通过迭代,筛选,选找目标函数最优值(极值)。但其与神经网络算法的不同之处在于,他没有利用导数信息,利用的是目标函数的值。一般步骤为:
    • 给定一组初始解
    • 评价当前这组解的性能
    • 从当前这组解中选择一定数量的解作为迭代后的解的基础
    • 在对其操作,得到迭代后的解
    • 若这些解满足要求则停止,否则将这些迭代得到的解作为当前解重新操作
  • 智能优化算法包含有许多,比如粒子群优化算法(PSO),飞蛾火焰算法(MFO)...等

一.飞蛾火焰算法(MFO)

算法核心思想:飞蛾以螺旋线运动方式不断靠近火焰,痛过对火焰的筛选,不断选出离目标函数极值最接近的位置。刚刚开始时候,飞蛾和火焰位置是一致的;以螺旋线方程更新飞蛾位置,接着以飞蛾位置计算火焰位置,再对火焰位置进行筛选,选出最优,不断重复迭代这个过程,得到的最优解位置就会不断接近于目标函数极值。具体内容在代码注释中。 论文地址 ---好像要期刊会员才能下载

In [17]

代码语言:javascript
复制
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

#初始化边界值以及目标函数
data_fun = {
    'F1':[-100,100,10],
    'F8':[-500,500,10]
}
class Fun_class():
    '''
    lb:下界
    ub:上界
    dim:初始化的飞蛾对应的矢量个数,也就是初始化数据的列数
    '''
    def __init__(self,F = 'F1'):
        self.lb,self.ub,self.dim = data_fun[F]
        #定义自适应函数(目标函数),此处列举2种目标函数F1和F8
        if F is 'F1':
            self.fobj = self.F1
        elif F is 'F8':
            self.fobj = self.F8
        else:
            raise Exception("未添加此目标函数")

    def __call__(self):
        return [self.lb,self.ub,self.dim,self.fobj]

    def F1(self,x):#单模态函数
        return np.sum(np.power(x,2),axis=1)#按照第二维度求和
    def F8(self,x):#多模态函数
        return np.sum(-x*np.sin(np.sqrt(np.abs(x))),axis=1)#按照第二维度求和
    #还有第三种复合模态函数,略

#初始化飞蛾的位置
def initialization(N,lb,ub,dim):
    if isinstance(ub,(int,float)):#判断是否是该种数据类型,所有边界值都是相同情况
        x = (ub - lb) * np.random.rand(N,dim) + lb
    elif isinstance(ub,(list,tuple)):#边界值不同情况,详细对照原论文公式说明
        for i in range(dim):
            #x = np.insert(x,(ub(i) - lb(i)) * np.random.rand(N,1) + lb(i),axis=1)#按列插入数据
            x = np.hstack((x,(ub(i) - lb(i)) * np.random.rand(N,1) + lb(i)))
    else:
        raise Exception("边界数据错误")
    return x

#飞蛾火焰算法MFO
def MFO(N,Max_iteration,lb,ub,dim,fobj):
    moth_pos = initialization(N,lb,ub,dim)#初始化飞蛾位置
    Convergence_curve = np.zeros((Max_iteration))#用于记录每一次迭代过程中,最优的飞蛾对应的自适应度的值
    
    #进行循环迭代,搜索最优解
    for Iteration in range(Max_iteration): #python中的此循环取值是从:0到Max_iteration-1
        #火焰数目自适应减少机制,火焰一开始数量与飞蛾一直,迭代过程中,按着迭代的轮数去平均减少火焰的数量,飞蛾数量不变
        Flame_no=round(N-Iteration*((N-1)/Max_iteration)) 

        #每一次迭代完都需要检查一下我们的飞蛾有没有飞出我们设定的边界值,如果有飞出,就将他们位置调回边界值
        flag_lb = moth_pos < lb#判断是否超出范围,返回布尔值矩阵
        flag_ub = moth_pos > ub
        moth_pos = moth_pos * (1 - (flag_lb+flag_ub)) + flag_lb * lb + flag_ub * ub#超出部分调整回来
        Moth_fitness = fobj(moth_pos)#求得飞蛾对应的自适应度

        #对飞蛾自适应度排序,并更新火焰
        if Iteration is 0:
            ids = np.argsort(Moth_fitness)#自适应度升序排序后的索引
            fitness_sorted = np.sort(Moth_fitness)#自适应度升序排序后的值
            sorted_population = moth_pos[ids]#按照排序顺序去重新排序对应的飞蛾位置
            
            #由飞蛾来更新火焰,即第一次是直接将飞蛾的位置以及自适应度赋值给火焰
            best_flames = sorted_population#位置
            best_flame_fitness = fitness_sorted#自适应度
        else:
            double_population = np.vstack((previous_population,best_flames))#位置按行拼接
            double_fitness = np.hstack((previous_fitness,best_flame_fitness))#自适应度按列拼接
            ids = np.argsort(double_fitness)#排序索引
            double_fitness_sorted = np.sort(double_fitness)##将前一次迭代的结果和这一次的结果进行升序排序
            double_sorted_population = double_population[ids]
            
            fitness_sorted = double_fitness_sorted[0:N]#取出前N个最小的自适应度
            sorted_population = double_sorted_population[0:N]#取出前N个最小的自适应度对应的位置
            
            # Update the flames 由飞蛾更新火焰
            best_flames = sorted_population#位置
            best_flame_fitness = fitness_sorted#自适应度
        
        #记录最优位置以及最优值
        Best_flame_score = sorted_population[0]#本次迭代最优的位置
        Best_flame_pos = fitness_sorted[0]#本次迭代最优的自适应度
        #更新飞蛾位置
        previous_population = moth_pos #位置
        previous_fitness = Moth_fitness #自适应度

        a=-1+Iteration * ((-1) / Max_iteration)#a从-1到-2线性分割以计算t,详细对照原论文公式说明
        
        #遍历所有飞蛾,迭代过程中,飞蛾数是不变的,火焰数是在不段减少。飞蛾围绕着火焰做螺旋靠近。
        #火焰是进行筛选,保留距离我们目标函数最近的火焰,即自适应度最小的火焰,最后火焰就只有一个,这个火焰的值无限接近于目标函数的极值。
        for i in range(moth_pos.shape[0]):
            if i < Flame_no:#飞蛾数和火焰数一致时候
                distance_to_flame=np.abs(sorted_population[i,:] - moth_pos[i,:])#求火焰和飞蛾直接的距离,是一个一维向量,具体对照论文公式说明
                #print(distance_to_flame.shape)
                b = 1
                t = (a - 1) * np.random.rand(1,1) + 1 #t是在[-2,1]之间动态变化,受前面的a影响,详细对照原论文公式说明
                #对数螺旋公式,飞蛾围绕着火焰做螺旋运动,更新其位置
                moth_pos[i,:]=distance_to_flame * np.exp(b*t) * np.cos(t * 2 * np.pi) + sorted_population[i,:];

            else:#飞蛾数大于火焰数时候,用最后一个火焰与这些飞蛾计算
                distance_to_flame=np.abs(sorted_population[i,:] - moth_pos[i,:])#求火焰和飞蛾直接的距离,是一个一维向量,具体对照论文公式说明
                b = 1
                t = (a - 1) * np.random.rand(1,1) + 1 #t是在[-2,1]之间动态变化,受前面的a影响,详细对照原论文公式说明
                #对数螺旋公式,飞蛾围绕着火焰做螺旋运动,更新其位置
                moth_pos[i,:]=distance_to_flame * np.exp(b * t) * np.cos(t * 2 * np.pi) + sorted_population[Flame_no-1,:]#使用最后一个火焰
        
        Convergence_curve[Iteration] = Best_flame_pos#记录每一次的最优自适应度
        if Iteration % 50 is 0:
            print(Best_flame_pos)
    
    return Best_flame_score,Best_flame_pos,Convergence_curve


#主函数
if __name__ == "__main__":
    N = 30#粒子数量,即飞蛾数量
    Max_iteration = 1000#最大迭代数量

    #初始化一些变量
    fun = Fun_class('F1')
    lb,ub,dim,fobj = fun()

    #飞蛾火焰算法MFO
    Best_flame_score,Best_flame_pos,Convergence_curve=MFO(N,Max_iteration,lb,ub,dim,fobj)
    print("最优解:{}".format(Best_flame_score))
    print("函数近似极值:{}".format(Best_flame_pos))
    print("每一次迭代的最优值维度:{}".format(Convergence_curve.shape))
    
    #画个曲线图
    plt.subplot(1,2,1)
    plt.plot(Convergence_curve)
    plt.title("Convergence_curve")
    plt.xlabel("iter")
    plt.ylabel("Best flame (score) obtained so far")
代码语言:javascript
复制
17119.536235460364
3218.906451394564
2172.8645838721854
1350.650895752926
1350.650895752926
1211.9943280737493
1122.7824779693876
1053.7494395636131
1019.832800861471
862.890984008977
488.5987825947539
396.76299619398867
396.76299619398867
396.76299619398867
396.76299619398867
335.19998325834916
335.19998325834916
335.19998325834916
304.81867060250653
304.81867060250653
最优解:[ -0.29300351  -8.42585415 -16.65158052  -5.39207436   0.60597754
   0.32618419  -5.16099647  -3.88361087  -0.15208169   6.92920333]
函数近似极值:304.81867060250653
每一次迭代的最优值维度:(1000,)
代码语言:javascript
复制
<Figure size 432x288 with 1 Axes>

观察曲线,最优解是在不断下降的,不断接近极值

二.鲸鱼算法(WOA)

算法核心思想:与前面的MFO相似,区别就是位置更新的公式不同。此算法的在每一次的调整边界时,计算自适应度,之后的位置更新操作有改变,它只记录了最小自适应度对应的位置(一只距离目标函数极值最近的鲸鱼)。接着在主循环中更新了鲸鱼的位置,有3种更新公式:

  • 1.百分之50的概率。用之前记录的最近的位置与该鲸鱼位置做差,然后带入螺旋线公式计算该矢量对应的下一步运动位置。
  • 2.25%-50%的概率。用之前记录的最近的位置与该鲸鱼位置做差,然后带入另一个矢量计算公式,更新鲸鱼位置
  • 3.0%-25%的概率。用随机的位置与该鲸鱼位置做差,然后用该随机的位置和做差后的值继续做差,去更新鲸鱼位置

三.樽海鞘群优化算法(SSA)

算法核心思想:与MFO类似,初始化鱼群后,对其求自适应度,然后进行排序,记录最小位置(也就是最优位置),作为食物位置。接下来的迭代循环阶段做的是,遍历鱼群中的所有鱼,其中一半的鱼群用(3.1)的公式去更新鱼群位置,另一半鱼群用(3.4)的公式去更新鱼群。最后在对这些更新后的鱼群进行排序,自适应度最小的鱼群位置作为新的食物位置。

四.灰太狼优化器(GWO)

算法核心思想:与前面几种都是类似

  • 初始化狼群(随机初始化)和初始化3只重要程度递减的狼(Alpha、Beta、Delta,求解极小值问题时候初始化为无穷大)
  • 判断狼群是否超出边界,是的话将值改回边界
  • 对狼群计算自适应度,然后通过判断语句去更新Alpha、Beta、Delta
  • 通过下列公式去更新狼群
  • 最后的Alpha领头狼对应的目标函数值就是我们所求的接近于目标函数极值的最优值

In [ ]

In [ ]

In [ ]

In [ ]

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 智能优化算法
    • 一.飞蛾火焰算法(MFO)
      • 观察曲线,最优解是在不断下降的,不断接近极值
        • 二.鲸鱼算法(WOA)
          • 三.樽海鞘群优化算法(SSA)
            • 四.灰太狼优化器(GWO)
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档