Développement réel de la plate-forme de test d'intégration d'algorithmes intelligents V0.1

avant-propos

Après avoir tourné en rond, je voulais faire un test de comparaison avec d'autres algorithmes d'essaim de particules. Il s'est avéré que s'il n'y a pas de code, ce n'est pas grave si python n'en a pas. Matlab ne peut pas le trouver. Si vous le trouvez, vous aura besoin d'argent. Bien qu'il existe des bibliothèques d'algorithmes intelligents en python, elles sont trop intégrées et certaines variantes de PSO ne sont pas spécifiquement intégrées. Bien qu'il existe une bibliothèque dédiée à PSO, cette chose intègre un algorithme et le fichier principal est un PSO.

Donc, puisqu'il n'y en a pas, je vais construire ma propre roue et jeter un coup d'œil d'abord, et je veux vraiment me plaindre, certains articles ne donnent pas le code, même si je ne donne pas les paramètres lors de l'expérience de comparaison , Je suis très confus et je dois le faire moi-même. Ajustez manuellement les paramètres. Et j'ai trouvé une chose très intéressante. Dans l'algorithme proposé par l'auteur de l'article, l'effet expérimental est très bon. Quand d'autres citent et comparent, même le PSO standard ne doit pas être capable de le faire.

Pour l'instant, je vais commencer par la version la plus simple, mais elle n'est intégrée qu'au PSO pour l'instant, et elle s'adresse pour l'instant aux plateformes mono-cibles. Pour les multi-cibles, il y a PlatEMO, donc à la base je n'ai pas besoin de écrivez-en une autre. S'il ne s'agit que d'une seule cible, je n'en ai pas trouvé une appropriée. Les auteurs de ces articles n'ont pas fourni de code et il y avait peu de ressources en ligne. Je ne sais pas si c'est trop simple ou j'ai peur de dévoiler les secrets... Il n'y a pas d'esprit open source.

droits d'auteur

郑重提示:本文版权归本人所有,任何人不得抄袭,搬运,使用需征得本人同意!

2022.7.4

Date : 2022.7.4

algorithme d'ensemble

À l'heure actuelle, cette chose est un algorithme PSO intégré. L'algorithme PSO est divisé en deux catégories, l'une est un algorithme basé sur l'optimisation des paramètres et l'autre est une stratégie multi-essaim. À l'origine, je voulais faire quelques structures de topologie d'optimisation . , mais d'un côté, c'est un problème de mise en œuvre, et de l'autre, le papier n'explique pas que l'anglais (en chinois) prend du temps. Je n'ai pas tellement le temps de faire cette merde, parce que mon l'algorithme n'est pas encore terminé, je veux juste un truc de test de comparaison.

Structuration du projet

在这里插入图片描述

Algorithme de base de l'essaim de particules SPSO

在这里插入图片描述

Structure de données

Afin d'unifier et de faciliter la gestion par la suite, une classe de données est également spécialement définie.在这里插入图片描述

import random
from ALGSet.Config.PSO.SPSO import *
class SBird(object):

    #这个是从1开始的
    ID = 1

    Y = None
    X = None
    V = None

    PbestY = None
    PBestX = None

    GBestX = None
    GBestY = None


    def __init__(self,ID):
        self.ID = ID
        self.V = [random.random() *(V_max-V_min) + V_min for _ in range(DIM)]
        self.X = [random.random() *(X_up-X_down) + X_down for _ in range(DIM)]

    def __str__(self):
        return "ID:"+str(self.ID)+" -Fintess:%.2e:"%(self.Y)+" -X"+str(self.X)+" -PBestFitness:%.2e"%(self.PbestY)+" -PBestX:"+str(self.PBestX)+\
            "\n -GBestFitness:%.2e"%(self.GBestY)+" -GBestX:"+str(self.GBestX)

Paramétrage associé

La configuration correspond également au nom de l'algorithme, qui peut également être vu dans la figure ci-dessus.

#coding=utf-8
# 相关参数的设置通过配置中心完成
import sys
import os
sys.path.append(os.path.abspath(os.path.dirname(os.getcwd())))
C1=1.458
C2=1.458
W = 0.72
m = 3
DIM = 10
PopulationSize=30
#运行1000次(可以理解为训练1次这个粒子群要跑一千次)
IterationsNumber = 3000
X_down = -10.0
X_up = 10

