摘要:本文按照差分进化算法流程,结合代码,逐步分析了DE求函数最值的全过程。
DE算法主要的控制参数包括:种群规模(NP)、缩放因子(F)和交叉概率(CR)
目标函数和参数定义
import numpy as np
POPULATION = 10
F = 0.7
P_CROSS = 0.9
MAX_ITER = 50
LAM = 1e15
lb = np.array([-10])
ub = np.array([10])
def obj_func(u):
#f的函数
#f = np.cos(u) * np.exp(-(u - np.pi) ** 2)
f = (np.pi)*(np.exp(u**2))+np.cos(u)
return f[0]
初始化种群,随机生成种群个体:个体=下限+rand(0,1)【上限-下限】(确定每个个体的基因)
i为个体序位,j为基因序位
s = np.zeros((POPULATION, len(lb)))# 待变异个体/父代
fitness = np.zeros(POPULATION)
# 初始化种群个体
for i in range(POPULATION):
s[i] = lb + (ub - lb) * np.random.rand(len(lb))
fitness[i] = obj_func(s[i])
i = 0
f_opt = np.min(fitness)# 最优值f
u_opt = s[np.argmin(fitness)]# 最优解x
变异:随机选取种群中两个不同的个体,将其向量差缩放后与待变异个体进行向量合成。
差分进化算法与遗传算法最显着的区别在于DE的个体变异是通过差分策略实现的。
在进化过程中,必须保证新生成的解的有效性,因此必须判断生成的解是否满足边界条件,如果不满足,则需要重新生成(生成方案与初始种群相同)。
while i < MAX_ITER:
i += 1
k = np.random.randint(0, POPULATION, 2)
v = s + F * (s[k[0]] - s[k[1]])# 合成变异个体v,这里v是一个数组
for x in v:
for p in range(len(x)):# 检查v是否满足边界条件
if x[p] > ub[p]:
x[p] = ub[p]
if x[p] < lb[p]:
x[p] = lb[p]
杂交:该代种群与变异中间体交叉【变异体必有基因遗传给下一代】
is_cross = np.random.rand(POPULATION * len(lb)).reshape((POPULATION, len(lb))) < P_CROSS
v = s * (1 - is_cross) + v * is_cross # 按要求杂交
选择:采用贪婪算法来选择下一代种群个体。if f(ui(g+1))⩽f(xi(g))。贪心算法为f。
# 贪心选择
for p in range(POPULATION):
f_new = obj_func(v[p])
if f_new <= fitness[p]:
s[p] = v[p]
fitness[p] = f_new
if f_new < f_opt:
f_opt = f_new
u_opt = v[p]
print(u_opt, f_opt, sep='\t')
Return最优。
print("The solution is:", u_opt)
print("The objective value is:", f_opt)
函数最小值寻优结果:
函数为f(x)=e^(x^2)+cos(x),-10<=x<=10。
这与min=π+1相差无几。
下面是DE算法求函数最小值源代码:
import numpy as np
# define some constants
POPULATION = 10
F = 0.7
P_CROSS = 0.9
MAX_ITER = 50
LAM = 1e15
print("Differential Evolution algorithm for constrained optimization")
print("Test case for nonlinear optimization: ")
print("-------------------------------------------------------------")
lb = np.array([-10])
ub = np.array([10])
# def obj_func(u):
# z = 0.01 * u[0]**2 + u[1]**2 - 100
# g = 10 * u[0] - u[1] - 10
# if g >= 0:
# h = 0
# else:
# h = 1
# z += LAM * h * g**2
# return z
def obj_func(u):
#f的函数
#f = np.cos(u) * np.exp(-(u - np.pi) ** 2)
f = (np.pi)*(np.exp(u**2))+np.cos(u)
return f[0]
# generate the initial generation
s = np.zeros((POPULATION, len(lb)))# 待变异个体/父代
fitness = np.zeros(POPULATION)
# 初始化种群个体
for i in range(POPULATION):
s[i] = lb + (ub - lb) * np.random.rand(len(lb))
fitness[i] = obj_func(s[i])
i = 0
f_opt = np.min(fitness)# 最优值f
u_opt = s[np.argmin(fitness)]# 最优解x
# starting the DE algorithm
while i < MAX_ITER:
i += 1
k = np.random.randint(0, POPULATION, 2)
v = s + F * (s[k[0]] - s[k[1]])# 合成变异个体v,这里v是一个数组
for x in v:
for p in range(len(x)):# 检查v是否满足边界条件
if x[p] > ub[p]:
x[p] = ub[p]
if x[p] < lb[p]:
x[p] = lb[p]
is_cross = np.random.rand(POPULATION * len(lb)).reshape((POPULATION, len(lb))) < P_CROSS
v = s * (1 - is_cross) + v * is_cross # 按要求杂交
# 贪心选择
for p in range(POPULATION):
f_new = obj_func(v[p])
if f_new <= fitness[p]:
s[p] = v[p]
fitness[p] = f_new
if f_new < f_opt:
f_opt = f_new
u_opt = v[p]
print(u_opt, f_opt, sep='\t')
print("The solution is:", u_opt)
print("The objective value is:", f_opt)