原文章:NSGA2算法原理及python实现_w要变强的博客-CSDN博客_nsga2 python

算法原理不多说了,网上都有,我是在NSGAII里加上约束违反值计算,实现不等式约束

RCM01问题:

#  这是Kalyanmoy Deb教授流行的NSGA-II算法的python实现# 导入模块
import math
import random
import matplotlib.pyplot as plt# 第一个约束函数
def function1(x1, x2, x3, x4):z1 = 0.0625 * x1value = 1.7781 * z1 * x3 ** 2 + 0.6224 * z1 * x2 * x4 + 3.1661 * z1 ** 2 * x4 + 19.84 * z1 ** 2 * x3return value# 第二个约束函数
def function2(x3, x4):value = -math.pi * x3 ** 2 * x4 - (4 / 3) * math.pi * x3 ** 3return value#计算约束违反值
def CV(x):z1 = 0.0625 * x[0]z2 = 0.0625 * x[1]g1 = 0.00954 * x[2] - z2g2 = 0.0193 * x[2] - z1if g1<=0 and g2<=0:return 0elif g1<=0 and g2>0:return g2elif g2<=0 and g1>0:return g1elif g1>0 and g2>0:return g1+g2# 查找列表值的索引的函数
def index_of(a, list):for i in range(0, len(list)):if list[i] == a:return ireturn -1# 按序号排序的功能
def sort_by_values(list1, values):  # list为下标序列,values为值序列sorted_list = []while (len(sorted_list) != len(list1)):  # 遍历len(list1)次if index_of(min(values), values) in list1:sorted_list.append(index_of(min(values), values))  # 查找该层次中的最小值所在的索引values[index_of(min(values), values)] = math.inf  # math.inf 浮点正无限(设置最小的(边界))的值为无穷,当找不到的时候设置最后一个为浮点正无限(return -1)return sorted_list# 执行NSGA-II快速非支配排序的功能
def fast_non_dominated_sort(values1, values2,cv):S = [[] for i in range(0, len(values1))]  # 生成values1(种群大小)个空列表的二维列表S,S记录被P支配的集合front = [[]]  # 一个空的二维列表n = [0 for i in range(0, len(values1))]  # 生成values1(种群大小)个0的一维列表n,n指p被支配的个数rank = [0 for i in range(0, len(values1))]  # 生成values1(种群大小)个0的以为列表,rank指非支配序for p in range(0, len(values1)):  # p为种群中的每个个体,遍历种群S[p] = []  # 初始化当前个体p支配的集合n[p] = 0  # 初始化当前个体p被支配的个数for q in range(0, len(values1)):  # q为种群中的每个个体,遍历种群(两层遍历达到每两两都进行比较)if cv[p]==0 and cv[q]==0:   #当p和q都不违反约束时if (values1[p] > values1[q] and values2[p] > values2[q]) or (values1[p] >= values1[q] and values2[p] > values2[q]) or (values1[p] > values1[q] and values2[p] >= values2[q]):  # 如果函数1当前值p大于函数1其他值而且函数2当前值大于函数2其他值# 或者  函数1当前值p不小于函数1其他值而且函数2当前值大于函数2其他值# 或者  函数1当前值p大于函数1其他值而且函数2当前值不小于函数2其他值# (判断条件 使其找到非支配前沿)if q not in S[p]:  # 保证当前p并未在S[p]中(即证明p支配q)S[p].append(q)  # 添加被p支配的集合S[p]elif (values1[q] > values1[p] and values2[q] > values2[p]) or (values1[q] >= values1[p] and values2[q] > values2[p]) or (values1[q] > values1[p] and values2[q] >= values2[p]):  # 如果函数1当前值p大于函数1其他值而且函数2当前值大于函数2其他值# 或者  函数1当前值p不小于函数1其他值而且函数2当前值大于函数2其他值# 或者  函数1当前值p大于函数1其他值而且函数2当前值不小于函数2其他值# (判断条件 p受q支配)n[p] = n[p] + 1  # 使其p被支配个数n[p]加1elif cv[p]==0 and cv[q]>0:  #当p是可行解,而q不可行时if q not in S[p]:  # 保证当前p并未在S[p]中(即证明p支配q)S[p].append(q)  # 添加被p支配的集合S[p]elif cv[p]>0 and cv[q]==0:  #当p时不可行解,而q是可行解时n[p]=n[p]+1if n[p] == 0:  # 如果p不被其他群体支配rank[p] = 0  # 则设置其非支配序为0if p not in front[0]:  # 并通过判断将其添加到(第一列)前沿序列Z1中front[0].append(p)print(front)i = 0while (front[i] != []):  # 通过判断前一列序列是否为空(保证不为空) i = 0(即第二步)Q = []  # 初始化另一个集Qfor p in front[i]:  # 遍历当前列序列里面的每个个体for q in S[p]:  # 考察它所支配的个体集s[p]n[q] = n[q] - 1  # 集合S[p]中的每个个体q的(被支配个数)n[q]减1(因为支配个体q已经加入到当前集front[i],即以不属于下面的序列)if (n[q] == 0):  # (注:在减1之前n[q]不存在为0的个数,以为在之前将n[q]=0的个体已经加入到front[0])rank[q] = i + 1  # 如果当前个体不再受其他个体支配,设置其该集合相同的非支配序rank值if q not in Q:  # 通过判断将其加入到当前最优集QQ.append(q)i = i + 1  # 继续下一序列集front.append(Q)  # 将其添加到前沿序列# print(front)del front[len(front) - 1]  # 最后一个序列什么都没有添加元素,即(front[i]==0)循环结束,故删除最后一个空列表return front  # 返回快速非支配排序后的结果,rank为其所在二维列表中所在一维列表的下标# [[6], [4], [11], [8, 17], [1], [5], [7], [2, 19], [13, 16], [18], [3], [0], [12], [14], [15], [9], [10]]# 需要注意的是其返回的只是种群个体下标划分的列表集(非值,形式如上)# 计算拥挤距离
def crowding_distance(values1, values2, front):  # 注意:此处front是一维列表形式,每个层次序号distance = [0 for i in range(0, len(front))]  # 初始化该层个体距离集合,且初值为0sorted1 = sort_by_values(front, values1[:])  # 返回函数1该层最小的索引(并设置好了无穷)sorted2 = sort_by_values(front, values2[:])  # 返回函数2该层最小的索引(并设置好了无穷)distance[0] = 4444444444444444  # 初始化(正无穷)distance[len(front) - 1] = 4444444444444444  # 初始化(正无穷)for k in range(1, len(front) - 1):  # 求函数1的拥挤度distance[k] = distance[k] + (values1[sorted1[k + 1]] - values2[sorted1[k - 1]]) / (max(values1) - min(values1))for k in range(1, len(front) - 1):  # 加上函数2的拥挤度distance[k] = distance[k] + (values1[sorted2[k + 1]] - values2[sorted2[k - 1]]) / (max(values2) - min(values2))return distance  # 返回改层拥挤距离集# 执行交叉
def crossover(a, b):answer=[]for i in range(len(a)):r = random.random()if r > 0.5:  # 算术交叉(由两个个体的线性组合而产生两个新的个体,该操作对象一般由浮点数编码表示的个体)answer.append(mutation((a[i] + b[i]) / 2,min_xi[i],max_xi[i]))else:answer.append(mutation((a[i] - b[i]) / 2,min_xi[i],max_xi[i]))# return mutation((a - b) / 2)return answer# 执行变异算子
def mutation(solution,minx,maxx):mutation_prob = random.random()if mutation_prob < 1:solution = minx + (maxx - minx) * random.random()return solution# 生成初始种群
def init(min_xi, max_xi, num):i = 0solution = []  # 存放结果种群数组,里面存放的每个元素格式为[x1,x2,x3……]while (i < num):x=[0]*len(min_xi)#随机生成x值for j in range(len(min_xi)):x[j]=min_xi[j] + (max_xi[j] - min_xi[j]) * random.random()#计算约束值z1=0.0625*x[0]z2=0.0625*x[1]g1=0.00954*x[2]-z2g2=0.0193*x[2]-z1if(g1<0 and g2<0):solution.append(x)i+=1return solution# 主程序从这里开始
pop_size = 30
max_gen = 1000# 初始化
min_xi = [1, 1, 10, 10]
max_xi = [99, 99, 200, 200]
solution=init(min_xi,max_xi,pop_size)   #solution的结构为[[x1,x2,x3,x4],[x1,x2,x3,x4]]
print("solution:")
print(solution)gen_no = 0
while (gen_no < max_gen):  # 循环921代,即每次循环为一个繁殖# 将产生的20个种群个体分别运用到function1 和function2# 即function1_values和function2_values为不同函数的计算值列表function1_values = [function1(solution[i][0],solution[i][1],solution[i][2],solution[i][3]) for i in range(0, pop_size)]function2_values = [function2(solution[i][2],solution[i][3]) for i in range(0, pop_size)]cv=[CV(solution[i]) for i in range(0,pop_size)]# print(function2_values[:])# 运行快速非支配排序法非支配排序解集合 (在python中使用列表切片[:]既可以复制原列表,复制后又不会改变原列表)non_dominated_sorted_solution = fast_non_dominated_sort(function1_values[:], function2_values[:],cv)print("第", gen_no, "代最优的点集是:")  # 开始输出结果for valuez in non_dominated_sorted_solution[0]:  # 遍历最优解集合(存储的只是下标)print([round(solution[valuez][0], 3),round(solution[valuez][1], 3),round(solution[valuez][2], 3),round(solution[valuez][3], 3)], end=" ")  # round() 返回浮点数x的四舍五入值print("\n")print("第", gen_no, "代最优的解是:")  # 开始输出结果result=[]print(len(non_dominated_sorted_solution[0]))for valuez in non_dominated_sorted_solution[0]:  # 遍历最优解集合(存储的只是下标)print([function1_values[valuez],function2_values[valuez]],end=" ")result.append([function1_values[valuez],function2_values[valuez]])  # round() 返回浮点数x的四舍五入值print("\n")# print(len(result))crowding_distance_values = []  # 定义拥挤距离值for i in range(0, len(non_dominated_sorted_solution)):  # 遍历快速非支配排序法产生的分级结果集crowding_distance_values.append(crowding_distance(function1_values[:], function2_values[:],non_dominated_sorted_solution[i][:]))  # 计算拥挤距离 (高级用法[:]( ̄▽ ̄)~*)# 求出每层的拥挤距离值并集中到crowding_distance_valuessolution2 = solution[:]  # (在python中使用列表切片[:]既可以复制原列表,复制后又不会改变原列表)# 产生后代while (len(solution2) != 2 * pop_size):  # 使产生的后代后种群大小为2Na1 = random.randint(0, pop_size - 1)  # random.randint(a,b)b1 = random.randint(0, pop_size - 1)  # 随机产生[a,b]中的一个数solution2.append(crossover(solution[a1], solution[b1]))  # 通过交叉变异产生一个新的后代# 将产生的2N个种群个体分别运用到function1 和function2# 即function1_values2和function2_values2为不同函数的计算值列表function1_values2 = [function1(solution2[i][0],solution2[i][1],solution2[i][2],solution2[i][3]) for i in range(0, 2 * pop_size)]function2_values2 = [function2(solution2[i][2],solution2[i][3]) for i in range(0, 2 * pop_size)]cv2=[CV(solution2[i]) for i in range(0,2*pop_size)]non_dominated_sorted_solution2 = fast_non_dominated_sort(function1_values2[:], function2_values2[:],cv2)  # 再次求快速非支配排序法crowding_distance_values2 = []for i in range(0, len(non_dominated_sorted_solution2)):crowding_distance_values2.append(crowding_distance(function1_values2[:], function2_values2[:], non_dominated_sorted_solution2[i][:]))# 求出每层的拥挤距离值并集中到crowding_distance_values2new_solution = []  # 初始化新解集for i in range(0, len(non_dominated_sorted_solution2)):  # 遍历拥挤距离集层non_dominated_sorted_solution2_1 = [index_of(non_dominated_sorted_solution2[i][j], non_dominated_sorted_solution2[i]) for j inrange(0, len(non_dominated_sorted_solution2[i]))]  #front22 = sort_by_values(non_dominated_sorted_solution2_1[:], crowding_distance_values2[i][:])front = [non_dominated_sorted_solution2[i][front22[j]] for j inrange(0, len(non_dominated_sorted_solution2[i]))]front.reverse()  # 将前沿解集进行翻转for value in front:  # 遍历前沿解集new_solution.append(value)  # 添加到新的解集合if (len(new_solution) == pop_size):breakif (len(new_solution) == pop_size):  # 保证新的种群个数仍然为Nbreaksolution = [[solution2[i][0],solution2[i][1],solution2[i][2],solution2[i][3]] for i in new_solution]gen_no = gen_no + 1
f = open("k1.txt", "a")
f.writelines(str(result))
f.writelines('\n')
f.close()
# 绘制图形
function1 = [i * -1 for i in function1_values]
function2 = [j * -1 for j in function2_values]
plt.xlabel('Function 1', fontsize=10)
plt.ylabel('Function 2', fontsize=10)
plt.scatter(function1, function2)
plt.savefig('image1/20.jpg')
plt.show()