V_min = -5.0
V_max = 5

Wmax = 0.9
Wmin = 0.4
def LinearW(iterate):
    #传入迭代次数

    w = Wmax-(iterate*((Wmax-Wmin)/IterationsNumber))
    return w


def Dw(iterate):
    w = Wmax-((iterate**2)*((Wmax-Wmin)/(IterationsNumber**2)))
    return w
def Nw(iterate):
    w = Wmin+(Wmax-Wmin)*(((IterationsNumber-iterate)**m)/(IterationsNumber**m))
    return w

code d'implémentation

#coding=utf-8
#这个是最基础的PSO算法SPSO算法

import sys
import os

from ALGSet.Alg.PSO.Bird.SBird import SBird

sys.path.append(os.path.abspath(os.path.dirname(os.getcwd())))
from ALGSet.Target.Target import Target
from ALGSet.Config.PSO.SPSO import *
import random
import time
class SPso(object):

    Population = None
    Random = random.random
    target = Target()
    W = W


    def __init__(self):
        #为了方便,我们这边直接先从1开始
        self.Population = [SBird(ID) for ID in range(1,PopulationSize+1)]

    def ComputeV(self,bird):
        #这个方法是用来计算速度滴
        NewV=[]
        for i in range(DIM):
            v = bird.V[i]*self.W + C1*self.Random()*(bird.PBestX[i]-bird.X[i])\
            +C2*self.Random()*(bird.GBestX[i]-bird.X[i])
            #这里注意判断是否超出了范围
            if(v>V_max):
                v = V_max
            elif(v<V_min):
                v = V_min
            NewV.append(v)

        return NewV

    def ComputeX(self,bird:SBird):
        NewX = []
        NewV = self.ComputeV(bird)
        bird.V = NewV
        for i in range(DIM):
            x = bird.X[i]+NewV[i]
            if(x>X_up):
                x = X_up
            elif(x<X_down):
                x = X_down
            NewX.append(x)
        return NewX

    def InitPopulation(self):
        #初始化种群
        GBestX = [0. for _ in range(DIM)]
        Flag = float("inf")
        for bird in self.Population:
            bird.PBestX = bird.X
            bird.Y = self.target.SquareSum(bird.X)
            bird.PbestY = bird.Y
            if(bird.Y<=Flag):
                GBestX = bird.X
                Flag = bird.Y
        #便利了一遍我们得到了全局最优的种群
        for bird in self.Population:
            bird.GBestX = GBestX
            bird.GBestY = Flag


    def Running(self):
        #这里开始进入迭代运算
        for iterate in range(1,IterationsNumber+1):
            #这个算的GBestX其实始终是在算下一轮的最好的玩意
            GBestX = [0. for _ in range(DIM)]
            Flag = float("inf")

            for bird in self.Population:
   
                x = self.ComputeX(bird)
                y = self.target.SquareSum(x)

                bird.X = x
                bird.Y = y
                if(bird.Y<=bird.PbestY):
                    bird.PBestX=bird.X
                    bird.PbestY = bird.Y

                #个体中的最优一定包含了全局经历过的最优值
                if(bird.PbestY<=Flag):
                    GBestX = bird.PBestX
                    Flag = bird.PbestY
            for bird in self.Population:
                bird.GBestX = GBestX
                bird.GBestY=Flag

if __name__ == '__main__':

    start = time.time()
    sPSO = SPso()
    sPSO.InitPopulation()
    sPSO.Running()
    end = time.time()

    print("Y: ",sPSO.Population[0].GBestY)
    print("X: ",sPSO.Population[0].GBestX)
    print("花费时长:",end-start)




fonction objectif

La fonction objective est en fait entièrement dans Target. À l'heure actuelle, elle fait encore de l'intégration d'algorithme. Beaucoup de choses qu'elle contient ne sont en fait pas du tout structurées, mais cela sera changé très rapidement plus tard. Maintenant, pour insérer quelques algorithmes.在这里插入图片描述

import math
import sys
import os
sys.path.append(os.path.abspath(os.path.dirname(os.getcwd())))
class Target(object):
    def SquareSum(self,X):
        res = 0
        for x in X:

            res+=x*x

        return res


