粒子群算法(PSO)的实现,具有详细的注释

# -*- coding: utf-8 -*-
"""
Created on Mon Mar 14 09:06:35 2022

@author: aa
"""

import numpy as np#调用numpy
import matplotlib.pylab as plt#画图
np.random.seed(1)#确实随机种子

def fitnessEvalute(x,problemIndex):#适应性评估
    # x:被优化问题的候选解,可以是矩阵形式,也可是一维数组形式。
    # problemIndex: 被优化问题的序号,方便主程序调用。

    if problemIndex == 1: # 球形函数
        return np.sum(x**2,axis=1)
        
    elif problemIndex == 2:# Rosenbrock function
        dim = len(x[0])
        a = 100*(x[:,1:dim] - x[:,0:dim-1]**2)**2
        b = (x[:,0:dim-1]-1)**2
        return np.sum(np.add(a,b),axis=1)
    
    
    

def diversity(pop):#多样性评估
    # 通过欧氏距离测量群体多样性。
    edist = []
    popsize,dim = pop.shape
    for i in range(popsize-1):
        for j in range(i,popsize):
            temp = np.sqrt(np.sum((pop[i,:]-pop[j,:])**2))
            edist.append(temp)
    return (sum(edist))/len(edist)
    

def validCheck(lb,ub,pop,check_select):
    # 1、随机赋值,2、定为边界,3、弹回
    init = np.random.uniform(lb,ub, pop.shape)#init是在上界和下界以及pop的大小范围确定的一个随机数
    #用来随机赋值
    if check_select == "rand": # 随机赋值
        pop = np.where(pop<lb,init,pop)
        pop = np.where(pop>ub,init,pop)
    elif check_select == "bound": # 超出边界以边界赋值
        pop = np.where(pop<lb,lb,pop)
        pop = np.where(pop>ub,ub,pop)
    elif check_select == "bound_back": # 弹回
        x = np.argwhere(pop<lb)
        y = np.argwhere(pop>ub)
        # print(x.shape,y.shape)
        for i in range(x.shape[0]):
            pop[x[i][0],x[i][1]] = 2 * lb - pop[x[i][0],x[i][1]]              
        for i in range(y.shape[0]):
            pop[y[i][0],y[i][1]] = 2 * ub - pop[y[i][0],y[i][1]]  
    return pop 







