Intelligent algorithm integration test platform V0.1 actual development

foreword

After going around in circles, I wanted to do a comparative test with other particle swarm algorithms. It turned out that if there is no code, it is fine if Python does not. Matlab can not be found. If you find it, you will have to pay for it. Good guy! Although there are some python intelligent algorithm libraries, they are either integrated too much, and some variants of PSO are not specifically integrated. Although there is a library dedicated to PSO, that thing integrates an algorithm, and the core file is a PSO.

So, since there is none, then I will build my own wheel and take a look first, and I really want to complain, some papers don’t give code, even if I don’t give the parameters when doing the comparison experiment, I am very confused and have to do it myself. Manually adjust parameters. And I found a very interesting thing. In the algorithm proposed by the author of the paper, the experimental effect is very good. When others cite and compare, even the standard PSO must not be able to do it.

At present, I will start with the simplest version, but it is only integrated into PSO at present, and it is currently aimed at single-target platforms. If there are multiple targets, there is PlatEMO, so basically I don’t need to write another one. If it is only a single target, I am I didn't find a suitable one, the authors of those papers didn't provide code, and there are few online resources. I don't know if it's too simple or I'm afraid of revealing the secrets, and there is no open source spirit.

copyright

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

2022.7.4

Date: 2022.7.4

ensemble algorithm

At present, this thing integrates the PSO algorithm. The PSO algorithm is divided into two categories, one is the algorithm based on parameter optimization, and the other is the multi-swarm strategy. Originally, I wanted to do a few optimization topology structures. , but on the one hand it is a problem of implementation, and on the other hand, the paper does not explain that (in Chinese) English takes time. I don't have so much time to do this shit, because my algorithm is not finished yet, I just want a Comparison test stuff.

Project structure

在这里插入图片描述

Basic particle swarm algorithm SPSO

在这里插入图片描述

data structure

In order to unify and facilitate management later, a data class is also specially defined.在这里插入图片描述

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)

Related configuration

The configuration also corresponds to the name of the algorithm, which can also be seen in the above figure.

#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

implementation code

#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)




objective function

The objective function is actually all in Target. At present, it is actually still doing algorithm integration. Many things in it are actually not structured at all, but this will be changed quickly later. Now to stuff some algorithms in.在这里插入图片描述

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


Parameter optimization (single population) PSO series algorithm

We are actually integrating three here

LPSO

This is actually a linearly changing weight.

"""
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

This is actually turning linear weights into this thing


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)





后续工作

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

Guess you like

Origin juejin.im/post/7116689995556978702