结果图:

也测试了RCM25,结果图如下:

Python实现带不等式约束的NSGAII算法解决cec2021中的RCM01问题相关推荐

  1. 【MPC的前身方法一】(5.2)【不使用机器人模型】反馈+前馈的控制方式计算反作用力+反作用力计算与线性约束的优化(即带不等式约束的最小二乘问题)方法

    系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录 前言 一.先使用反馈+前馈的控制方式,根据躯干期望的位置速度,计算出当前身 ...

  2. 利用匈牙利算法Hopcroft-Karp算法解决二分图中的最大二分匹配问题 例poj 1469 COURSES...

    首先介绍一下题意:已知,有N个学生和P门课程,每个学生可以选0门,1门或者多门课程,要求在N个学生中选出P个学生使得这P个学生与P门课程一一对应. 这个问题既可以利用最大流算法解决也可以用匈牙利算法解 ...

  3. 使用ga算法解决背包问题_我如何使用算法解决现实生活中的手提背包的背包问题

    使用ga算法解决背包问题 I'm a nomad and live out of one carry-on bag. This means that the total weight of all m ...

  4. python不带颜色的图形_python – 为什么seaborn pairplot中的kde子图中没有显示颜色?...

    使用参数创建seaborn pairplot sns.pairplot(iris.drop("Id", axis=1), diag_kind="kde", hu ...

  5. python NSGA-II 算法

    NSGA-II 算法 NSGA-II 提出的 NSGA的缺点 算法计算量大.NSGA算法的计算复杂度与种群数量N.目标函数个数m的关系为T = O(mN3),当种群规模较大.目标函数较多时所耗时间较长 ...

  6. UA SIE545 优化理论基础3 Fritz-John与Kuhn-Tucker理论总结 带等式约束与不等式约束的极值问题

    UA SIE545 优化理论基础3 Fritz-John与Kuhn-Tucker理论总结 带等式约束与不等式约束的极值问题 对于函数f:X→Yf:X \to Yf:X→Y,我们希望XXX是一个凸的度量 ...

  7. 粒子群算法python实现: 带活化因子

    粒子群算法python实现: 带活化因子 求解一个较复杂的函数 实现 求解一个较复杂的函数 def function(x):#2004年考研题(我这里只求极小值):x^2-6xy+10^2-2yz-z ...

  8. Python 遗传算法求解Stackelberg均衡问题(带概率约束)

    目录 引言 遗传算法 关键词解释 MCMC Stackelberg 算法思路 求解某一次博弈过程中的遗传算法逻辑 各文件(模块)间调用关系 求解结果 在50轮博弈中,下层的决策变化: 在50轮博弈中, ...

  9. matlab 遗传算法 等式约束,关于MATLAB遗传算法工具箱不等式约束

    过去很久了,之前写论文的经验分享一下. 写毕业论文的时候需要用到遗传算法,网上查了很多资料,由于没时间认真去学算法的内部结构,最后还是选择了MATLAB自带的遗传算法工具箱(MATLAB2017-GA ...

最新文章

  1. influxDB和grafana
  2. “黄背心”运动持续进行 马克龙发长信呼吁沟通
  3. 关于C# this 指针
  4. linux shell获取字符串第1个字符
  5. 这就是搜索引擎:核心技术详解
  6. 从MongoDB GridFS流式传输文件
  7. JPA EntityManagers,事务及其周围的一切
  8. wget下载速度太慢,mwget多线程下载工具
  9. Java 基础数据结构介绍
  10. stm32--FatFs调试过程(SPIFlash)
  11. SVN上传文件注意事项-------------------养成良好的项目文件上传习惯
  12. 开发者的实用 Vim 插件(二)
  13. java提示程序包有问题_如何解决安装java时出现程序包有问题不能运行的问题?...
  14. sql server 2008 新建服务器注册,SQL Server 2008中不能注册服务器怎么回事
  15. 抖音视频评论获取系统,获取抖音评论的系统
  16. 批量合成bilibili的m4s缓存文件为MP4格式 ver2.5
  17. elasticsearch + ik
  18. 无法连接虚拟设备 ide1:0,因为主机上没有相应的设备。 您要在每次开启此虚拟机时都尝试连接此虚拟设备吗?
  19. 【转载】SOP SO SOIC TSSOP SSOP 封装直观比较图
  20. 问题 : Day of Week

热门文章

  1. 【ArcGIS】server授权文件ecp超期的处理
  2. 计算机科学与技术论文摘要范文,计算机科学与技术论文范文两篇(2)
  3. 最全软件测试面试题(经典)
  4. 咖说 | 暗潮涌动,ERC20 BTC 正在搅动市场
  5. GPS地图升级价格一览表
  6. 卖一次淫,帮助一名失学儿童--看完…
  7. 硬盘的主流技术,最新的硬盘技术
  8. Keras下载数据失败,本地导入
  9. 【Solidity】函数returns多个值的接收方式
  10. Ubuntu VNC 如何调整分辨率