if __name__ == '__main__':
    lb,ub = -10,10#确定粒子的上边界和下边界
    popsize,dim = 100,50#确定粒子的个数和维度
    maxIter =10000 #确定最大迭代次数
    omiga,c1,c2 = 0.7,1.4,1.4 # 确定参数表,此时的参数为经验值
    problemIndex = 1
    
    #初始化过程
    pop = np.random.uniform(lb,ub,(popsize,dim))#使用random函数中的uniform函数生成popsize个个体,维度为dim,uniform是生成[popsize,dim)
    velocity = pop.copy() # 确实每一个个体的次数
    fit = fitnessEvalute(pop,problemIndex) # 进行适应值评估
    individualBestFit = fit.copy() # location and the individual best
    individualBest = pop.copy()#将当前适应性评估的值作为个体最优的初始值
    globalBest = pop[0].copy() # 将pop的第一个值作为全局最优解
    globalBestFit = fit[0].copy()#适应性评估的第一个值作为全局适应性评估的最优解
    fitBest = globalBestFit.copy()
    
    
    
    #初始化结束了,进入迭代过程
    fitBest = []#使用fitBest存储每一代的最优值
    # 初始化过程结束,进入迭代过程
    fitBest = []  # 用列表存储每一代的最优值
    for gen in range(maxIter):#迭代次数
        if gen % 100 == 0:#每100次进行一次输出
            edist = diversity(pop)#评价多样性
            print("gen:{}, globalBestFit:{} edist={}".format(gen, globalBestFit,edist))
        for i in range(popsize):#对每一个个体进行一次循环,
            r1 = np.random.random(dim)#
            r2 = np.random.random(dim) # 生成两个随机数
            r3 = np.random.randint(0,popsize,2)
        # 更新速度和位置,公式
            velocity[i,:] = velocity[i,:] * omiga + r1*c1*(globalBest - pop[i,:]) + r2*c2*(individualBest[i,:] - pop[i,:]) # 
                    
            #velocity[i,:] = velocity[i,:] * omiga + r1*c1*(globalBest - pop[i,:]) + r2*c2*(individualBest[r3[0],:] - pop[i,:]) # 
    ##        
    #        velocity[i,:] = velocity[i,:] * omiga + r1*c1*(globalBest - pop[i,:]) \
    #                + r2*c2*(individualBest[r3[0],:] - individualBest[i,:])
        
    #        velocity[i,:] = velocity[i,:] * omiga + r1*c1*(individualBest[r3[0],:] - pop[i,:]) \
    #                + r2*c2*(individualBest[r3[1],:] - pop[i,:]) # 
    #        
    #        velocity[i,:] = velocity[i,:] * omiga + r1*c1*(pop[r3[0],:] - pop[r3[1],:])               
        
                    
            pop[i,:] = pop[i,:] + velocity[i,:]
    
         #合法性检查 ,用来规避个体有越界的行为
        popchild = validCheck(lb,ub,pop,"rand") # 此处的第四个参数的取值有"rand","bound","bound_back"
        #
        #对当前进行适应性评估
        fitCurrent = fitnessEvalute(popchild,problemIndex)#适用性函数相当于一个评估函数,进行比较与评估
            
        
        #更新历史最优解和个体最优解
        for i in range(popsize):
            if fitCurrent[i] < fit[i]: # 如果当前的适应性的值小于fit存储的值,就进行更新
                pop[i,:],fit[i] = popchild[i,:],fitCurrent[i]#如果子代的值优于父代,就把子代的值覆盖掉父代的值
                if fitCurrent[i] < individualBestFit[i]: # 更新个体最优解和位置
                    individualBestFit[i] = fitCurrent[i]  #个体最优适应性更新  
                    individualBest[i,:] = popchild[i,:] #个体最优值
        
        
        if np.min(individualBestFit)<globalBestFit:#如果个体总群中有值小于全局最优值,那么将最优适应性进行更新,将群居最优解也进行更新
            globalBestFit = np.min(individualBestFit)
            globalBest = individualBest[np.argmin(individualBestFit),:]
        
        fitBest.append(globalBestFit)  # 记录每一代最优值。
        
    print(fitBest[-10:]) # 输出最后五个值
    # 汇出函数图像。为了便于观察,取适应值的对数。
    plt.plot(np.log(fitBest))
    plt.show() 
    
   

