首页 > 编程语言 >粒子群算法及蜂群算法求多维函数极值对比

粒子群算法及蜂群算法求多维函数极值对比

时间:2024-05-30 18:01:30浏览次数:26  
标签:蜂群 plt self 算法 fitness 多维 dimension best

1.粒子群算法

        1.1粒子群算法简单介绍

        粒子群优化算法源于对鸟群活动的研究。20 世纪 70 年代许多学者对鸟群的群体性活动进行了深入研究。生物学家 Reynolds 提出了 Boids模型,用来模拟鸟群聚集飞行的行为。在这个模型中每个个体都遵守三条规则:避免碰撞、速度一致,向中心聚集。该模型的仿真结果与自然界鸟群时而聚集时而分散的飞行特性基本一致。验证了鸟群个体的飞行轨迹与邻近个体的行为有关。生物学家 Erank Heppner对鸟群的趋同性进行了深入研究,建立了这样的鸟群运动模型:一群小鸟在空中漫无目的地飞行,当群体中的一只小鸟发现栖息地时,它会飞向这个栖息地,同时也会将它周围的小鸟吸引过来,而它周围的这些鸟也将影响群体中其他的小鸟,最终将整个鸟群引向这个栖息地。研究发现,鸟群的同步飞行只是建立在每只鸟对邻近鸟的局部感知,而并不存在一个集中控制者。

        1.2粒子群算法流程图

        1.3python代码求极小值

import math
import random
import numpy as np
import matplotlib.pyplot as plt
import pylab as mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']


class PSO:
    def __init__(self, dimension, time, size, low, up, v_low, v_high):
        # 初始化
        self.dimension = dimension  # 变量个数
        self.time = time  # 迭代的代数
        self.size = size  # 种群大小
        self.bound = []  # 变量的约束范围
        self.bound.append(low)
        self.bound.append(up)
        self.v_low = v_low
        self.v_high = v_high
        self.x = np.zeros((self.size, self.dimension))  # 所有粒子的位置
        self.v = np.zeros((self.size, self.dimension))  # 所有粒子的速度
        self.p_best = np.zeros((self.size, self.dimension))  # 每个粒子最优的位置
        self.g_best = np.zeros((1, self.dimension))[0]  # 全局最优的位置

        # 初始化第0代初始全局最优解
        temp = -1000000
        for i in range(self.size):
            for j in range(self.dimension):
                self.x[i][j] = random.uniform(self.bound[0][j], self.bound[1][j])
                self.v[i][j] = random.uniform(self.v_low, self.v_high)
            self.p_best[i] = self.x[i]  # 储存最优的个体
            fit = self.fitness(self.p_best[i])
            # 做出修改
            if fit > temp:
                self.g_best = self.p_best[i]
                temp = fit

    #函数1
    def fitness(self, x):
        total=0
        for i in range(1,len(x)):
            total = total+x[i] 
        y=np.floor((total*100)/100)
        return y
    
    #函数2
    # def fitness(self, x):
    #     sun=0
    #     for i in range(1,len(x)):
    #         if i<len(x)-1:
    #             sun+=100*(x[i+1]-x[i]**2)**2+(x[i]-1)**2
    #     return sun
    
    #函数3
    # def fitness(self,x):  
    #     sun=0
    #     for i in range(1,len(x)):
    #         sun+=(x[i]**2-10*np.cos(2*np.pi*x[i])+10)
    #     sun=sun+10*len(x)
    #     return sun 
    
    #函数4
    # def fitness(self,x):  
    #     sun1=0
    #     sun2=1
    #     sun=0
    #     for i in range(1,len(x)):
    #         sun1+=x[i]**2
    #         sun2*=np.cos(x[i]/np.sqrt(i))
    #     sun=(1/400)*sun1-sun2+1
    #     return sun
    
    

    def update(self, size):
        c1 = 2.0  # 学习因子
        c2 = 2.0
        w = 0.8  # 自身权重因子
        for i in range(size):
            # 更新速度(核心公式)
            self.v[i] = w * self.v[i] + c1 * random.uniform(0, 1) * (
                    self.p_best[i] - self.x[i]) + c2 * random.uniform(0, 1) * (self.g_best - self.x[i])
            # 速度限制
            for j in range(self.dimension):
                if self.v[i][j] < self.v_low:
                    self.v[i][j] = self.v_low
                if self.v[i][j] > self.v_high:
                    self.v[i][j] = self.v_high

            # 更新位置
            self.x[i] = self.x[i] + self.v[i]
            # 位置限制
            for j in range(self.dimension):
                if self.x[i][j] < self.bound[0][j]:
                    self.x[i][j] = self.bound[0][j]
                if self.x[i][j] > self.bound[1][j]:
                    self.x[i][j] = self.bound[1][j]
            # 更新p_best和g_best
            if self.fitness(self.x[i]) < self.fitness(self.p_best[i]):
                self.p_best[i] = self.x[i]
            if self.fitness(self.x[i]) < self.fitness(self.g_best):
                self.g_best = self.x[i]

    def pso(self):
        best = []
        self.final_best = np.array([i for i in range(dimension)])
        for gen in range(self.time):
            self.update(self.size)
            if self.fitness(self.g_best) < self.fitness(self.final_best):
                self.final_best = self.g_best.copy()
            print('当前最佳位置:{}'.format(self.final_best))
            temp = self.fitness(self.final_best)
            print('当前的最佳适应度:{}'.format(temp))
            best.append(temp)
        t = [i for i in range(self.time)]
