智能优化算法——差分进化算法(Python实现)

7.2 Python实现

import numpy as np

import matplotlib.pyplot as plt

from pylab import *

mpl.rcParams[‘font.sans-serif’] = [‘SimHei’]

mpl.rcParams[‘axes.unicode_minus’] = False

#=适应度函数=

def func1(x):

SUM = [i * i for i in x]

return np.sum(SUM)

#初始化======

NP = 50 # 个体数目

D = 10 # 变量的维数

G = 200 # 最大进化代数

F0 = 0.4 # 初始变异算子

CR = 0.1 # 交叉算子

Xs = 20; # 上限

Xx = -20 # 下限

yz = 10e-6 # 阈值

ob = np.zeros(NP) # 存放个体目标函数值(父辈)

ob1 = np.zeros(NP) # 存放个体目标函数值(子代)

#=赋初值=========

x = np.zeros((NP, D)) # 初始种群 (个体数目,维数)

v = np.zeros((NP, D)) # 变异种群 (个体数目,维数)

u = np.zeros((NP, D)); # 选择种群 (个体数目,维数)

x = np.random.uniform(Xx, Xs, (NP, D)) # 赋初值 (xx-xs之间的随机数 ,(个体数目,维数)

trace = [] # 记录每次迭代的最小适应值

#=计算当前群体个体目标函数值

for i in range(NP): # 遍历每一个个体

ob[i] = func1(x[i, :])

trace.append(np.min(ob))

#差分进化循环=======

for gen in range(G): # 遍历每一代

#=变异操作====

#自适应变异算子=

lambda1 = np.exp(1 - G / (G + 1 - gen))

F = F0 * np.power(2, lambda1)

#=r1,r2,r3和m互不相同=

for m in range(NP): # 遍历每一个个体

r1=np.random.randint(0,NP,1)

while r1==m: #r1不能取m

r1 = np.random.randint(0, NP, 1)

r2=np.random.randint(0,NP,1)

while (r2m) or (r2r1): #r2不能取m 和r1

r2 = np.random.randint(0, NP, 1)

r3 = np.random.randint(0, NP, 1)

while (r3m) or (r3r2) or (r3==r1):#r3不能取m,r2,r1

r3 = np.random.randint(0, NP, 1)

v[m,:]=x[r1,:]+F*(x[r2,:]-x[r3,:]) #v.shape =(50, 10) 存放的是变异后的种群

#交叉操作===

r = np.random.randint(0, D, 1) #随机选择维度 (即选择x的一维)

for n in range(D):#遍历每一个维度

cr=np.random.random() #生成一个0-1之间的随机数

if (cr<CR) or (n==r):#如果随机数小于交叉算子 或者 当前维数 等于r

u[:,n]=v[:,n] #则选择群体个体维数 为变异后的维数

else:

u[:, n]=x[:,n] #为原始维度

#=边界条件处理===

for m in range(NP):#遍历每一个个体

for n in range(D): # 遍历每一个维度

if (u[m,n]<Xx) or (u[m,n]>Xs):#如果当前元素不处于最大值和最小值之间

u[m, n]=np.random.uniform(Xx, Xs)#则重新初始化该元素

#选择操作=

for m in range(NP):#遍历每一个个体

ob1[m]=func1(u[m,:]) #计算子代个体适应度值

for m in range(NP): # 遍历每一个个体

if ob1[m]<ob[m]:#如果子代个体适应度值小于父代个体适应度值

x[m,:]=u[m,:]#则替换个体

for m in range(NP): # 遍历每一个个体

ob[m]=func1(x[m,:]) #修改父代适应度值

trace.append(min(ob))#记录当代最优适应度值

index=np.argmin(ob)#取出最小值所在位置索引

print(‘最优值解\n’,x[index,:])

print(‘最优值\n’,func1(x[index,:]))

plt.plot(trace)

plt.title(‘迭代曲线’)

