NSGA2_python

NSGA2_pythonimportrandomimportnumpyasnpfrommatplotlib.tickerimport MultipleLocatorimportmatplotlib.pyplotaspltclassNSGA2():   def__init__(self,dim,pop,max_iter):    #维度,群体数量,迭代次数       self.pc=…

大家好,又见面了,我是你们的朋友全栈君。

import random

import numpy as np

from matplotlib.ticker import  MultipleLocator

import matplotlib.pyplot as plt
class NSGA2():

    def __init__(self, dim, pop, max_iter):     #维度,群体数量,迭代次数

        self.pc = 0.4                           #交叉概率

        self.pm = 0.4                           #变异概率

        self.dim = dim                          #搜索维度

        self.pop = pop                          #粒子数量

        self.max_iter = max_iter                #迭代次数

        self.population = []                    #父代种群

        self.new_popu = []                      #选择算子操作过后的新种群

        #self.children = []                     #子代种群

        self.popu_child = []                    #合并后的父代与子代种群

        self.fronts = []                        #Pareto前沿面

        self.rank = []#np.zeros(self.pop)       #非支配排序等级

        self.crowding_distance = []             #个体拥挤度

        self.objectives = []                    #目标函数值,pop行 2列

        self.set = []                           #个体 i的支配解集

        self.np = []                            #该个体被支配的数目

       

    def init_Population(self):                  #初始化种群

        self.population = np.zeros((self.pop,self.dim))

        for i in range(self.pop):

            for j in range(self.dim):

                self.population[i][j] = random.random()

  

    def children_parent(self):                  #父代种群和子代种群合并,pop*2       

        self.popu_child = np.zeros((2*self.pop,self.dim))#self.population

        for i in range(self.pop):

            for j in range(self.dim):

                self.popu_child[i][j] = self.population[i][j]

                self.popu_child[i+self.pop][j] = self.new_popu[i][j]

   

    def select_newparent(self):                 #根据排序和拥挤度计算,选取新的父代种群 pop*2 到 pop*1

        #self.non_donminate2()

        #self.crowd_distance()

        self.population =  np.zeros((self.pop,self.dim))                   #选取新的种群       

        a = len(self.fronts[0]) #Pareto前沿面第一层 个体的个数

        if a >= self.pop:

            for i in range(self.pop):

                self.population[i] = self.popu_child[self.fronts[0][i]]   

        else:

            d = []     #用于存放前b层个体

            i = 1

            while a < self.pop:

                c = a  #新种群内 已经存放的个体数目    *列

                a += len(self.fronts[i])

                for j in range(len(self.fronts[i-1])):

                    d.append(self.fronts[i-1][j])

                    #while d < self.dim:

                        #self.population[j][d] = self.popu_child[self.fronts[i-1][j]][d]

                        #d += 1

                b = i  #第b层不能放,超过种群数目了    *行

                i = i+1

            #把前c个放进去

            for j in range(c):  

                self.population[j] = self.popu_child[d[j]]

            temp = np.zeros((len(self.fronts[b]),2))  #存放拥挤度和个体序号

            for i in range(len(self.fronts[b])):

                temp[i][0] = self.crowding_distance[self.fronts[b][i]]

                temp[i][1] = self.fronts[b][i]

            temp = sorted(temp.tolist())      #拥挤距离由小到大排序

            for i in range(self.pop – c):

                self.population[c+i] = self.popu_child[int(temp[len(temp) – i – 1][1])]          

 #按拥挤距离由大到小填充直到种群数量达到 pop

       

    def cal_obj(self,position):                          #计算一个个体的多目标函数值 f1,f2 最小值

        f1 = position[0]

        f = 0

        for i in range(self.dim-1):

            f += 9*(position[i+1]/(self.dim – 1))

        g = 1+f

        f2 = g*(1- np.square(f1/g))

        return [f1,f2]

   

    def non_donminate2(self):                   #pop*2行

        self.fronts = []                        #Pareto前沿面

        self.fronts.append([])

        self.set = []

        self.objectives = []#np.zeros((2*self.pop,2))

        self.np = np.zeros(2*self.pop)

        self.rank = np.zeros(2*self.pop)

        position = []

        for i in range(2*self.pop):            #越界处理

            for j in range(self.dim):

                if self.popu_child[i][j] < 0:

                    self.popu_child[i][j] = 0  #最小值0

                if self.popu_child[i][j] >1:

                    self.popu_child[i][j] = 1  #最大值1

        for i in range(2*self.pop):

            position = self.popu_child[i]

            #self.cal_obj(position)

            self.objectives.append(self.cal_obj(position))#[i][0] = f1          #将 f1,f2赋到目标函数值矩阵里

            #self.objectives[i][1] = f2

        for i in range(2*self.pop):

            temp = []

            for j in range(2*self.pop):

                #temp=[]

                if j != i:

                    if self.objectives[i][0] >= self.objectives[j][0] and self.objectives[i][1] >= self.objectives[j][1]:

                        self.np[i] += 1         # j支配 i,np+1

                    if self.objectives[j][0] >= self.objectives[i][0] and self.objectives[j][1] >= self.objectives[i][1]:

                        temp.append(j)

            self.set.append(temp)   # i支配 j,将 j 加入 i 的支配解集里

            if self.np[i] == 0:               

                self.fronts[0].append(i)     #个体序号

                self.rank[i] = 1    #Pareto前沿面 第一层级   

        i = 0

        while len(self.fronts[i]) > 0:

            temp = []

            for j in range(len(self.fronts[i])):

                a = 0

                while a < len(self.set[self.fronts[i][j]]):

                    self.np[self.set[self.fronts[i][j]][a]] -= 1

                    if self.np[self.set[self.fronts[i][j]][a]] == 0:

                        self.rank[self.set[self.fronts[i][j]][a]] = i+2   #第二层级

                        temp.append(self.set[self.fronts[i][j]][a])

                    a = a+1

            i = i+1

            self.fronts.append(temp)       

   

    def non_donminate1(self):                    #pop行 快速非支配排序

        self.fronts = []                        #Pareto前沿面

        self.fronts.append([])

        self.set = []

        self.objectives = []#np.zeros((self.pop,2))

        self.np = np.zeros(self.pop)

        self.rank = np.zeros(self.pop)

        position = []

        for i in range(self.pop):            #越界处理

            for j in range(self.dim):

                if self.population[i][j] < 0:

                    self.population[i][j] = 0  #最小值0

                if self.population[i][j] >1:

                    self.population[i][j] = 1  #最大值1

        for i in range(self.pop):

            position = self.population[i]

            #self.cal_obj(position)

            self.objectives.append(self.cal_obj(position))#[i][0] = f1          #将 f1,f2赋到目标函数值矩阵里

            #self.objectives[i][1] = f2

        for i in range(self.pop):

            temp = []

            for j in range(self.pop):

                #temp=[]

                if j != i:

                    if self.objectives[i][0] >= self.objectives[j][0] and self.objectives[i][1] >= self.objectives[j][1]:

                        self.np[i] += 1         # j支配 i,np+1

                    if self.objectives[j][0] >= self.objectives[i][0] and self.objectives[j][1] >= self.objectives[i][1]:

                        temp.append(j)

            self.set.append(temp)   # i支配 j,将 j 加入 i 的支配解集里

            if self.np[i] == 0:               

                self.fronts[0].append(i)     #个体序号

                self.rank[i] = 1    #Pareto前沿面 第一层级   

        i = 0

        while len(self.fronts[i]) > 0:

            temp = []

            for j in range(len(self.fronts[i])):

                a = 0

                while a < len(self.set[self.fronts[i][j]]):

                    self.np[self.set[self.fronts[i][j]][a]] -= 1

                    if self.np[self.set[self.fronts[i][j]][a]] == 0:

                        self.rank[self.set[self.fronts[i][j]][a]] = i+2   #第二层级

                        temp.append(self.set[self.fronts[i][j]][a])

                    a = a+1

            i = i+1

            self.fronts.append(temp)

           

    def selection(self):                               #轮盘赌选择

        self.non_donminate1()                          #非支配排序,获得Pareto前沿面

        pi = np.zeros(self.pop)                        #个体的概率

        qi = np.zeros(self.pop+1)                      #个体的累积概率

        P = 0

        for i in range(len(self.fronts)):

            #for j in range(len(self.fronts[i])):

            P += (1/(i+1))*(len(self.fronts[i]))       #累积适应度

        for i in range(len(self.fronts)):

            for j in range(len(self.fronts[i])):

                pi[self.fronts[i][j]] =  (1/(i+1))/P   #个体遗传到下一代的概率

        for i in range(self.pop):

            qi[0] = 0

            qi[i+1] = np.sum(pi[0:i+1])                #累积概率

        self.new_popu = np.zeros((self.pop,self.dim))

        for i in range(self.pop):

            r = random.random()                        #生成随机数,

            a = 0

            for j in range(self.pop):

                if r > qi[j] and r < qi[j+1]:

                    while a < self.dim:

                        self.new_popu[i][a] = self.population[j][a]

                        a += 1

                j += 1

               

    def crossover(self):                               #交叉,SBX交叉

        for i in range(self.pop-1):

            #temp1 = []

            #temp2 = []

            if random.random() < self.pc:

                #pc_point = random.randint(0,self.dim-1)        #生成交叉点

                #temp1.append(self.population[i][pc_point:self.dim])

                #temp2.append(self.population[i+1][pc_point:self.dim])

                #self.population[i][pc_point:self.dim] = temp2

                #self.population[i+1][pc_point:self.dim] = temp1

                a = random.random()

                for j in range(self.dim):

                    self.new_popu[i][j] = a*self.new_popu[i][j] + (1-a)*self.new_popu[i+1][j]

                    self.new_popu[i+1][j] = a*self.new_popu[i+1][j] + (1-a)*self.new_popu[i][j]

            i += 2      

       

    def mutation(self):                         #变异

        for i in range(self.pop):

            for j in range(self.dim):

                if random.random() < self.pm:

                    self.new_popu[i][j] = self.new_popu[i][j] – 0.1 + np.random.random()*0.2              

                    if self.new_popu[i][j] < 0:

                        self.new_popu[i][j] = 0  #最小值0

                    if self.new_popu[i][j] >1:

                        self.new_popu[i][j] = 1  #最大值1

       

    def crowd_distance(self):                   #拥挤度计算,前沿面每个个体的拥挤度

        self.crowding_distance = np.zeros(2*self.pop)

        for i in range(len(self.fronts)-1):   #fronts最后一行为空集

            temp1 = np.zeros((len(self.fronts[i]),2))

            temp2 = np.zeros((len(self.fronts[i]),2))

            for j in range(len(self.fronts[i])):

                temp1[j][0] = self.objectives[self.fronts[i][j]][0] #f1赋值

                temp1[j][1] = self.fronts[i][j]

                temp2[j][0] = self.objectives[self.fronts[i][j]][1] #f2赋值

                temp2[j][1] = self.fronts[i][j]

            #temp3 = temp1.tolist()

            #temp4 = temp2.tolist()

            temp1 = sorted(temp1.tolist())             #f1排序

            temp2 = sorted(temp2.tolist())             #f2排序

            self.crowding_distance[int(temp1[0][1])] = float(‘inf’)

            self.crowding_distance[int(temp1[len(self.fronts[i])-1][1])] = float(‘inf’)

            f1_min = temp1[0][0]

            f1_max = temp1[len(self.fronts[i])-1][0]

            f2_max = temp2[len(self.fronts[i])-1][0]

            f2_min = temp2[0][0]

            a = 1

            while a < len(self.fronts[i])-1:

                self.crowding_distance[int(temp1[a][1])] = (temp1[a+1][0] – temp1[a-1][0])/(f1_max – f1_min) +  (temp2[a+1][0] – temp2[a-1][0])/(f2_max – f2_min)  #个体i的拥挤度等于 f1 + f2

                a += 1

               

    def draw(self):                             #画图       

        self.objectives = []#np.zeros((self.pop,2))

        position = []       

        for i in range(self.pop):            #越界处理

            for j in range(self.dim):

                if self.population[i][j] < 0:

                    self.population[i][j] = 0  #最小值0

                if self.population[i][j] >1:

                    self.population[i][j] = 1  #最大值1

        self.non_donminate1()

        for i in range(len(self.fronts[0])):

            position = self.population[self.fronts[0][i]]

            self.objectives.append(self.cal_obj(position))

        #for i in range(self.pop):

            #position = self.population[i]

            #self.objectives.append(self.cal_obj(position))#[i][0] = f1          #将 f1,f2赋到目标函数值矩阵里

        x=[]

        y=[]

        for i in range(self.pop):

            x.append(self.objectives[i][0])

            y.append(self.objectives[i][1])   

        ax=plt.subplot(111)

        plt.scatter(x,y)#,marker=’+’)#self.objectives[:][0],self.objectives[:][1]) #?

        #plt.plot(,’–‘,label=”)       

        plt.axis([0.0,1.0,0.0,1.1])

        xmajorLocator = MultipleLocator(0.1)

        ymajorLocator = MultipleLocator(0.1) 

        ax.xaxis.set_major_locator(xmajorLocator)

        ax.yaxis.set_major_locator(ymajorLocator)

        plt.xlabel(‘f1’)

        plt.ylabel(‘f2’)

        plt.title(‘ZDT2 Pareto Front’)

        plt.grid()

        #plt.show()

        plt.savefig(‘ZDT2 Pareto Front 2.png’)

       

    def run(self):                              #主程序

        self.init_Population()                  #初始化种群,选择交叉变异,生成子代种群

        #self.selection()

        #self.crossover()

        #self.mutation()

        for i in range(self.max_iter):

            self.selection()

            self.crossover()

            self.mutation()

            self.children_parent()              #父代与子代种群合并,快速非支配排序和拥挤度计算

            self.non_donminate2()

            self.crowd_distance()

            self.select_newparent()             #根据Pareto等级和拥挤度选取新的父代种群,选择交叉变异            

        self.draw()

        #print(self.fronts)

        #print(self.population)

        #print(self.new_popu)

        #print(self.popu_child)

        #print(self.objectives)

        #print()       

