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 案例
用离散差分进化算法求函数
的最大值,其中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行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!