• 连续问题北极熊算法


    import matplotlib;
    matplotlib.use('TkAgg')
    from pylab import *
    mpl.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体
    mpl.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
    import numpy as np
    from tqdm import tqdm  # 进度条设置
    import random
    # 更改了位置更新函数,
    
    class PBO(object):
        """"
         M:种群最大容量
         m:种群当前规模大小
         N:目标函数解的维度
         T:迭代次数
         V:最大视野距离
         P:初始化种群数量百分比
         K:动态调整规模参数
         B:变量限制范围
         X:解集合
         """
        def __init__(self):
            self.M =50
            self.N= 2
            self.T= 200
            self.V= 0.3
            self.P= 0.75
            self.K= 0.25
            self.x_min = -32  #暂时设置每个维度的可移动范围相同,实际需要根据N个维度进行设置
            self.x_max = 32
            self.m = int(np.floor(self.M*self.P)) #随后期的繁衍和死亡会变化
    
    
            # 初始化种群
    
        def init_x(self):
            """
            :return:
            """
            X = np.zeros((self.M, self.N))
            X[:self.m] = np.random.random((self.m, self.N)) * (self.x_max - self.x_min) + self.x_min
            return X
    
        def fitness(self,X):
            """
            有待更改
            :param X:
            :return:
            """
            # y = X[0]+X[1]+X[2]+X[3]+X[4]+X[5]+X[6]+X[7]+X[8]+X[9]
            y = -1*np.sum(X**2)
            return y
    
        def up_data(self,index,angle,radius,action,X):
            """
            局部搜索中的位置更新公式  公式看原版文献csdn有误
            :param index:每一只熊的的编号
            :param angle:angles [0,2pi]
            :param X[index][0]:第index只熊的0维
            :param radius:
            :param action:
            :param X:
            :return:
            """
            temp = np.zeros(self.N)
            result = 0
            if "add".__eq__(action):
                x_temp = X[index][0] + radius * np.cos(angle[0])
            else:
                x_temp = X[index][0] - radius * np.cos(angle[0])
            if x_temp>=self.x_min and x_temp<=self.x_max:
                temp[0] = x_temp
            elif x_temp<self.x_min :
                temp[0] = self.x_min
            elif x_temp>self.x_max:
                temp[0] = self.x_max
    
    
            #因为从第2到n-1只熊由通用计算工时
            for i in range(self.N-2):
                result += np.sin(angle[i])
                if "add".__eq__(action):
                    x_temp = X[index][i+1] + radius * (result+np.cos(angle[i+1]))
                else:
                    x_temp = X[index][i+1] - radius * (result+np.cos(angle[i+1]))
                if x_temp >= self.x_min and x_temp <= self.x_max:
                    temp[i + 1] = x_temp
                elif x_temp < self.x_min:
                    temp[i + 1] = self.x_min
                elif x_temp > self.x_max:
                    temp[i + 1] = self.x_max
            if "add".__eq__(action):
                x_temp = X[index][self.N-1] + radius * (result + np.sin(angle[self.N-2]))
            else:
                x_temp = X[index][self.N-1] - radius * (result + np.sin(angle[self.N-2]))
            if x_temp >= self.x_min and x_temp <= self.x_max:
                temp[self.N-1] = x_temp
            elif x_temp < self.x_min:
                temp[self.N-1] = self.x_min
            elif x_temp > self.x_max:
                temp[self.N-1] = self.x_max
            return temp
    
        def move_local(self,X):
            """
            局部更新 (包含搜索半径 和局部更新)
            :param X:
            :return:
            r=4acos(φ)sin(φ)
            """
            # 对每个北极熊设计随机角度  根据公式计算出搜索半径  r=4acos(φ)sin(φ)
            for i in range(self.m):
                angles = np.random.random(self.N-1) * 2 * np.pi  # [0,2pi]用于局部搜索中的位置更新
                sta = np.random.random() * self.V  # [0,0.3]
                angle0 = np.random.random() * np.pi / 2  # [0,pi/2]
                # 搜索半径
                r = 4 * sta * np.cos(angle0) * np.sin(angle0)
                # using the sign of add
                tmp = self.up_data(i, angles, r, 'add', X)
                if self.fitness(tmp) > self.fitness(X[i]):
                    X[i] = tmp
                else:
                    tmp = self.up_data(i, angles, r, 'minus', X)
                if self.fitness(tmp) > self.fitness(X[i]):
                    X[i] = tmp
            return X
    
        def move_globle(self,X,xbest):
            """
            浮水漂移,全局搜索
            X:M行N列的二维矩阵 ,每一个子矩阵代表一个多纬度的北极熊
            全局位置更新
            :return:
            """
            for i in range(self.m):
                # 每一只熊的W
                w = np.sqrt(np.sum(xbest - X[i]) ** 2)    #w是n-1个维度的欧氏距离
                alpha = np.random.random()
                gamma = np.random.random() * w  # 0-w之间的随机数
                x_temp = X[i] + np.sign(w) * alpha + gamma
    
                x_temp[x_temp<self.x_min] = self.x_min
                x_temp[x_temp>self.x_max] = self.x_max
                if self.fitness(x_temp) > self.fitness(X[i]):
                     X[i] = x_temp
            return X
    
    
        def fit_best(self,X,f_best,x_best):
            fits = np.zeros(self.m)
            for i in range(self.m):
                #找个体最优
                fits[i] = self.fitness(X[i])
            arg = np.argsort(fits[:self.m])
            if fits[arg[-1]]>=f_best:
                f_best = fits[arg[-1]]
                x_best = X[arg[-1]]
            return f_best,x_best,fits
    
    
        def zhongqunfangyan(self,X,x_best,fits):
            k = np.random.random()
            arg = np.argsort(fits[:self.m])
            # 种群繁衍
            if self.m < self.M - 1 and k > 0.75:
                # 从前10%中随机抽取一个 个体与最好个体交配 生成新的个体
                idx = random.randint(1, np.floor(self.m * 0.1) + 1)
                X[self.m] = (x_best + X[arg[self.m-1-idx]]) / 2
                self.m += 1
            # 最弱个体死亡
            if self.m > self.M * 0.5 and k < 0.25:
                # arg中排序最后的为最弱个体
                # 死亡之后 后面的所有个体往前移动一个位置
                X[arg[0]:self.m] = X[arg[0] + 1:self.m + 1]
                self.m -= 1
            return  X
    
        def main(self):
            fitness_list = []    #画图使用
            x_best_list=[]
            X = self.init_x()
            f_best = -1*np.inf   #表示负无穷
            x_best = 0
            f_best,x_best,fits = self.fit_best(X,f_best,x_best)
            fitness_list.append(f_best)
    
    
            #先局部后全局搜索
            for i in tqdm(range(self.T)):
                X = self.move_local(X)
                X = self.move_globle(X,x_best)
                print(i)
                #计算当前适应度
                f_best, x_best,fits= self.fit_best(X, f_best, x_best)
                fitness_list.append(f_best)
                print(x_best)
                #种群动态变化
                X = self.zhongqunfangyan(X,x_best,fits)
                f_best, x_best, fits = self.fit_best(X, f_best, x_best)
            print("最大适应度值:", f_best, '个体为:', x_best)
            plt.plot(fitness_list, "--")
            plt.xlabel('迭代次数', size=15)
            plt.ylabel('fitness', size=15)
            plt.legend()
            plt.show()
    
    if __name__ == '__main__':
    
           pbo = PBO()
           pbo.main()
  • 相关阅读:
    mysql将一个表的数据 重复复制多份到表中
    PHP中将指定文本内容导入到word中
    系统安全-SElinux
    通过身份证号码提取年龄,性别
    MySQL-获取某天的数据
    mysql-介绍、MySQL部署、数据类型、存储引擎
    监控系统-ELK
    监控系统-Grafana
    监控系统-zabbix
    监控系统-openfalcon
  • 原文地址:https://www.cnblogs.com/qj696/p/16091926.html
Copyright © 2020-2023  润新知