Python—标准遗传算法求函数最大值代码实现

参考资料《智能优化算法及其matlab实例第二版》

第一次写博客,格式什么的不太清楚,大家见谅。

遗传算法

学习过程中,为了加深自己理解,在matlab源码的基础上采用Python进行改写,功能一致,对其实现过程进行了修改。个人认为这个版本的代码对初学者更为友好。

遗传算法的基本概念本文简单介绍,重点在于给出实现代码

简而言之,遗传算法就是一个小世界。我们需要为这个世界创造规则。

种群:所有个体的集合,我们会在最初的设定中,给出种群的数目,这个数量就是一次迭代中所有存活的个体数。

个体:染色体的携带者,现实世界中的个体是鲜活的,明确的,但是在遗传算法中,它可能就表现为一段二进制变量,或者是一些实数变量,这个会跟我们选取的染色体表现方式有关。在本例中选取0、1编码的方式刻画染色体。

染色体:每一个个体携带的编码,通常适应度函数会把染色体的信息作为输入以此评估个体的优劣,在遗传算法中个体和染色体的概念比较相似,有时理解为一个也ok的,只要不影响编写代码。

适应度函数:评估个体好坏的函数,适者生存,适应度函数就是选出“适者”的函数。每一个特定问题对应不同的生存法则,所以适应度函数都不一样。

迭代次数:可以理解为这个世界存在的时间,我们会预设一个迭代次数的最大值,算法迭代次数达到最大值时,种群进化过程结束。

复制、交叉、变异:参考生物意义上的概念,都是针对染色体的操作。

代码部分

直接附上代码,代码复制后可以直接运行。

import numpy as np
import matplotlib.pyplot as plt
# import math as mt
import seaborn as sns
sns.set_style('darkgrid')

x=np.arange(0,10,0.02)
y=x+10*np.sin(5*x)+7*np.cos(4*x)
plt.plot(x,y)   #画原函数
plt.title('Primitive function')
plt.xlabel('x',fontsize = 10)
plt.ylabel('y',fontsize = 10)
plt.savefig('pic1',bbox_inches = 'tight',pad_inches = 0,dpi =350)
plt.close()

def funcl(x):
    y=y=x+10*np.sin(5*x)+7*np.cos(4*x)
    return y
#%%
NP=50   #初始化种群数
L=20    #二进制位串长度
Pc=0.8  #交叉率
Pm=0.3  #变异率
G=100   #最大遗传代数
Xs=10   #上限
Xx=0    #下限
f=np.random.randint(0,high=2,size=(NP,L))   #生成随机初始种群
fit=np.zeros((1,100))[0].tolist()
x=np.zeros((1,100))[0].tolist()
trace=[]
xtrace=[]
#%%遗传算法循环
for i in range(G):
    print(i)
    nf=f
    for M in range(0,NP,2):
        p=np.random.rand()     #交叉
        if p<Pc:
            q=np.random.randint(0,high=2,size=(1,L))[0].tolist()
            for j in range(L):
                if q[j]==1:
                    temp=nf[M+1][j]
                    nf[M+1][j]=nf[M][j]
                    nf[M][j]=temp
    j=1
    while j<=(NP*Pm):
        h=np.random.randint(1,high=NP)  #变异
        for k in range(round(L*Pm)):
            g=np.random.randint(1,high=L)
            nf[h][g]=(not nf[h][g])+0         #取反操作,python和matlab不一样
        j+=1
    #交叉变异结束之后,新一代nf加上前代f共2*NP个个体进行筛选
    newf=np.vstack((f,nf))
    for j in range(newf.shape[0]):
        U=newf[j]
        m=0
        for k in range(L):
            m=U[k]*(2**(k-1))+m    #将二进制解码为定义域范围内十进制
        x[j]=Xx+m*(Xs-Xx)/(2**(L-1))
        fit[j]=funcl(x[j])         #适应度函数
    maxfit=max(fit)
    minfit=min(fit)
    if maxfit==minfit:
        break
    rr=fit.index(maxfit)
    fbest=f[rr]
    xbest=x[rr]
    Fit=(np.array(fit)-minfit)/(maxfit-minfit)
    sum_Fit=sum(Fit)   #概率筛选复制操作(不是简单的复制,我们是根据适应函数给导向的)
    Pfit=Fit/sum_Fit
    indexnf=np.arange(0,100).tolist()
    ng=[]
    for dex in range(NP):
        ng.append(np.random.choice(indexnf,p=Pfit))
    for j in range(NP):
        f[j]=newf[ng[j]]
    f[0]=fbest
    trace.append(maxfit)
    xtrace.append(xbest)
 
plt.plot(trace,color='green', marker='o',linewidth=2, markersize=3)
plt.xlabel('Number of iterations',fontsize = 10)
plt.ylabel('maxyvalue',fontsize = 10)
plt.savefig('pic3',bbox_inches = 'tight',pad_inches = 0,dpi =350)
plt.close()

plt.plot(xtrace,color='m', marker='o',linewidth=2, markersize=3)
plt.xlabel('Number of iterations',fontsize = 10)
plt.ylabel('Corresponding xvalue',fontsize = 10)
plt.savefig('pic2',bbox_inches = 'tight',pad_inches = 0,dpi =350)
plt.close()

简单介绍一下代码内容:

我们的目标是对这个函数求最大值: f(x) = x+10sin(5x)+7cos(4x)

它的图像长这样:

       估计应该是7到8之间的那个点最大,然后,就开始遗传算法了。与参考资料源码不同的是,我们生成的第一代种群数目是50,先经过了交叉和变异,得到50个新的个体,加上原来的50个,就一共是100了,再对这100个进行筛选复制的过程,选出50个作为下一代,迭代次数为100次。下面是算法得到的结果。第一张是收敛得到的x的值,第二张是maxy的值。

 

  • 14
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值