def main():

    NSGA=NSGA2(30,100,500)

    NSGA.run()

if __name__==’__main__’:

    main()
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/144322.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 大数据分析技术方案

    大数据分析技术方案现在已经进入大数据时代,数据是无缝连接网络世界与物理世界的DNA。发现数据DNA、重组数据DNA是人类不断认识、探索、实践大数据的持续过程。大数据分析可以有效地促进营销,个性化医疗治病,帮助学生提高

  • ThreadStart和ParameterizedThreadStart区别「建议收藏」

    ThreadStart和ParameterizedThreadStart区别「建议收藏」ThreadStart:ThreadStart这个委托定义为voidThreadStart(),也就是说,所执行的方法不能有参数。ThreadStartthreadStart=newThread

  • 激活函数-Sigmoid, Tanh及ReLU

    什么是激活函数在神经网络中,我们会对所有的输入进行加权求和,之后我们会在对结果施加一个函数,这个函数就是我们所说的激活函数。如下图所示。为什么使用激活函数我们使用激活函数并不是真的激活什么,这只是一个抽象概念,使用激活函数时为了让中间输出多样化,能够处理更复杂的问题。如果不适用结果函数的话,每一层最后输出的都是上一层输入的线性函数,不管加多少层神经网络,我们最后的输出也只…

  • 警告:Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA

    警告:Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA问题:安装TensorFlow(CPU版本),使用pipinstalltensorflow安装,安装一切顺利,但是在跑一个简单的程序时,遇到如下情况:大概意思是:你的CPU支持AVX扩展,但是你安装的TensorFlow版本无法编译使用。原因:除了通常的算术和逻辑,现代CPU提供了许多低级指令,称为扩展,例如,SSE2,SSE4,AVX等来自维基百科:高级矢量扩…

  • 《前端运维》一、Linux基础–01基础命令与vim

    在开始之前,你需要做一些准备工作,去阿里买一台服务器,服务器的具体细节其实并不是十分重要,我也不会在这里一步一步的教大家如何去买一个服务器。百度一下足够了,但是还是要贴一下这系列文章中,我所使用的服务

  • jedis连接redis3.2.9集群密码问题[通俗易懂]

    jedis连接redis3.2.9集群密码问题[通俗易懂]转载来自:https://www.cnblogs.com/snowstar123/p/5696052.html主要想说的是,源码中对于jedis连接redisclsuter没有设置密码,所以会一直报错说NOAUTH认证需要。后来,在改篇文章的评论中有如下:#1楼 2016-12-2814:21 破壁人  您好按照您的方式进行了修改,但是问题依然出现报错,NOAUTHAuthenticatio…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号