• 粒子群算法


    PSO——连续

    import numpy as np
    import matplotlib.pyplot as plt
    from pylab import *
    matplotlib.use('TkAgg')
    from pylab import *
    mpl.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体
    mpl.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
    from tqdm import tqdm  # 进度条设置
    import random
    
    
    
    class PSO(object):
        def __init__(self, M,T,lb,ub,l,n):
            self.w = 0.6  # 惯性权重
            self.c1 = self.c2 = 2
            self.M= M  # 粒子群数量
            self.T = T
            self.L = l
            self.N = n
            self.lb = lb
            self.ub = ub
            self.lv = -10
            self.uv = 10
    
        def init_x(self):
            x = np.random.uniform(self.lb, self.ub, (self.M, self.L, self.N))
            return x
    
        def init_v(self):
            v = np.random.uniform(0,1,(self.M,self.L,self.N))
            return v
    
        def fitness(self,x):
            """
            (x1-90)**2+(x2-90)**2
            :param x:
            :return:
            """
            result =(x[0]-90) ** 2 + (x[1]-90) ** 2
            return result
    
        def best(self,x):
            l = []
            for m in range(self.M):
                for i in range(self.L):
                    result = self.fitness(list(x[m, i]))
                    l.append(result)
            return l.index(min(l)),l
    
        def updata_v(self,X,V,pbest,gbest):
            r1 = np.random.random((self.M, self.L, self.N))  # (粒子个数,1)
            r2 = np.random.random((self.M, self.L, self.N))
            V = self.w * V + self.c1 * r1 * (pbest - X) + self.c2 * r2 * (gbest - X)  # 直接对照公式写就好了
            # 防止越界处理
            V[V < self.lv] = np.random.random() * (self.uv - self.lv) + self.lv
            V[V > self.uv] = np.random.random() * (self.uv - self.lv) + self.lv
            return V
        def update_x(self, X, V):
            """
            根据公式更新粒子的位置
            :param X: 粒子当前的位置矩阵,维度是 size*10
            :param V: 粒子当前的速度举着,维度是 size*10
            return  更新后的种群
          """
            X1= X.copy()
            for i in range(self.M):  # 遍历每一个粒子
                for j in range(self.L):  # 遍历粒子中的每一个元素
                    X1[i,j] = X[i,j]+V[i,j]
                # 对当前个体进行限制,放在超重
            return X1
    
        def update_pbest(self, X, fitness, pbest, pbestfitness):
            """
            更新个体最优
            :param X: 当前种群
            :param fitness: 当前每个粒子的适应度
            :param pbest: 更新前的个体最优解
            :param pbestfitness: 更新前的个体最优适应度
            :param m: 粒子数量
            :return: 更新后的个体最优解、个体最优适应度
            """
    
            for i in range(self.M):
                if fitness[i] < pbestfitness[i]:
                    pbest[i] = X[i]
                    pbestfitness[i] = fitness[i]
            return pbest, pbestfitness
    
        def update_gbest(self, pbest, pbestfitness, gbest, gbestfitness):
            """
            更新全局最优解
            :param pbest: 粒子群
            :param pbestfitness: 个体适应度(个体最优)
            :param gbest: 全局最优解
            :param gbestfitness: 全局最优解
            :param m: 粒子数量
            :return: gbest全局最优,g对应的全局最优解
            """
            for i in range(self.M):
                if pbestfitness[i] < gbestfitness:
                    gbest = pbest[i]
                    gbestfitness = pbestfitness[i]
            return gbest, gbestfitness
    
    
        def main(self):
            op_list = []
            x = self.init_x()
            v = self.init_v()
            num,pbestfitness = self.best(x)
            gbestfitness = max(pbestfitness)
            op_list.append(gbestfitness)
            pbest = x
            gbest = x[num]
            for i in range(self.T):
                v = self.updata_v(x,v,pbest,gbest)
                x = self.update_x(x,v)
                num1,fitness = self.best(x)
                pbest, pbestfitness = self.update_pbest(x,fitness,pbest,pbestfitness)
                gbest, gbestfitness = self.update_gbest( pbest, pbestfitness, gbest, gbestfitness)
                op_list.append(gbestfitness)
    
            print("最优适应度是:%.5f" % op_list[-1])
            print("最优解是", gbest)
            plt.plot(op_list, label='PSO')
            plt.xlabel('Iterations', size=13)
            plt.ylabel('Fitness', size=13)
            plt.legend()
            plt.show()
    
    
    if __name__ == '__main__':
        pso = PSO(30, 1000,-100,100,1,2)  # M,T,lb,ub,l,n
        pso.main()

    PSO-离散

    import numpy as np
    import matplotlib.pyplot as plt
    from tqdm import tqdm  # 进度条设置
    import matplotlib.pyplot as plt
    import matplotlib;
    
    matplotlib.use('TkAgg')
    from pylab import *
    
    mpl.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体
    mpl.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
    
    
    
    #未修改
    
    class BackPack(object):
        def __init__(self):
            self.Weight = [95, 75, 23, 73, 50, 22, 6, 57, 89, 98]  # 物品体积
            self.Value = [89, 59, 19, 43, 100, 72, 44, 16, 7, 64]  # 物品价值
            self.N = 50 # 群体粒子个数
            self.D = 10 # 粒子维数
            self.T = 200# 最大迭代次数
            self.c1 = 2  # 学习因子1
            self.c2 = 2  # 学习因子2
            self.w = 1.5  # 惯性因子,一般取1
            self.V_max = 1  # 速度最大值
            self.V_min = -1  # 速度最小值
            self.Weight_max = 300  # 背包容量
            self.afa = 100# 惩罚系数
    
                
        # 初始化种群
        def init_x(self):
            """
            :return: 随机生成的种群(二维list)
            """
            X = np.random.choice([0, 1], size=(self.N, self.D))
            return X
    
        # 初始化速度
        def init_v(self):
            """
            :return: 速度
            """
            V = np.random.random(size=(self.N, self.D))  ##10维
            return V
    
        # 适应度值
        def fitness_func(self, X):
            """
            :param X: 种群
            :return:
            """
            """计算粒子的的适应度值,也就是目标函数值,X 的维度是 size * 10 """
            size = np.shape(X)[0]  # 种群个数
            result = np.zeros((size, 1))
    
            for i in range(size):  # 遍历每一个粒子
                fit = sum(X[i] * self.Value)  # 物品价值
                TotalSize = sum(X[i] * self.Weight)  # 物品重量
                l=list(X[i])
                #xiandinglegeshu
                if TotalSize <= self.Weight_max and l.count(1)<=1:  # 如果小于限制重量
                    fit = fit
                    result[i] = fit
    
                else:
                    if TotalSize - self.Weight_max>0:
                        fit = fit - self.afa * (TotalSize - self.Weight_max)  # 对fit进行惩罚
                    else:
                        fit = fit +self.afa * (TotalSize - self.Weight_max)  # 对fit进行惩罚
                    # fit=0
                    result[i] = fit
    
            return result  # 我们要求result越大
    
        # 速度更新公式
        def velocity_update(self, V, X, pbest, gbest):
            """
            根据速度更新公式更新每个粒子的速度
             种群size=100
            :param V: 粒子当前的速度矩阵,size*10 的矩阵
            :param X: 粒子当前的位置矩阵,size*10 的矩阵
            :param pbest: 每个粒子历史最优位置,size*10 的矩阵
            :param gbest: 种群历史最优位置,1*10 的矩阵
            """
            r1 = np.random.random((self.N, 1))  # (粒子个数,1)
            r2 = np.random.random((self.N, 1))
            V = self.w * V + self.c1 * r1 * (pbest - X) + self.c2 * r2 * (gbest - X)  # 直接对照公式写就好了
            # 防止越界处理
            V[V < self.V_min] = np.random.random() * (self.V_max - self.V_min) + self.V_min
            V[V > self.V_max] = self.V_max - np.random.random() * (self.V_max - self.V_min)
    
            # V[V < self.V_min] =self.V_min
            # V[V > self.V_max] =self.V_max
            return V
    
        # 位置更新公式
        def position_update(self, X, V):
            """
            根据公式更新粒子的位置
            :param X: 粒子当前的位置矩阵,维度是 size*10
            :param V: 粒子当前的速度举着,维度是 size*10
            return  更新后的种群
          """
    
            for i in range(self.N):  # 遍历每一个粒子
                # 修改速度为sigmoid形式
    
                V[i, :] = 1. / (1 + np.exp(-np.array(V[i, :])))
                for j in range(self.D):  # 遍历粒子中的每一个元素
                    rand = np.random.random()  # 生成 0-1之间的随机数
                    if V[i, j] > rand:
                        X[i, j] = 1
                    else:
                        X[i, j] = 0
                # 对当前个体进行限制,放在超重
                while np.sum(X[i] * self.Weight) > self.Weight_max:  # 如果当前粒子超重
                    X[i] = np.random.choice([0, 1], size=(1, self.D))
            return X
    
        def update_pbest(self, X, fitness, pbest, pbestfitness, m):
            """
            更新个体最优
            :param X: 当前种群
            :param fitness: 当前每个粒子的适应度
            :param pbest: 更新前的个体最优解
            :param pbestfitness: 更新前的个体最优适应度
            :param m: 粒子数量
            :return: 更新后的个体最优解、个体最优适应度
            """
    
            for i in range(m):
                if fitness[i] > pbestfitness[i]:
                    pbest[i] = X[i]
                    pbestfitness[i] = fitness[i]
            return pbest, pbestfitness
    
        def update_gbest(self, pbest, pbestfitness, gbest, gbestfitness, m):
            """
            更新全局最优解
            :param pbest: 粒子群
            :param pbestfitness: 个体适应度(个体最优)
            :param gbest: 全局最优解
            :param gbestfitness: 全局最优解
            :param m: 粒子数量
            :return: gbest全局最优,g对应的全局最优解
            """
            for i in range(m):
                if pbestfitness[i] > gbestfitness:
                    gbest = pbest[i]
                    gbestfitness = pbestfitness[i]
            return gbest, gbestfitness
    
        def main(self):
            fitneess_value_list = []  # 记录每次迭代过程中的种群适应度值变化
            x = self.init_x()  # 初始化x
            v = self.init_v()  # 初始化v
            # 计算种群各个粒子的初始适应度值
            p_fitness = self.fitness_func(x)
            # 计算种群的初始最优适应度值
            g_fitness = p_fitness.max()
            # 讲添加到记录中
            fitneess_value_list.append(g_fitness)
            # 初始的个体最优位置和种群最优位置
            pbest = x
            gbest = x[p_fitness.argmax()]  #
    
            # 接下来就是不断迭代了
            for i in tqdm(range(self.T)):
                pbest = pbest.copy()  # 必须加,不然会被篡改值,造成结果错
                p_fitness = p_fitness.copy()  # 必须加,不然会被篡改值,造成结果错
                gbest = gbest.copy()  # 必须加,不然会被篡改值,造成结果错
                g_fitness = g_fitness.copy()  # 必须加,不然会被篡改值,造成结果错
                v = self.velocity_update(v, x, pbest, gbest)  # 更新速度
                x = self.position_update(x, v)  # 更新位置
                p_fitness2 = self.fitness_func(x)  # 计算子代各个粒子的适应度
    
                # 更新每个粒子的历史最优位置
                pbest, p_fitness = self.update_pbest(x, p_fitness2, pbest, p_fitness, self.N)
    
                # 更新群体的最优位置
                gbest, g_fitness = self.update_gbest(pbest, p_fitness, gbest, g_fitness, self.N)
    
                # 记录最优迭代结果
                fitneess_value_list.append(g_fitness)
    
            print("最优适应度是:%.5f" % fitneess_value_list[-1])
            print("最优解是", gbest)
            print('最优解对应的体积', np.sum(gbest * self.Weight))
            print('最优解对应的价值', np.sum(gbest * self.Value))
    
            plt.plot(fitneess_value_list, label='迭代曲线')
            plt.xlabel('迭代次数')
            plt.ylabel('适应度')
            plt.legend()
            plt.show()
    
    
    if __name__ == '__main__':
        pso = BackPack()
        pso.main()
  • 相关阅读:
    hdu 1201 18岁生日
    线性代数
    关于pymongo的一些说明
    利用数组进行数据处理
    通用函数:快速的元素级数组函数
    IPython:一种交互式计算和开发环境
    关于一道面试题的思考
    wireshark中的抓包过滤器和显示过滤器
    wireshark推荐书籍
    wireshark 找不到网卡的解决办法
  • 原文地址:https://www.cnblogs.com/qj696/p/16326507.html
Copyright © 2020-2023  润新知