plt.show()

7.3 结果

最优值解

[-5.89325075e-04 7.66296863e-04 -8.03461860e-04 4.19070900e-04

5.02012066e-04 2.78923440e-04 6.83655920e-04 3.75556622e-04

-5.35755777e-05 3.49538162e-04]

最优值

2.81897616751295e-06

8 案例2


8.1 案例

求函数f(x, y) = 3cos(xy) +x +y的最小值,其中x的取值范围为[-4,4], y的取值范围为[-4, 4]。 这是一个有多个局部极值的函数。

8.2 代码

import numpy as np

import matplotlib.pyplot as plt

from pylab import *

mpl.rcParams[‘font.sans-serif’] = [‘SimHei’]

mpl.rcParams[‘axes.unicode_minus’] = False

#=适应度函数=

def func2(x):

value = 3 * np.cos(x[0] * x[1]) + x[0] + x[1]

return value

#初始化

NP=20 #个体数目

D=2 #变量的维数

G=12 #最大进化代数

F=0.5 #变异算子

CR=0.1 #交叉算子

Xs=4 #上限

Xx=-4 #下限

ob = np.zeros(NP) # 存放个体目标函数值(父辈)

ob1 = np.zeros(NP) # 存放个体目标函数值(子代)

#赋初值====

x = np.zeros((NP, D)) # 初始种群 (个体数目,维数)

v = np.zeros((NP, D)) # 变异种群 (个体数目,维数)

u = np.zeros((NP, D)); # 选择种群 (个体数目,维数)

x = np.random.uniform(Xx, Xs, (NP, D)) # 赋初值 (xx-xs之间的随机数 ,(个体数目,维数)

trace = [] # 记录每次迭代的最小适应值

#=计算当前群体个体目标函数值

for i in range(NP): # 遍历每一个个体

ob[i] = func2(x[i, :])

trace.append(np.min(ob))

#==差分进化循环

for gen in range(G): # 遍历每一代

#=变异操作=

#=r1,r2,r3和m互不相同

for m in range(NP): # 遍历每一个个体

r1 = np.random.randint(0, NP, 1)

while r1 == m: # r1不能取m

r1 = np.random.randint(0, NP, 1)

r2 = np.random.randint(0, NP, 1)

while (r2 == m) or (r2 == r1): # r2不能取m 和r1

r2 = np.random.randint(0, NP, 1)

r3 = np.random.randint(0, NP, 1)

while (r3 == m) or (r3 == r2) or (r3 == r1): # r3不能取m,r2,r1

r3 = np.random.randint(0, NP, 1)

v[m, :] = x[r1, :] + F * (x[r2, :] - x[r3, :]) # v.shape =(20, 2) 存放的是变异后的种群

#交叉操作=

r = np.random.randint(0, D, 1) # 随机选择维度 (即选择x的一维)

for n in range(D): # 遍历每一个维度

cr = np.random.random() # 生成一个0-1之间的随机数

if (cr < CR) or (n == r): # 如果随机数小于交叉算子 或者 当前维数 等于r

u[:, n] = v[:, n] # 则选择群体个体维数 为变异后的维数

else:

u[:, n] = x[:, n] # 为原始维度

#=边界条件处理====

for m in range(NP): # 遍历每一个个体

for n in range(D): # 遍历每一个维度

if (u[m, n] < Xx) or (u[m, n] > Xs): # 如果当前元素不处于最大值和最小值之间

u[m, n] = np.random.uniform(Xx, Xs) # 则重新初始化该元素

#选择操作=

for m in range(NP): # 遍历每一个个体

ob1[m] = func2(u[m, :]) # 计算子代个体适应度值

for m in range(NP): # 遍历每一个个体

if ob1[m] < ob[m]: # 如果子代个体适应度值小于父代个体适应度值

x[m, :] = u[m, :] # 则替换个体

for m in range(NP): # 遍历每一个个体

