目录
前言
代码正文
结果展示
写在最后
之前写过多目标优化的情况,算是一个最基础的版本吧,只考虑了两个变量作为输入,绝对谈不上多个输入,今天这篇在之前的基础上,将输入量增加至6个,同时对交叉、变异函数进行封装,提升代码的规范性和可读性。
基础版多目标优化代码入门:
Python_多目标遗传算法_多输入代码实现
Python_多目标遗传算法_入门学习+代码实现
阅读本文之前默认大家已经具备了基本遗传算法的知识了,否则不建议阅读。遗传算法的基础知识我在之前的博客中给出了说明,这里不再赘述了。
封装函数模块,简单说明一下吧。funcl是优化函数,见下方:
length:计算变量上下限的差值,这一步是为了二进制编码转换成实数写的。
cross:染色体交叉功能。
variation:染色体变异功能
translate:解码,转换成实数值。
def funclsin(x1,x2,x3,x4,x5,x6):
z=-25*(x1-2)**2-(x2-2)**2-(x3-1)**2-(x4-4)**2-(x5-1)**2
return z
def funclcos(x1,x2,x3,x4,x5,x6):
z=x1**2+x2**2+x3**2+x4**2+x5**2+x6**2
return z
def length(lis):
result=max(lis)-min(lis)
return result
def cross(lislocal,a,b):
temp=lislocal[a+1][b]
lislocal[a+1][b]=lislocal[a][b]
lislocal[a][b]=temp
return lislocal
def variation(lislocal,a,b):
lislocal[a][b]=(not lislocal[a][b])+0 #取反操作,python和matlab不一样
return lislocal
def translate(xlist,Ulist,ll):
m=0
x=0
for k in range(ll):
m=Ulist[k]*(2**(k-1))+m
x=xlist[0]+m*length(xlist)/(2**(ll-1))
return x
多目标优化过程,思路跟之前是一样的,不过是增加了输入量,所以代码看上去更多更复杂了,这也是为啥要强调代码封装的重要性。
import numpy as np
import matplotlib.pyplot as plt
import math as mt
#%%
pi=mt.pi
NP=50 #初始化种群数
L=15 #二进制位串长度
Pc=0.9 #交叉率
Pm=0.3 #变异率
G=20 #最大遗传代数
x1=[0,10]
x2=[0,10]
x6=[0,10]
x3=[1,5]
x5=[1,5]
x4=[0,6]
f11=np.random.randint(0,high=2,size=(NP,L)) #生成随机初始种群
f22=np.random.randint(0,high=2,size=(NP,L)) #生成随机初始种群,这里把xy分开生成
f33=np.random.randint(0,high=2,size=(NP,L))
f44=np.random.randint(0,high=2,size=(NP,L))
f55=np.random.randint(0,high=2,size=(NP,L))
f66=np.random.randint(0,high=2,size=(NP,L))
x11=np.zeros(100).tolist() #记录种群生成的x1~x6的十进制数值
x22=np.zeros(100).tolist()
x33=np.zeros(100).tolist()
x44=np.zeros(100).tolist()
x55=np.zeros(100).tolist()
x66=np.zeros(100).tolist()
tempx1=np.zeros(100).tolist()
tempx2=np.zeros(100).tolist()
tempx3=np.zeros(100).tolist()
tempx4=np.zeros(100).tolist()
tempx5=np.zeros(100).tolist()
tempx6=np.zeros(100).tolist()
f1trace=[] #记录第一个目标函数
f2trace=[] #记录第二个目标函数
diedazhongzhi=-1
#%%遗传算法循环
for i in range(G):
print(i)
f1=[]
f2=[]
nf=f11 #出新的种群,在其基础上进行交叉、变异
nf1=f22
nf2=f33
nf3=f44
nf4=f55
nf5=f66
for M in range(0,NP,2):
p=np.random.rand() #交叉
if p
给出第一代和第20代的对比图,我们设计的目标是希望优化函数越小越好。
第一代
第20代
优化效果还是比较明显的。
这个脚本功能已经可以满足大多数比较简单的工程实际优化问题了,但是,可提升的空间还是很大的,具体如下:
那如何在遗传算法中加入这些约束条件,就是后面我们需要讨论和解决的问题了。
假期结束了,继续加油。