#函数图像
        plt.figure()
        plt.plot(t, best, color='red', marker='.', ms=15)
        plt.rcParams['axes.unicode_minus'] = False
        plt.margins(0)
        plt.xlabel(u"迭代次数")  # X轴标签
        plt.ylabel(u"适应度")  # Y轴标签
        plt.title(u"迭代过程")  # 标题
        plt.show()


if __name__ == '__main__':
    time = 50
    size = 100
    dimension = 50
    v_low = -1
    v_high = 1
    low=[]
    up=[]
    for i in range(dimension):
        low.append(0)
        up.append(40)
    pso = PSO(dimension, time, size, low, up, v_low, v_high)
    pso.pso()

2.蜂群算法

        1.1蜂群算法简单介绍

       ABC算法利用蜜蜂觅食的自组织特性,通过蜜蜂不断地搜索和探索来完成解的更新。在现实的蜜蜂群中,蜂群包含三个基本要素:蜜源、雇佣蜂、非雇佣蜂,以及两种主要的行为模式;蜜源招募蜜蜂和放弃食物源。蜜源的好坏由多种因素决定,如蜜源到蜂巢的距离,蜂蜜的多少及开采的难易等。为了简单起见,用收益来表示蜜源的好坏。雇佣蜂是指正在某个蜜源采蜜或已经被这个蜜源雇佣的蜜蜂。它们会把这个蜜源的信息,如离蜂巢的距离和方向、蜜源的收益等通过舞蹈的方式告知其他的蜜蜂。非雇佣蜂包括侦查蜂和跟随蜂,侦查蜂四处探索寻找新的蜜源。一般来说,侦查蜂的数量为蜂群总数的 5%~10%。跟随蜂在舞蹈区等待由雇佣蜂带回的蜜源信息,根据舞蹈信息决定到哪个蜜源采蜜。较大收益的蜜源,可以招募到更多的蜜蜂去采蜜。

        1.2蜂群算法流程图

        1.3python代码求极小值

import numpy as np  
import random  
import matplotlib.pyplot as plt
#函数1
def objective_function(x): 
    total=0
    for i in range(1,len(x)):
        total = total+x[i] 
    y=np.floor((total*100)/100)
    return y

#函数2
# def objective_function(x): 
#     sun=0
#     for i in range(1,len(x)):
#         if i<len(x)-1:
#             sun+=100*(x[i+1]-x[i]**2)**2+(x[i]-1)**2
#     return sun