ob[m] = func2(x[m, :]) # 修改父代适应度值

trace.append(min(ob)) # 记录当代最优适应度值

index=np.argmin(ob)#取出最小值所在位置索引

print(‘最优值解\n’,x[index,:])

print(‘最优值\n’,func2(x[index,:]))

plt.plot(trace)

plt.title(‘迭代曲线’)

plt.show()

8.3 结果

最优值解

[-3.92989959 -3.99847196]

最优值

-10.92832400647969

9 案例3——离散差分算法


9.1 案例

用离散差分进化算法求函数f(x,y)=-[(x{2}+y-1){2}+(x+y{2}-7){2}]/200+10的最大值,其中x的取值为- 100~ 100之间的整数, y的取值为一100~ 100之间的整数。

9.2 Python实现

import numpy as np

import matplotlib.pyplot as plt

from pylab import *

mpl.rcParams[‘font.sans-serif’] = [‘SimHei’]

mpl.rcParams[‘axes.unicode_minus’] = False

#=适应度函数=====

def func3(x):

value=-(np.power(x[0]*x[0]+x[1]-1,2)+np.power(x[0]+x[1]*x[1]-7,2)/200)+10

return value

#print(func3([-2,-3]))

#初始化=======

NP=20 #个体数目

D=2 #变量的维数

G=100 #最大进化代数

F=0.5 #变异算子

CR=0.1 #交叉算子

Xs=100 #上限

Xx=-100 #下限

ob = np.zeros(NP) # 存放个体目标函数值(父辈)

ob1 = np.zeros(NP) # 存放个体目标函数值(子代)

#赋初值===

x = np.zeros((NP, D)) # 初始种群 (个体数目,维数)

v = np.zeros((NP, D)) # 变异种群 (个体数目,维数)

u = np.zeros((NP, D)); # 选择种群 (个体数目,维数)

x = np.random.randint(Xx, Xs, (NP, D)) # 赋初值 (xx-xs之间的随机整数 ,(个体数目,维数)

trace = [] # 记录每次迭代的最大适应值

#======计算当前群体个体目标函数值

for i in range(NP): # 遍历每一个个体

ob[i] = func3(x[i, :])

trace.append(np.max(ob))

#==差分进化循环=

for gen in range(G): # 遍历每一代

#变异操作====

#===r1,r2,r3和m互不相同=

for m in range(NP): # 遍历每一个个体

r1 = np.random.randint(0, NP, 1)

while r1 == m: # r1不能取m

r1 = np.random.randint(0, NP, 1)

r2 = np.random.randint(0, NP, 1)

while (r2 == m) or (r2 == r1): # r2不能取m 和r1

r2 = np.random.randint(0, NP, 1)

r3 = np.random.randint(0, NP, 1)

while (r3 == m) or (r3 == r2) or (r3 == r1): # r3不能取m,r2,r1

r3 = np.random.randint(0, NP, 1)

v[m, :] = np.floor(x[r1, :] + F * (x[r2, :] - x[r3, :]))

v.shape =(20, 2) 存放的是变异后的种群 np.floor 向下取整

#交叉操作=

r = np.random.randint(0, D, 1) # 随机选择维度 (即选择x的一维)

for n in range(D): # 遍历每一个维度

cr = np.random.random() # 生成一个0-1之间的随机数

if (cr < CR) or (n == r): # 如果随机数小于交叉算子 或者 当前维数等于r

u[:, n] = v[:, n] # 则选择群体个体维数 为变异后的维数

else:

u[:, n] = x[:, n] # 为原始维度

#=边界条件处理==

for m in range(NP): # 遍历每一个个体

for n in range(D): # 遍历每一个维度

if (u[m, n] < Xx) or (u[m, n] > Xs): # 如果当前元素不处于最大值和最小值之间

u[m, n] = np.random.randint(Xx, Xs) # 则重新初始化该元素

#=选择操作