Optimisation des paramètres (population unique) Algorithme de la série PSO

Nous en intégrons en fait trois ici

LPSO

Il s'agit en fait d'un poids qui change linéairement.

"""
LPSO:这个玩意其实还只是对W进行优化了
"""
import time

from ALGSet.Alg.PSO.SPSO import SPso
from ALGSet.Config.PSO.SPSO import *
class LPso(SPso):

    def Running(self):
        # 这里开始进入迭代运算
        for iterate in range(1, IterationsNumber + 1):
            # 这个算的GBestX其实始终是在算下一轮的最好的玩意
            GBestX = [0. for _ in range(DIM)]
            Flag = float("inf")
            w = LinearW(iterate)
            self.W = w
            for bird in self.Population:

                x = self.ComputeX(bird)
                y = self.target.SquareSum(x)

                bird.X = x
                bird.Y = y
                if (bird.Y <= bird.PbestY):
                    bird.PBestX = bird.X
                    bird.PbestY = bird.Y

                # 个体中的最优一定包含了全局经历过的最优值
                if (bird.PbestY <= Flag):
                    GBestX = bird.PBestX
                    Flag = bird.PbestY
            for bird in self.Population:
                bird.GBestX = GBestX
                bird.GBestY = Flag
                
if __name__ == '__main__':
    start = time.time()
    lPSO = LPso()
    lPSO.InitPopulation()
    lPSO.Running()
    end = time.time()

    print("Y: ",lPSO.Population[0].GBestY)
    print("X: ",lPSO.Population[0].GBestX)
    print("花费时长:",end-start)


DPSO

Cela transforme en fait des poids linéaires en cette chose


def Dw(iterate):
    w = Wmax-((iterate**2)*((Wmax-Wmin)/(IterationsNumber**2)))
    return w

代码其实就是把刚刚的WLinear变成了Dw

NPSO

同理,w函数变成这个了。

def Nw(iterate):
    w = Wmin+(Wmax-Wmin)*(((IterationsNumber-iterate)**m)/(IterationsNumber**m))
    return w

自适应PSO(VCAPSO)

这个算法的实现相对复杂一点,其实也不难。 具体资料的话自己感兴趣可以去查查,我这里还没整理好,就不发了。

参数配置

这个的话也是在Config那个包下面的

#coding=utf-8
# 相关参数的设置通过配置中心完成
import sys
import os
sys.path.append(os.path.abspath(os.path.dirname(os.getcwd())))
C1=1.458
C2=1.458

K1 = 0.72
K2 = 0.9

DIM = 10
PopulationSize=30

IterationsNumber = 3000
X_down = -10.0
X_up = 10

V_min = -5.0
V_max = 5

Wmax = 0.9
Wmin = 0.4

核心代码

"""
这个算法其实也是关于参数进行了优化的
基于云自适应算法进行适应的(什么叫做云我也不懂,不过公式给我就好了)
"""
import math
import time
import random

from ALGSet.Alg.PSO.SPSO import SPso

from ALGSet.Config.PSO.VCAPSO import *


