PSO-粒子群算法

PSO-粒子群算法

介绍

嗯,算法作业,网上找的,然后我自己补充了注释,方便理解,仅用于学习和参考。
具体内容嘛,就是用粒子群算法解一个函数最值,太难的我也不会。
目标函数:

x 2 − 4 x + 3 x^{2}-4x+3 x24x+3

完整代码

# -*- coding: utf-8 -*-
import numpy as np
import random
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D#导入该函数是为了绘制3D图
import matplotlib as mpl
import copy
# ----------------------PSO参数设置---------------------------------
class PSO():
    def __init__(self, pN, dim, max_iter): #构造方法 初始参数设置
        self.w = 0.8    #惯性权重
        self.c1 = 2     #个体学习因子
        self.c2 = 2     #群体学习因子
        self.r1 = random.random()   #区间[0,1]内的随机数,增加搜索的随机性
        self.r2 = random.random()   #区间[0,1]内的随机数,增加搜索的随机性
        self.pN = pN    #粒子数量
        self.dim = dim  #搜索维度
        self.max_iter = max_iter  #迭代次数
        self.X = np.zeros((self.pN, self.dim))  #所有粒子的位置
        self.V = np.zeros((self.pN, self.dim))  #所有粒子的速度
        self.pbest = np.zeros((self.pN, self.dim))  #个体历史的最佳位置
        self.gbest = np.zeros((1, self.dim))        #全局历史的最佳位置
        self.p_fit = np.zeros(self.pN)  # 每个个体的历史最佳适应值
        self.fit = 1e10                 # 全局最佳适应值

    # ---------------------目标函数-----------------------------
    def function(self, X):
        return (X**2-4*X+3)

    # ---------------------初始化种群----------------------------------
    def init_Population(self):       
        #初始化粒子
        for i in range(self.pN):     #因为有pN个粒子,所以需要循环pN次,逐一初始化
            #初始化位置与速度
            for j in range(self.dim):#每一个维度都需要生成速度和位置,故循环dim次
                self.X[i][j] = random.uniform(0, 1)
                self.V[i][j] = random.uniform(0, 1)
            #初始化个体最佳位置
            self.pbest[i] = copy.copy(self.X[i])#其实就是给self.pbest定值
            #初始化个体最佳适应值
            tmp = self.function(self.X[i])#得到该粒子初始位置的适应值
            self.p_fit[i] = tmp   #初始时该粒子最佳的适应值
            if tmp < self.fit:    #将全局最佳适应值与该粒子此时适应值比较,若全局最佳适应值大于该粒子此时适应值,则更新全局最优(全局最佳适应值与全局历史的最佳位置都更新)
                self.fit = tmp
                self.gbest = copy.copy(self.X[i])

    def iterator(self):
        fitness = []
        fig = plt.figure(figsize=(20,20))
        ax = fig.add_subplot(111, projection='3d')
        ax.set_xlabel('迭代次数')
        ax.set_ylabel('位置')
        ax.set_zlabel('最优值')
        
        for t in range(self.max_iter):  #迭代次数,不是越多越好
            for i in range(self.pN):  # 更新gbest\pbest
                temp = self.function(self.X[i])
                ax.scatter(t,self.X[i],temp)
                if temp < self.p_fit[i]:  # 更新个体最优 ()
                    self.pbest[i] = copy.copy(self.X[i])
                    self.p_fit[i] = copy.copy(temp)
                    
                    if self.p_fit[i] < self.fit:  # 更新全局最优
                        self.gbest = copy.copy(self.X[i])
                        self.fit = copy.copy(self.p_fit[i])
            for i in range(self.pN):
                #速度更新 公式V(t+1)=w*V(t)+c1*r1*(pbest_i-xi)+c1*r1*(gbest_xi)
                self.V[i] = self.w * self.V[i] + self.c1 * self.r1 * (self.pbest[i] - self.X[i]) + self.c2 * self.r2 * (self.gbest - self.X[i])
                #位置更新 公式X(t+1)=X(t)+V
                self.X[i] = self.X[i] + self.V[i]
                
            fitness.append(self.fit)
            print(self.gbest, end=" ")
            print(self.fit)  # 输出最优值
        plt.savefig('3D.png')
        plt.show()
        return fitness

        # ----------------------程序执行-----------------------
#主函数
if __name__=="__main__":
    my_pso = PSO(pN=40, dim=1, max_iter=100)
    my_pso.init_Population()
    fitness = my_pso.iterator()
    # -------------------画图--------------------
    plt.figure(1)
    plt.title("Figure1")
    plt.xlabel("iterators", size=14)
    plt.ylabel("fitness", size=14)
    t = np.array([t for t in range(0, 100)])
    fitness = np.array(fitness)
    plt.plot(t, fitness, color='b', linewidth=3)
    plt.savefig('polt.png')
    plt.show()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值