for m in range(NP): # 遍历每一个个体

ob1[m] = func3(u[m, :]) # 计算子代个体适应度值

for m in range(NP): # 遍历每一个个体

if ob1[m] > ob[m]: # 如果子代个体适应度值大于父代个体适应度值

x[m, :] = u[m, :] # 则替换个体

for m in range(NP): # 遍历每一个个体

ob[m] = func3(x[m, :]) # 修改父代适应度值

trace.append(max(ob)) # 记录当代最优适应度值

index = np.argmax(ob) # 取出最小值所在位置索引

print(‘最优值解\n’, x[index, :])

print(‘最优值\n’, func3(x[index, :]))

plt.plot(trace)

plt.title(‘迭代曲线’)

plt.show()

9.3 结果

最优解

[-2,-3]

最优值

10.0

10 案例4——求解复杂约束问题


10.1 案例

10.2 Python实现

import numpy as np

import matplotlib.pyplot as plt

from pylab import *

mpl.rcParams[‘font.sans-serif’] = [‘SimHei’]

mpl.rcParams[‘axes.unicode_minus’] = False

#=============分别是计算适应度函数和计算约束惩罚项函数=

def calc_f(X):

“”“计算群体粒子的目标函数值,X 的维度是 size * 2 “””

a = 10

pi = np.pi

x = X[0]

y = X[1]

return 2 * a + x ** 2 - a * np.cos(2 * pi * x) + y ** 2 - a * np.cos(2 * 3.14 * y)

def calc_e(X):

“”“计算群体粒子的目惩罚项,X 的维度是 size * 2 “””

ee = 0

“”“计算第一个约束的惩罚项”“”

e1 = X[0] + X[1] - 6

ee += max(0, e1)

“”“计算第二个约束的惩罚项”“”

e2 = 3 * X[0] - 2 * X[1] - 5

ee += max(0, e2)

return ee

#子代和父辈之间的选择操作

def update_best(parent,parent_fitness,parent_e,child,child_fitness,child_e):

“”"

:param parent: 父辈个体

:param parent_fitness:父辈适应度值

:param parent_e :父辈惩罚项

:param child: 子代个体

:param child_fitness 子代适应度值

:param child_e :子代惩罚项

:return: 父辈 和子代中较优者、适应度、惩罚项

“”"

规则1,如果 parent 和 child 都没有违反约束,则取适应度小的

if parent_e <= 0.0000001 and child_e <= 0.0000001:

if parent_fitness <= child_fitness:

return parent,parent_fitness,parent_e

else:

return child,child_fitness,child_e

规则2,如果child违反约束而parent没有违反约束,则取parent

if parent_e < 0.0000001 and child_e >= 0.0000001:

return parent,parent_fitness,parent_e

规则3,如果parent违反约束而child没有违反约束,则取child

if parent_e >= 0.0000001 and child_e < 0.0000001:

return child,child_fitness,child_e

规则4,如果两个都违反约束,则取适应度值小的

if parent_fitness <= child_fitness:

return parent,parent_fitness,parent_e

else:

return child,child_fitness,child_e

如果你也是看准了Python,想自学Python,在这里为大家准备了丰厚的免费学习大礼包,带大家一起学习,给大家剖析Python兼职、就业行情前景的这些事儿。

一、Python所有方向的学习路线

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

二、学习软件

工欲善其必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

三、全套PDF电子书

书籍的好处就在于权威和体系健全,刚开始学习的时候你可以只看视频或者听某个人讲课,但等你学完之后,你觉得你掌握了,这时候建议还是得去看一下书籍,看权威技术书籍也是每个程序员必经之路。

四、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

五、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

成为一个Python程序员专家或许需要花费数年时间,但是打下坚实的基础只要几周就可以,如果你按照我提供的学习路线以及资料有意识地去实践,你就有很大可能成功!
最后祝你好运!!!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里无偿获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 12
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值