class VCAPso(SPso):

    F_avg = 0.
    F_avg1=0.
    F_avg2=0.
    En = 0.
    He = 0.

    def InitPopulation(self):
        #初始化种群
        GBestX = [0. for _ in range(DIM)]
        Flag = float("inf")
        for bird in self.Population:
            bird.PBestX = bird.X
            bird.Y = self.target.SquareSum(bird.X)
            bird.PbestY = bird.Y
            self.F_avg+=bird.Y
            if(bird.Y<=Flag):
                GBestX = bird.X
                Flag = bird.Y
        #便利了一遍我们得到了全局最优的种群
        for bird in self.Population:
            bird.GBestX = GBestX
            bird.GBestY = Flag
        self.F_avg/=PopulationSize
        self.En = (self.F_avg-Flag)/C1
        self.He = self.En/C2
        self.En = random.uniform(self.En,self.He)
        self.F_avg1,self.F_avg2 = self.__GetAvg2(self.Population)

    def ComputeV(self,bird):
        #这个方法是用来计算速度滴
        NewV=[]

        if(bird.Y<=self.F_avg1):
            w = K1
        elif(bird.Y>=self.F_avg2):
            w = K2
        else:
            w = Wmax-Wmin*(math.exp(-((bird.Y-self.En)**2)/(2*(self.En**2))))


        for i in range(DIM):
            v = bird.V[i]*w + C1*self.Random()*(bird.PBestX[i]-bird.X[i])\
            +C2*self.Random()*(bird.GBestX[i]-bird.X[i])
            #这里注意判断是否超出了范围
            if(v>V_max):
                v = V_max
            elif(v<V_min):
                v = V_min
            NewV.append(v)

        return NewV

    def __GetAvg2(self,Population):
        F_avg1 = 0.
        F_avg2 = 0.
        F_avg1_index = 0
        F_avg2_index = 0
        for bird in Population:
            if(bird.Y<self.F_avg):
                F_avg1_index+=1
                F_avg1+=bird.Y
            elif(bird.Y>self.F_avg):
                F_avg2_index+=1
                F_avg2+=bird.Y

        if (not F_avg1_index == 0):
            F_avg1 /= F_avg1_index
        else:
            F_avg1 = float("inf")
        if (not F_avg2_index == 0):
            F_avg2 /= F_avg2_index
        else:
            F_avg2 = float("inf")

        return F_avg1,F_avg2


    def Running(self):
        # 这里开始进入迭代运算
        for iterate in range(1, IterationsNumber + 1):
            # 这个算的GBestX其实始终是在算下一轮的最好的玩意
            GBestX = [0. for _ in range(DIM)]
            Flag = float("inf")
            F_avg = 0.
            for bird in self.Population:

                x = self.ComputeX(bird)
                y = self.target.SquareSum(x)

                bird.X = x
                bird.Y = y

                F_avg += bird.Y

                if (bird.Y <= bird.PbestY):
                    bird.PBestX = bird.X
                    bird.PbestY = bird.Y

                # 个体中的最优一定包含了全局经历过的最优值
                if (bird.PbestY <= Flag):
                    GBestX = bird.PBestX
                    Flag = bird.PbestY

            for bird in self.Population:
                bird.GBestX = GBestX
                bird.GBestY = Flag

            self.F_avg = F_avg
            self.F_avg /= PopulationSize
            self.En = (self.F_avg - Flag) / C1
            self.He = self.En / C2
            self.En = random.uniform(self.En, self.He)
            self.F_avg1, self.F_avg2 = self.__GetAvg2(self.Population)

if __name__ == '__main__':
    start = time.time()
    vcaPso = VCAPso()
    vcaPso.InitPopulation()
    vcaPso.Running()
    end = time.time()

    print("Y: ", vcaPso.Population[0].GBestY)
    print("X: ", vcaPso.Population[0].GBestX)
    print("花费时长:", end - start)


综合粒子群算法(CLPSO)

这个算法是在原来那篇论文里面提到的,先去复现的时候也是复现了的其实,现在只是单独提取出来罢了。 值得一提的是,这个玩意其实设计出来主要是应对多峰函数的,收敛也较慢。

import math
import time