运行结果:
gen:0, globalBestFit:3474.868421982262 edist=79.6682356664077
gen:100, globalBestFit:140.48546901908603 edist=4.102766066578025
gen:200, globalBestFit:52.55578309791457 edist=1.401527044098573
gen:300, globalBestFit:25.878779822377165 edist=0.48473753238003375
gen:400, globalBestFit:23.285714829255852 edist=0.2110591677581779
gen:500, globalBestFit:20.615111916463608 edist=0.10705842601159207
gen:600, globalBestFit:12.295009224335312 edist=0.21221435423446272
gen:700, globalBestFit:12.045860570955622 edist=0.028524440328110825
gen:800, globalBestFit:11.594352179114685 edist=0.022423928726239363
gen:900, globalBestFit:10.63460907436306 edist=0.008949303488937677
gen:1000, globalBestFit:10.342613452960736 edist=0.025739792111941773
gen:1100, globalBestFit:10.278183028539402 edist=0.01966159442339601
gen:1200, globalBestFit:10.230571716986748 edist=0.004781061180254118
gen:1300, globalBestFit:10.206778154515673 edist=0.0027585356551705327
gen:1400, globalBestFit:4.21199214946001 edist=0.11044276390279283
gen:1500, globalBestFit:4.209998843036691 edist=0.0028659065728237885
gen:1600, globalBestFit:4.2035010423581225 edist=0.0055041306035474745
gen:1700, globalBestFit:4.202363573217319 edist=0.00185579918822108
gen:1800, globalBestFit:4.2019167071476655 edist=0.0004010604761363078
gen:1900, globalBestFit:4.2003246265829945 edist=0.0005337626937005378
gen:2000, globalBestFit:4.035943689183826 edist=0.0006156148545869195
gen:2100, globalBestFit:3.493170104391786 edist=0.007735864742317073
gen:2200, globalBestFit:3.4931191189882345 edist=0.00024931370394743754
gen:2300, globalBestFit:3.4912596189648433 edist=0.0001549454032002674
gen:2400, globalBestFit:3.4911936330446287 edist=0.0001831807970544893
gen:2500, globalBestFit:3.4911613219665285 edist=0.00032676222476040053
gen:2600, globalBestFit:3.490804294866671 edist=0.0004056227143997571
gen:2700, globalBestFit:3.4900755979953337 edist=0.001168432874858142
gen:2800, globalBestFit:3.4900754481408707 edist=1.3346724706805687e-05
gen:2900, globalBestFit:3.4900740002058406 edist=5.048235604124714e-05
gen:3000, globalBestFit:3.4900735578862796 edist=8.424026856664483e-06
gen:3100, globalBestFit:3.3849269004992886 edist=0.0068067067561920595
gen:3200, globalBestFit:3.148913649320306 edist=2.2935768502744297e-05
gen:3300, globalBestFit:3.1488948924627387 edist=4.567153422387e-06
gen:3400, globalBestFit:3.135293771118033 edist=8.971370104422628e-05
gen:3500, globalBestFit:3.1340031874495815 edist=4.6380419962587546e-05
gen:3600, globalBestFit:2.289747397418629 edist=0.00019145220989673026
gen:3700, globalBestFit:2.289736435955503 edist=1.0276812898504331e-05
gen:3800, globalBestFit:2.288121631430392 edist=1.4154205436656599e-05
gen:3900, globalBestFit:2.28812163073056 edist=2.2083803462505684e-06
gen:4000, globalBestFit:2.288118583854497 edist=3.3065313796153507e-05
gen:4100, globalBestFit:2.28811858378051 edist=1.5934859221160837e-07
gen:4200, globalBestFit:2.2881185830966047 edist=1.3569036566932365e-07
gen:4300, globalBestFit:2.1021249015614165 edist=0.013452444030302614
gen:4400, globalBestFit:1.839192615679958 edist=1.4032264185780908e-05
gen:4500, globalBestFit:1.8389182768308665 edist=9.894243874537981e-06
gen:4600, globalBestFit:1.2009247318466547 edist=0.00027616139434793503
gen:4700, globalBestFit:1.2009247298919337 edist=4.2455652814341236e-08
gen:4800, globalBestFit:1.0634456461923518 edist=0.016093128415467724
gen:4900, globalBestFit:1.063445646170368 edist=6.379338506255092e-07
gen:5000, globalBestFit:1.0634456461686805 edist=2.556073278318917e-09
gen:5100, globalBestFit:1.0609334727196071 edist=0.0005444926725752089
gen:5200, globalBestFit:1.044946857982695 edist=8.019115574376528e-06
gen:5300, globalBestFit:1.044946857982695 edist=5.648460111558194e-09
gen:5400, globalBestFit:1.044946857982695 edist=4.706677788923633e-09
gen:5500, globalBestFit:1.044946857982695 edist=6.124950431751896e-09
gen:5600, globalBestFit:1.044946857982695 edist=5.245436965043857e-09
gen:5700, globalBestFit:1.044946857982695 edist=5.109895639391901e-09
gen:5800, globalBestFit:1.044946857982695 edist=6.0806834627457175e-09
gen:5900, globalBestFit:1.044946857982695 edist=5.901550715670337e-09
gen:6000, globalBestFit:1.044946857982695 edist=5.402952303104211e-09
gen:6100, globalBestFit:1.044946857982695 edist=5.1068643875222125e-09
gen:6200, globalBestFit:1.044946857982695 edist=5.199160412573614e-09
gen:6300, globalBestFit:1.044946857982695 edist=5.0077877882783456e-09
gen:6400, globalBestFit:1.044946857982695 edist=4.567956456774929e-09
gen:6500, globalBestFit:1.044946857982695 edist=5.3463461093980934e-09
gen:6600, globalBestFit:1.044946857982695 edist=4.847356599918589e-09
gen:6700, globalBestFit:1.044946857982695 edist=4.710416365992886e-09
gen:6800, globalBestFit:1.044946857982695 edist=4.86152283862822e-09
gen:6900, globalBestFit:1.044946857982695 edist=5.1712110900914705e-09
gen:7000, globalBestFit:1.044946857982695 edist=5.4012591540265925e-09
gen:7100, globalBestFit:1.044946857982695 edist=4.0962133979048434e-09
gen:7200, globalBestFit:1.044946857982695 edist=4.935868281547475e-09
gen:7300, globalBestFit:1.044946857982695 edist=6.607166580586777e-09
gen:7400, globalBestFit:1.044946857982695 edist=4.837894706244063e-09
gen:7500, globalBestFit:1.044946857982695 edist=4.824448067440524e-09
gen:7600, globalBestFit:1.044946857982695 edist=4.380139829717852e-09
gen:7700, globalBestFit:1.044946857982695 edist=4.621512218864146e-09
gen:7800, globalBestFit:1.044946857982695 edist=4.957605851581997e-09
gen:7900, globalBestFit:1.044946857982695 edist=5.222133493948974e-09
gen:8000, globalBestFit:1.044946857982695 edist=4.654821602961558e-09
gen:8100, globalBestFit:1.044946857982695 edist=5.1458517165638435e-09
gen:8200, globalBestFit:1.044946857982695 edist=5.477250273260866e-09
gen:8300, globalBestFit:1.044946857982695 edist=5.966652205340479e-09
gen:8400, globalBestFit:1.044946857982695 edist=5.9957101848306745e-09
gen:8500, globalBestFit:1.044946857982695 edist=4.874319227254483e-09
gen:8600, globalBestFit:1.044946857982695 edist=4.686255861582584e-09
gen:8700, globalBestFit:1.044946857982695 edist=5.7445786081714244e-09
gen:8800, globalBestFit:1.044946857982695 edist=5.4628722603045426e-09
gen:8900, globalBestFit:1.044946857982695 edist=4.922253145189731e-09
gen:9000, globalBestFit:1.044946857982695 edist=4.546249811369738e-09
gen:9100, globalBestFit:1.044946857982695 edist=4.3431760615486774e-09
gen:9200, globalBestFit:1.044946857982695 edist=4.557314989559076e-09
gen:9300, globalBestFit:1.044946857982695 edist=4.432872199030961e-09
gen:9400, globalBestFit:1.044946857982695 edist=5.955503539330763e-09
gen:9500, globalBestFit:1.044946857982695 edist=5.5025801560197266e-09
gen:9600, globalBestFit:1.044946857982695 edist=5.691153115048001e-09
gen:9700, globalBestFit:1.044946857982695 edist=4.764220635576974e-09
gen:9800, globalBestFit:1.044946857982695 edist=4.99556833682449e-09
gen:9900, globalBestFit:1.044946857982695 edist=4.884152101567283e-09
[1.044946857982695, 1.044946857982695, 1.044946857982695, 1.044946857982695, 1.044946857982695, 1.044946857982695, 1.044946857982695, 1.044946857982695, 1.044946857982695, 1.044946857982695]

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

iWTknow

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值