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)


相关推荐

  • Camera 之水波纹和banding现象[通俗易懂]

    Camera 之水波纹和banding现象[通俗易懂]预览画面中出现了一条明一条暗相间隔的竖条纹,这种现象叫做“水波纹”,并对原因进行了讲解,现记录如下。其实这些“水波纹”产生是因为手机的快门频率与灯光的频率不匹配导致的。首先,我们都知道手机拍照的时候都是有一定曝光时间的,例如假设手机的快门频率为50Hz,则其拍照时的曝光时间就是20ms。同理,屏幕或者日光灯不是一直在发光的,而是更隔一段时间就会刷新一次,我们生活中的日光灯为50Hz,国外的是60Hz。例如那个50Hz,就代表每秒刷新50次,因为刷…

    2022年10月13日
  • Vue进阶(三十六):created() 详解「建议收藏」

    Vue进阶(三十六):created() 详解「建议收藏」这次给大家带来vue.js中created方法的使用详解,使用vue.js中created方法的注意事项有哪些,下面就是实战案例,一起来看一下。这是它的一个生命周期钩子函数,就是一个vue实例被生成后调用这个函数。一个vue实例被生成后还要绑定到某个html元素上,之后还要进行编译,然后再插入到document中。每一个阶段都会有一个钩子函数,方便开发者在不同阶段处理不同逻辑。一般可以在creat…

  • Elasticsearch索引迁移的四种方式

    Elasticsearch索引迁移的四种方式本文主要讲解Elasticsearch下实现索引迁移的几种方式。0、引言将ES中的索引拷贝到其他ES中,或者将ES整体迁移,研究发现有两个开源的工具:elaticserch-dump和Elasticsearch-Exporter。除此之外,logstash在索引同步、迁移方面的作用也很大。两工具及logstash实现迁移的介绍、安装、使用、验证效果等展示如下:1、el…

  • stm32编程步骤_单片机STM32

    stm32编程步骤_单片机STM32近几年来,从云计算、大数据到机器学习、AI、物联网,各种新潮的技术概念一波~~接一波。于是就产生了一些好奇心旺盛,抱着去凑一凑热闹的心态,实际上却是也想分一杯羹儿的程序员!但问题是,在他们的技术栈里,一切…

  • 我写的RadControls_Q1_2005注册机「建议收藏」

    我写的RadControls_Q1_2005注册机「建议收藏」有个朋友给我来信,说激活成功教程某控件时ildasm无法反汇编出il代码,我近来也遇到一些类似情况,只有试着做注册机,居然成功。想验证注册机真实性的朋友可把你的主机的ip地址暂时设为60.20.130.15试一下就知道了   control=”combobox”/>……现在急需asp.net空间,能免费提供的请与我联系 

  • 红帽子linux 架设ftp,RedHatLinux9架设FTP服务器方法[通俗易懂]

    红帽子linux 架设ftp,RedHatLinux9架设FTP服务器方法[通俗易懂]1.安装vsftpd服务器vsftpd是目前Linux最好的FTP服务器工具之一,其中的vs就是“VerySecure”(很安全)的缩写,可见它的最大优点就是安全,除此之外,它还具有体积小,可定制强,效率高的优点。如果选择完全安装RedHatLinux9.0,则系统会默认安装vsftpd服务器。我们可以在终端命令窗口输入以下命令进行验证:[root@ahpengroot]rpm-qagrepvsf…

发表回复

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

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