不知道为什么一个大一的萌新能有这么多事要干......蚁群算法的代码先缓一缓,等博主写完作业,考完英语期中再说吧。关于遗传算法的代码,由于忘记了np数组不copy的时候会直接引用,导致很长一段时间不知道自己哪里出bug了,调了半天才想出来。所以大家学python的时候一定要打好基础呀~~下面是遗传算法的代码:
from math import *
from random import *
import numpy as np
import matplotlib.pyplot as plt
#遗传算法步骤
f=lambda x:x+10*np.sin(5*x)+7*np.cos(4*x)
#绘制函数图像,读者可自行去掉#号查看
x0=np.linspace(0,10,50000)
y0=f(x0)
#plt.figure()
#plt.plot(x0,y0)
#plt.show()
#初始参数
num=100 #种群数量
n=20 #DNA长度
pc=0.6 #交叉互换概率
pm=0.001 #变异概率
G=100 #最大代数
adaption=0.01 #适应度补充值
x=[i for i in range(0,101)] #代数,即迭代次数
y=[] #历代最优值
a=0 #下界
b=10 #上界
lis=[] #种群集
#1.选取初始种群
for i in range(num):
lis.append(np.random.randint(2,size=n))
#产生num个随机的DNA,只用两种碱基
for generation in range(G):
#2.解码
lis0=[] #个体函数值集
for k in lis:
s=0
for j in range(n):
s+=k[j]*2**(n-1-j)
lis0.append(f(a+s*(b-a)/(2**n)))
#3.适应度计算
minlis=min(lis0)
maxlis=max(lis0)
y.append(maxlis)
top=lis0.index(maxlis)
ad_lis=[] #适应度集
for i in range(num):
ad_lis.append(lis0[i]-minlis+adaption)
sum_ad=sum(ad_lis)
for i in range(num):
ad_lis[i]=ad_lis[i]/sum_ad
#4.物竞天择
#先计算部分和方便使用轮盘法
ad_k=[] #适应度部分和序列
optlis=[] #储存物竞天择后的个体
for i in range(num):
ad_k.append(sum(ad_lis[0:i+1]))
for i in range(num-1):#物竞天择,但是留出一个位置给父辈的最优者
p=random()
for j in range(num):
if p<ad_k[j]:
opt=j
break
optlis.append(lis[opt].copy())
#lis[opt]是对lis中的数组的引用!!
#这里如果不使用copy,后面对optlis进行修改时也会带动lis的修改!!!
#5.繁衍后代
#先交叉互换,然后变异
newlis=[]
for i in range(0,num-1):
A=optlis[i]#父本
l=randint(0,98)
B=optlis[l]#母本
for j in range(0,n):
p1=random()
if p1<pc:
A[j]=B[j] #交叉互换
newlis.append(A.copy())
for i in range(0,num-1):
C=newlis[i]
for j in range(0,n):
p2=random()
if p2<pm:
C[j]=1-C[j] #变异
newlis.append(lis[top].copy())
#6.重复进化
lis=newlis
#将上面的步骤重复G次,即繁衍G代
lis0=[] #清空上一代函数值,准备做最后的处理
x1=[] #最后一代x值集合
for k in lis:
s=0
for i in range(n):
s+=k[i]*2**(n-1-i)
x1.append(a+s*(b-a)/(2**n)) #记录最后一代的x值
lis0.append(f(a+s*(b-a)/(2**n))) #记录最后一代的y值
y.append(max(lis0)) #将最后一代的最优值储存
top=lis0.index(max(lis0))
print([x1[top],max(lis0)]) #输出最优x值和y值
#绘制图像
yc=[max(y0) for i in range(len(y))]
plt.figure()
plt.plot(x,y,'b-',label='GA')
plt.plot(x,yc,'r-',label='max(f)')
plt.legend()
plt.show()
下面是原函数图像:
下面是算法的迭代过程,做了多次,选择其中两次进行参考:
不难看出来遗传算法的收敛速度还是挺快的~~若要了解遗传算法的原理,请移步至博主的另一篇短文《遗传算法原理》。