看这篇文章之前,读者应已经理解差分进化算法。
用python写带约束条件的差分进化的代码时,我参考了别人不带约束条件的代码。我解决的问题如下图所示。
我得到的结果如下
-14.98869与-15差一点,不过算是找到了f(x)的最小值。对应的向量也与(1,1,1,1,1,1,1,1,1,3,3,3,1)差不多。
我的代码如下:
# -*- coding: cp936 -*-
import pdb
import g01
import matplotlib.pyplot as plt
global Gm,F0,Np,CR,D
Gm=500
F0=0.5
Np=130
CR=0.2
G=1
D=13
from numpy import *
import numpy as np
V=np.zeros((Np,D))
U=np.zeros((Np,D))
XG_next=np.zeros((Np,D))
value=np.zeros(Np)
cv=np.zeros(Np)
cv[:]=1000
##############产生初始种群############
from numpy import random
max0=1
max1=100
min0=0
min1=0
X0=random.random(size=(Np,D))
for i in range(9):
X0[:,i]=X0[:,i]*(max0-min0)+min0
for i in range(9,12):
X0[:,i]=X0[:,i]*(max1-min1)+min1
X0[:,12]=X0[:,12]*(max0-min0)+min0
XG=X0
while G<=Gm:
print G
####################变异操作###################
for i in range(1,Np):
li=range(Np)
random.shuffle(li)
dx=li
j=dx[0]
k=dx[1]
p=dx[2]
#要保证与i不同
if j==i:
j=dx[3]
elif k==i:
k=dx[3]
elif p==i:
p=dx[3]
#变异操作
suanzi=math.exp(1-float(Gm)/(Gm+1-G))
F=F0*(2**suanzi)
mutant=XG[p]+F*(XG[j]-XG[k])
for j in range(9):
if mutant[j]>min0 and mutant[j]
else:
V[i,j]=(max0-min0)*random.rand()+min0
for j in range(9,12):
if mutant[j]>min1 and mutant[j]
else:
V[i,j]=(max1-min1)*random.rand()+min1
if mutant[12]>min0 and mutant[12]
else:
V[i,12]=(max0-min0)*random.rand()+min0
#######################交叉操作#####################
for i in range(Np):
randx=range(D)
random.shuffle(randx)
for j in range(D):
if random.rand()>CR and randx[0]!=j:
U[i,j]=XG[i,j]
else:
U[i,j]=V[i,j]
########################选择操作######################
for i in range(Np):
f1=g01.f(XG[i])
f2=g01.f(U[i])
g1=g01.g(XG[i])
g2=g01.g(U[i])
if g1==0 and g2==0:
if f1
else:
XG_next[i]=U[i]
elif g1==0 or g2==0:
if g1==0:
XG_next[i]=XG[i]
else:
XG_next[i]=U[i]
elif g1!=0 and g2!=0:
if g1
else:
XG_next[i]=U[i]
XG=XG_next
G=G+1
for i in range(Np):
cv[i]=g01.g(XG[i])
if abs(cv[i]-0)<0.05:
value[i]=g01.f(XG[i])
best_value=min(value)
temp=value.tolist()
pos_min=temp.index(min(temp))
print best_value
best_vector=XG[pos_min]
print best_vector
我写的函数在另一个叫g01.py的文件里,这个文件是对问题的描述,代码如下。
def f(v): 初始种群Xi(i=1,2,...Np)——>变异Vi(i=1,2,...Np)——>交叉Ui(i=1,2,...Np),接下来就是选择操作,这与不带约束条件的差分进化算法不同,我这里用到的方法如下: 设有m个约束条件,计算每个约束条件的违约值:,比如我解决的这个问题中,第一个约束条件g1(x)=2*x1+2*x2+x10+x11-10<0,那么某一个解向量(1,1,1,1,1,1,1,1,1,3,3,3,1)对应的第一个约束条件的违约值是max(2*1+2*1+3+3-10,0)=0,函数对应的违约值为0时,对应的xi即为满足约束条件的个体。 下面就要计算一个解向量对应的违约值了,即(1,1,1,1,1,1,1,1,1,3,3,3,1)对应的违约值,用到这个公式:,这叫向量的违约值,记为cv,cv越小,说明这个解向量越满足约束条件。所以,在进行选择操作时,我用到这样一个方法: 举个例子: 选择得到的新群体再进行变异,交叉选择操作,就这样迭代数次后,群体里的每个个体就越来越趋近于minimum vector了。
import math
y=5*(v[0]+v[1]+v[2]+v[3])-5*(v[0]**2+v[1]**2+v[2]**2+v[3]**2)-\
(v[4]+v[5]+v[6]+v[7]+v[8]+v[9]+v[10]+v[11]+v[12])
return y
def g(v):
import math
g1=2*v[0]+2*v[1]+v[9]+v[10]-10
g2=2*v[0]+2*v[2]+v[9]+v[11]-10
g3=2*v[1]+2*v[2]+v[10]+v[11]-10
g4=-8*v[0]+v[9]
g5=-8*v[1]+v[10]
g6=-8*v[2]+v[11]
g7=-2*v[3]-v[4]+v[9]
g8=-2*v[5]-v[6]+v[10]
g9=-2*v[7]-v[8]+v[11]
g1=max(g1,0)
g2=max(g2,0)
g3=max(g3,0)
g4=max(g4,0)
g5=max(g5,0)
g6=max(g6,0)
g7=max(g7,0)
g8=max(g8,0)
g9=max(g9,0)
g=max(g1,g2,g3,g4,g5,g6,g7,g8,g9)
if g==0:
cv=0
else:
cv=1.0/(13*g)*(g1+g2+g3+g4+g5+g6+g7+g8+g9)
return cv
带约束问题与不带约束问题的不同在于,前者有一系列不等式gi(x)(i=1,2,....m)对X进行了限制,所以问题的一个难点在于如何使产生的群体X满足约束条件。我们不可能直接产生这样的群体,只能不断更新群体,使其里条件更近。首先产生满足边界条件的初始种群,在这个问题中,即0