#函数3
# def objective_function(x): 
#     sun=0
#     for i in range(1,len(x)):
#         sun+=(x[i]**2-10*np.cos(2*np.pi*x[i])+10)
#     sun=sun+10*len(x)
#     return sun 

#函数4
# def objective_function(x):  
#     sun1=0
#     sun2=1
#     sun=0
#     for i in range(1,len(x)):
#         sun1+=x[i]**2
#         sun2*=np.cos(x[i]/np.sqrt(i))
#     sun=(1/400)*sun1-sun2+1
#     return sun

  
# ABC参数  
N = 50  # 蜜蜂总数(通常工蜂和观察蜂数量相等)  
D = 6 # 问题维度  
limit = 100  # 蜜源的最大迭代次数限制  
  
# 初始化蜜源(解)  
solutions = np.random.rand(N, D)  
fitness = np.array([objective_function(sol) for sol in solutions])  
trials = np.zeros(N, dtype=int)  # 记录蜜源被放弃的次数  

# ABC主循环  
for iter_count in range(limit):  
    # 工蜂阶段(搜索新蜜源)  
    for i in range(N):  
        # 选择一个随机蜜源作为邻居  
        j = random.randint(0, N-1)  
        while j == i:  
            j = random.randint(0, N-1)  
          
        # 在两个蜜源之间进行邻域搜索  
        phi = np.random.uniform(-1, 1, D)  
        new_solution = solutions[i] + phi * (solutions[i] - solutions[j])  
          
        # 检查新蜜源是否越界,并适当处理  
        new_solution = np.clip(new_solution, 0, 1)  # 假设解在[0,1]范围内  
          
        # 评估新蜜源的适应度  
        new_fitness = objective_function(new_solution)  
          
        # 如果新蜜源更好,则替换当前蜜源  
        if new_fitness < fitness[i]:  
            solutions[i] = new_solution  
            fitness[i] = new_fitness  
            trials[i] = 0  # 重置放弃次数  
        else:  
            trials[i] += 1  
      
    # 观察蜂阶段(选择蜜源并搜索)  
    # ...(与工蜂阶段类似,但选择是基于适应度的)  
      
    # 侦查蜂阶段(当蜜源被放弃多次后,随机生成新蜜源)  
    for i in range(N):  
        if trials[i] > limit:  
            solutions[i] = np.random.rand(D)  
            fitness[i] = objective_function(solutions[i])  
            trials[i] = 0  
      
    # 可以添加一些输出或收敛检查  
    # ...  

#画图
t = [i for i in range(N)]
plt.figure()
plt.plot(t, fitness, color='red', marker='.', ms=15)
plt.rcParams['axes.unicode_minus'] = False
plt.margins(0)
plt.xlabel(u"迭代次数")  # X轴标签
plt.ylabel(u"适应度")  # Y轴标签
plt.title(u"迭代过程")  # 标题
plt.show() 
      
  
# 输出最佳解  
best_idx = np.argmin(fitness)  
print("Best solution:", solutions[best_idx])  
print("Best fitness:", fitness[best_idx])

3.多维度下极值对比

        3.1涉及多维函数

        代码涉及函数分别为以下四个函数:

        3.2粒子群算法与蜂群算法各维度图像及输出值对比

           左边为粒子群算法,右边为蜂群算法,n为函数维度

  n=5时

      n=10时

      n=15时

      n=20时

        这里发现在n=15时,两种算法均出现极值收敛错误,故分别取n=11、12、13、14多次实验,发现在n=11时粒子群算法多次出现极值收敛错误,蜂群算法并未出现错误。后续逐渐取大维数,发现在n=15时,蜂群算法开始出现极值收敛错误。

n=11

4. 对比结论

        由于粒子群算法和蜂群算法涉及参数较多,如粒子群算法涉及学习因子、惯性权重、粒子速度及方向等,蜂群算法涉及食物源、雇佣蜂、跟随蜂等,无法很好控制变量得出结论。但从多维函数极值对比可以得出初步结论:在维度n=11时,粒子群算法极值收敛位置出现问题,且收敛极值也出现错误。蜂群算法更加适用于多维度函数极值问题,蜂群算法适用于15维以内的极值问题。