from ALGSet.Target.Target import Target
from ALGSet.Config.PSO.CLPSO import *
from ALGSet.Alg.PSO.Bird.CLBird import CLBird
import random
class CLPso(object):
    
    Population = None
    Random = random.random
    target = Target()
    W = 0.
    Math = math

    def __init__(self):
        #为了方便,我们这边直接先从1开始
        self.Population = [CLBird(ID) for ID in range(1,PopulationSize+1)]
        
    def __PCi(self,i,ps):
        """
        论文当中的PCi的算子
        :return:
        """
        pci = 0.05+0.45*((self.Math.exp(10*(i-1)/(ps-1)))/(self.Math.exp(10)-1))
        return pci

    def NewComputeV(self, bird):
        """

        :param bird:
        :param params: 传入的数据格式为:[[w,c1,c2,c3],[],[],[],[]] 这里一共是5组共设置100个粒子
        :return:
        这里按照ID的顺序来调用不同的参数
        """
        NewV = []

        for i in range(DIM):
            v = bird.V[i] * self.W
            if (self.Random() < self.__PCi((i + 1), PopulationSize)):
                pbestfi = bird.Follow.PBestX[i]
            else:
                pbestfi = bird.PBestX[i]
            v = v + C1 * self.Random() * (pbestfi - bird.X[i])
            if (v > V_max):
                v = V_max
            elif (v < V_min):
                v = V_min
            NewV.append(v)

        return NewV

    def NewComputeX(self, bird: CLBird):
        NewX = []
        NewV = self.NewComputeV(bird)
        bird.V = NewV
        for i in range(DIM):
            x = bird.X[i] + NewV[i]
            if (x > X_up):
                x = X_up
            elif (x < X_down):
                x = X_down
            NewX.append(x)
        return NewX
    
    def InitPopulation(self):
        #初始化种群,不过是给ENV调用的,因为这个里面有一个CLPSO的思想
        GBestX = [0. for _ in range(DIM)]
        Flag = float("inf")
        for bird in self.Population:
            bird.PBestX = bird.X
            bird.Y = self.target.SquareSum(bird.X)
            bird.PbestY = bird.Y
            if(bird.Y<=Flag):
                GBestX = bird.X
                Flag = bird.Y

        #便利了一遍我们得到了全局最优的种群
        self.GBestY = Flag
        for bird in self.Population:
            bird.GBestX = GBestX
            bird.GBestY = Flag
            #现在是初始化,所以这个这样算是没问题的
            self.GBestYLast = Flag
            #给每一个粒子找到一个追随者
            self.ChangeBird(bird,self.Population)


    def ChangeBird(self,bird,Population):
        #这个主要是实现锦标赛法来对粒子的跟踪对象进行更新

        while True:
            #被跟踪的粒子不能和自己一样,也不能和上一个一样
            a,b = random.sample(range(PopulationSize),2)
            a = Population[a];b=Population[b]
            follow = a
            if(a.PbestY>b.PbestY):
                follow = b
            if(follow.ID!=bird.ID):
                if(bird.Follow):
                    if(bird.Follow.ID !=follow.ID):
                        bird.Follow = follow
                        return
                else:
                    bird.Follow = follow
                    return
                
    def Running(self):
       
        for iterate in range(1,IterationsNumber+1):
          
            #这个算的GBestX其实始终是在算下一轮的最好的玩意
            GBestX = [0. for _ in range(DIM)]
            Flag = float("inf")
            self.W = LinearW(iterate)
            for bird in self.Population:

                x = self.NewComputeX(bird)
                y = self.target.SquareSum(x)
        
                bird.X = x
                bird.Y = y
                if(bird.Y<=bird.PbestY):
                    bird.PBestX=bird.X
                    bird.PbestY = bird.Y
                elif (bird.Y == bird.PbestY):
                    bird.NoChange += 1
                    if (bird.NoChange == M_follow):
                        self.ChangeBird(bird, self.Population)
                        bird.NoChange = 0

                #个体中的最优一定包含了全局经历过的最优值
                if(bird.PbestY<=Flag):
                    GBestX = bird.PBestX
                    Flag = bird.PbestY
            for bird in self.Population:
                bird.GBestX = GBestX
                bird.GBestY=Flag
                
if __name__ == '__main__':

    start = time.time()
    clPSO = CLPso()
    clPSO.InitPopulation()
    clPSO.Running()
    end = time.time()

    print("Y: ",clPSO.Population[0].GBestY)
    print("X: ",clPSO.Population[0].GBestX)
    print("花费时长:",end-start)

多种群算法

MPSO 算法

这个算法就是分三个种群,然后,一个执行LPSO,一个执行SPSO,还一个执行VCAPSO。

这个就是集成三个算法,然后改了一些速度方程。

      v = bird.V[i] * w + C1 * self.Random() * (bird.PBestX[i] - bird.X[i]) \
                + C2*self.Random()*(bird.CBestX[i]-bird.X[i])\
                +C3*self.Random()*(self.GBestX[i]-bird.X[i])

HPSO算法

这个就是混合多种群PSO。也是代码很简单,而且是目前测试效果最好的。

import random
import time

from ALGSet.Alg.PSO.Bird.Hbird import HBird
from ALGSet.Config.PSO.HPSO import *
from ALGSet.Target.Target import Target


