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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java贪吃蛇源码

    java贪吃蛇源码java是一种面向对象的语言,有着其中不用质疑的优点。学习java将近三个月了,一直在琢磨着“万物皆对象”的意义,却总是只知其表不知其意,做完这个java贪吃蛇后才有了那么一点的理解。直接上效果图。游戏分为了六个类,分别为:Node类:蛇身都是由一个一个节点组成,所以首先将节点抽象为一个类。Snake类:此类是一条蛇抽象出来的一个类。一种包含了存储节点的LinkedList类型…

    2022年5月9日
    51
  • HTML和CSS面试题及答案总结一

    HTML和CSS面试题及答案总结一对于html的语义化标签的理解,结构化标签的理解,同时写出简洁的html结构,如何进行SEO优化?答:对于html的语义化标签,用正确的标签做正确的事情。html语义化,让页面的内容结构化,便于对浏览器和搜索引擎的解析,在没有css样式的情况下,以文档的形式同样易于阅读,符合文档语义的标签。标签本身所代表的语义,每一个标签所带有的语义,根据语义去使用标签,依赖标记确定权重,同时也可以提高SE…

    2022年5月10日
    44
  • qtreewidget基本使用_qtreewidget列宽自适应

    qtreewidget基本使用_qtreewidget列宽自适应1、voidQTreeWidget::setHeaderLabels(constQStringList&labels)设置表头,QStringList有几项,表头就有多少列2、voidQHeaderView::setSortIndicatorShown(boolshow)Thispropertyholdswhetherthesortindicatoris

    2022年10月1日
    0
  • rider 激活码分享【中文破解版】

    (rider 激活码分享)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.htmlS32PGH0SQB-eyJsaWNlbnNlSWQi…

    2022年3月25日
    381
  • LabVIEW入门教程

    LabVIEW从初学到入门LabVIEW简介如何入门LabVIEW我该去哪找相应学习资源LabVIEW简介LabVIEW是一款图形化编程语言(G语言),由美国国家仪器研制(NationalInstruments,NI)研制,被称为虚拟仪器(VirtualInstrument,VI)。它提供了整套的工具用来对信号进行采集、分析、保存及后续的处理。优点:界面美观程序模块化强与设备交…

    2022年4月4日
    47
  • 后台开元模板 H-ui.admin

    后台开元模板 H-ui.admin

    2022年3月12日
    31

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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