标签:蜂群,plt,self,算法,fitness,多维,dimension,best
From: https://blog.csdn.net/qq_67896689/article/details/139329673

相关文章

  • 【智能算法驱动的光子学设计与应用】
    在智能算法与光子学设计融合的背景下,科研的边界持续扩展,创新成果不断涌现。从理论模型的整合到光学现象的复杂模拟,从数据驱动的探索到光场的智能分析,智能算法正以前所未有的动力推动光子学领域的革新。据调查,目前在Nature和Science杂志上发表的智能算法与光子学结合的研究......
  • 算法金 | 吴恩达:机器学习的六个核心算法!
    大侠幸会,在下全网同名「算法金」0基础转AI上岸,多个算法赛Top「日更万日,让更多人享受智能乐趣」人工智能领域的权威吴恩达教授,在其创立的《TheBatch》周报中发表了一篇博文,概述了机器学习领域六种基础算法的历史和重要性。他强调了在这一领域不断学习和更新知识的必要......
  • 哈希曼压缩算法
    一、哈夫曼压缩算法的原理? (1)哈夫曼压缩算法是一种无损数据压缩算法,它通过建立一种基于字符出现频率的二叉树来实现数据压缩。它的原理很简单:就是根据字符出现的频率,给高频字符分配较短的编码,低频字符分配较长的编码。这样一来,整个文件的总编码长度就大大缩短了,从而达到......
  • Floyd算法(计算最短路径)
    [JLOI2009]二叉树问题题目描述如下图所示的一棵二叉树的深度、宽度及结点间距离分别为:深度:$4$宽度:$4$结点8和6之间的距离:$8$结点7和6之间的距离:$3$其中宽度表示二叉树上同一层最多的结点个数,节点$u,v$之间的距离表示从$u$到$v$的最短有向路径上向根节点......
  • TF-IDF算法
    TF-IDF(termfrequency–inversedocumentfrequency,词频-逆向文件频率)TF-IDF本质上是一种统计方法,用来评估一个词/token在整个语料库中当前文档中的重要程度,字词的重要性随着它在当前文档中出现的频率成正比增加,随着它在整个语料库中出现的频率成反比降低。主要思想:某个单词在当......
  • 编程奇境:C++之旅,从新手村到ACM/OI算法竞赛大门(基础语法)
    踏入C++王国的神秘之门,首要任务是装备上基础语法这把万能钥匙,它不仅是你与代码世界对话的初级咒语,更是构筑编程魔法塔的基石。想象自己是一位即将踏上征途的勇士,先要学会站立、行走,方能奔跑、飞跃。基础语法:勇者的起跑线顺序结构:这就像是一场精心策划的冒险,你的每一个指令—......
  • 基于 MATLAB 的麻雀算法 (SSA) 优化注意力机制卷积神经网络结合门控循环单元 (SSA-Att
    鱼弦:公众号【红尘灯塔】,CSDN博客专家、内容合伙人、新星导师、全栈领域优质创作者、51CTO(Top红人+专家博主)、github开源爱好者(go-zero源码二次开发、游戏后端架构https://github.com/Peakchen)基于MATLAB的麻雀算法(SSA)优化注意力机制卷积神经网络结合门控循环单元......
  • 算法课程笔记——快速幂
    算法课程笔记——快速幂......
  • 常见的算法题
    冒泡排序privatestaticint[]queryArr(int[]arr1){intlen=arr1.length;if(len==0||len==1){returnarr1;}        for(inti=0;i<len;i++){            for(intj=0,lenArr=len-1-i;j<lenArr;j++){    ......
  • 基于Matlab OMP和KSVD算法的彩色图像修复
    欢迎大家点赞、收藏、关注、评论啦,由于篇幅有限,只展示了部分核心代码。文章目录一项目简介二、功能三、系统四.总结一项目简介  一、项目背景与意义在数字图像处理领域,图像修复技术一直是一个重要的研究方向。彩色图像修复旨在恢复图像中由于各种原因(如划......