class HPso():

    rand = random.random
    miu = miu
    target = Target()
    def __init__(self):
        self.Population = [HBird(ID) for ID in range(1,PopulationSize+1)]
        self.Divide()

    def Divide(self):
        #我们这边直接通过ID进行分类
        CID = 0
        for bird in self.Population:
            bird.CID=CID
            if(bird.ID % ClusterSize==0):
                if(CID<=ClusterNumber):
                    CID+=1

    def ComputeV(self,bird):
        #这个方法是用来计算速度滴
        NewV=[]

        for i in range(DIM):
    

            v1 = bird.V[i] * self.W + C1 * self.rand() * (bird.PBestX[i] - bird.X[i]) \
                + C2 * self.rand() * (bird.GBestX[i] - bird.X[i])
            v2 = bird.V[i] * self.W + C1 * self.rand() * (bird.PBestX[i] - bird.X[i]) \
                + C2 * self.rand() * (bird.CBestX[i] - bird.X[i])
            v = v1*self.miu+(1-self.miu)*v2

            if(v>V_max):
                v = V_max
            elif(v<V_min):
                v = V_min
            NewV.append(v)
        return NewV

    def ComputeX(self,bird):
        NewX = []
        NewV = self.ComputeV(bird)
        bird.V = NewV
        for i in range(DIM):
            x = bird.X[i]+NewV[i]

            if (x > X_up):
                x = X_up
            elif (x < X_down):
                x = X_down
            NewX.append(x)
        return NewX


    def InitPopulation(self):
        #初始化种群
        #这个是记录全局最优解的
        GBestX = [0. for _ in range(DIM)]
        Flag = float("inf")

        #还有一个是记录Cluster最优解的
        CBest = {}
        CFlag = {}
        for i in range(ClusterNumber):
            CFlag[i]=float("inf")


        for bird in self.Population:
            bird.PBestX = bird.X
            bird.Y = self.target.SquareSum(bird.X)
            bird.PbestY = bird.Y

            bird.CBestX = bird.X
            bird.CBestY = bird.Y

            if(bird.Y<=Flag):
                GBestX = bird.X
                Flag = bird.Y

            if(bird.Y<=CFlag.get(bird.CID)):
                CBest[bird.CID]=bird.X
                CFlag[bird.CID] = bird.Y

        #便利了一遍我们得到了全局最优的种群
        for bird in self.Population:
            bird.GBestX = GBestX
            bird.GBestY = Flag
            bird.CBestY=CFlag.get(bird.CID)
            bird.CBestX=CBest.get(bird.CID)



    def Running(self):
        #这里开始进入迭代运算
        for iterate in range(1,IterationsNumber+1):
            w = LinearW(iterate)
            #这个算的GBestX其实始终是在算下一轮的最好的玩意
            GBestX = [0. for _ in range(DIM)]
            Flag = float("inf")
            CBest = {}
            CFlag = {}
            for i in range(ClusterNumber):
                CFlag[i] = float("inf")

            for bird in self.Population:
                #更改为线性权重
                self.W = w
                x = self.ComputeX(bird)
                y = self.target.SquareSum(x)
                bird.X = x
                bird.Y = y
                if(bird.Y<=bird.PbestY):
                    bird.PBestX=bird.X
                    bird.PbestY = bird.Y

                #个体中的最优一定包含了全局经历过的最优值
                if(bird.PbestY<=Flag):
                    GBestX = bird.PBestX
                    Flag = bird.PbestY

                if (bird.Y <= CFlag.get(bird.CID)):
                    CBest[bird.CID] = bird.X
                    CFlag[bird.CID] = bird.Y

            for bird in self.Population:
                bird.GBestX = GBestX
                bird.GBestY=Flag
                bird.CBestY = CFlag.get(bird.CID)
                bird.CBestX = CBest.get(bird.CID)


if __name__ == '__main__':
    start = time.time()
    hPso = HPso()
    hPso.InitPopulation()
    hPso.Running()
    end = time.time()

    print("Y: ", hPso.Population[0].GBestY)
    print("X: ", hPso.Population[0].GBestX)
    print("花费时长:", end - start)





后续工作

搞可视化测试,后面,不过,这个要后面在做,代码后面上传。

Je suppose que tu aimes

Origine juejin.im/post/7116689995556978702
conseillé
Classement