提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
遗传算法是和粒子群算法、蚁群算法等归于一类的自启发式算法。 通过给定方向的随机迭代过程对多维方程进行求解。 遗传算法的实现过程包括了对染色体的编码,迭代过程中的交叉变异,以及所谓的自然选择。以上都是废话,能看到这篇文字的人怎么会不知道这个呢。
一、遗传算法通用基础
染色体的编码
通常采用二进制编码的方式。
将方程中一个未知数当做一个染色体,整个方程的解构成一个个体,则染色体上的二进制位就称之为基因。
示例:
假设一个参数的取值范围为
(
a
,
b
)
(a,b)
(a,b),那么取染色体长度为20。
区间内的取值可以表示为
s
o
l
u
t
i
o
n
=
d
e
c
i
m
a
l
(
c
h
r
o
m
a
)
×
(
b
−
a
2
20
)
+
a
solution=decimal(chroma)×(\frac{b-a}{2^{20}})+a
solution=decimal(chroma)×(220b−a)+a
自然看出染色体长度越长,精度就越高。
初次之外还有其他的编码方式,如实数编码,字符编码等等。
交叉与变异
交叉的方式有单点交叉和多点交叉两种。
变异没什么好说的,多点变异。
变异的概率通常取0.05,交叉的概率通常取0.7。
遗传策略
通常采用的是俄罗斯轮盘赌的方式,通过计算累计概率密度确定那些个体被淘汰。同时也还有最优保存等方式。我采用的是最优保存,通过每次迭代把最差个体替换为最优个体。收敛速递快一些。
二、本篇的不同点
这篇文字来源于我的毕业设计,其中的算法来自于:基于多种群进化的遗传算法 吕 卉1,周 聪2,邹 娟2,郑金华2
其与GA的区别是有两个副种群采用不同的交叉突变概率进行演化,并且将每代副种群的最优个体加入主种群。
加入了线程操作以提高运算速度。
# 三、多种群遗传算法的实现
#main.py
from MyClass.myclass import *
from MyClass.GAFunction import *
IndividualQuantity=40
Parameters=5
frequence=450
MainPop=MainPOP(100,Parameters,frequence,0.05,0.7)
VicePop1=Population(IndividualQuantity ,Parameters,frequence,0.01,0.8)
VicePop2=Population(IndividualQuantity,Parameters,frequence,0.01,0.8)
import matplotlib.pyplot as plt
from numpy import sqrt,cos,sin,matrix,e,array,tan,log,floor
from numpy.linalg import eig
IterateTimes=100
MaxIndividualRecord=(Evolution(MainPop,VicePop1,VicePop2,IterateTimes))
print(MaxIndividualRecord)
################################################
parameters=MaxIndividualRecord[0:Parameters]
print(parameters)
#myclass.py
from MyClass.Function.Functions import *
class Population():
popupation=0
arguments=0
POP=[]
MaxIndividual=[]
IndexOfMaxPOP=0
VariationProbility=0.005
CrossoverProbility=0.7
Frequence=5
Ratio=2**16
def __init__(self,population,arguments,frequence,VariationProbility,CrossoverProbility):
self.population=population
self.arguments=arguments
self.Frequence=frequence
self.VariationProbility = VariationProbility
self.CrossoverProbility = CrossoverProbility
self.POP=InitPoP(population,arguments)
self.POP=CalcFitness(self.POP,self.population,self.arguments,self.Frequence,self.Ratio)
self.POP=GetFittingRate(self.POP,self.population,self.arguments)
def GetMaxIndividual(self):
return self.MaxIndividual
def UpdateMax(self):
self.MaxIndividual=self.POP.loc[(self.population)-1,:]
def Evolution(self):
self.POP=Variation(self.POP,self.population,self.arguments,self.VariationProbility)
self.POP=Generate(self.POP,self.population,self.arguments)
self.POP=CalcFitness(self.POP,self.population,self.arguments,self.Frequence,self.Ratio)
self.POP=GetFittingRate(self.POP,self.population,self.arguments)
self.UpdateMax()
class MainPOP(Population):
record=[]
def GetEmigate(self,newone1,newone2):
self.POP.loc[0,:]=newone1
self.POP.loc[1,:]=newone2
self.POP=self.POP.sort_values(by='fitness')
self.POP=GetFittingRate(self.POP,self.population,self.arguments)
self.POP.index=range(self.population)
def Evolution(self):
self.POP=Variation(self.POP,self.population,self.arguments,self.VariationProbility)
self.POP=Generate(self.POP,self.population,self.arguments)
self.POP=CalcFitness(self.POP,self.population,self.arguments,self.Frequence,self.Ratio)
self.POP=GetFittingRate(self.POP,self.population,self.arguments)
def UpdateMax(self):
last=self.population-1
self.MaxIndividual=self.POP.loc[last,:]
self.record.append(self.MaxIndividual['fitness'])
#GAFunction.py
import threading as th
def Evolution(MainPop,VicePop1,VicePop2,iteratetimes):
for i in range(iteratetimes):
ViceThread1=th.Thread(target=VicePop1.Evolution())
ViceThread2=th.Thread(target=VicePop2.Evolution())
ViceThread1.start()
ViceThread2.start()
ViceThread1.join()
ViceThread2.join()
MainPop.Evolution()
while(ViceThread1.is_alive() or ViceThread2.is_alive()):
pass
MainPop.GetEmigate(VicePop1.MaxIndividual,VicePop2.MaxIndividual)
MainPop.UpdateMax()
return MainPop.MaxIndividual
#Functions.py
import numpy as np
import pandas as pd
def InitPoP(population,arguments):
PoP=np.random.randint(0,2**16,[population,arguments])
PoP=pd.DataFrame(PoP).applymap(lambda x:bin(x)[2:])
PoP=PoP.applymap(lambda x:x.zfill(16))
PoP.insert(arguments,'fitness',np.nan)
PoP.insert(arguments+1,'probability',np.nan)
return PoP
def CalcFitness(PoP,population,arguments,Frequence,Ratio):
for index in range(population):
Temp=PoP.iloc[index,0:arguments]
Temp=Temp.apply(lambda x:int(x,2))
PoP.loc[index,'fitness']=inspiringfuction(Temp,Frequence,Ratio)
return PoP
def GetFittingRate(PoP,population,arguments):
PoP=PoP.sort_values(by='fitness')
PoP.loc[:,'probability'] = np.cumsum(PoP.loc[:,'fitness'])
PoP.index=range(population)
SumOfFitness=PoP.loc[population-1,'probability']
PoP.loc[:,'probability'] = PoP.loc[:,'probability']/SumOfFitness
return PoP
def Generate(PoP,population,arguments):
PoP2=PoP.copy()
for i in range(population):
rate=np.random.random()
temp=PoP[PoP['probability']>rate]
Individual1=temp.iloc[0,:]
rate=np.random.random()
Individual2=PoP[PoP['probability']>rate].iloc[0,:]
for chromosome in range(arguments):
a=Crossover(Individual1[chromosome],Individual2[chromosome])
PoP2.loc[i,chromosome]=a
return PoP2
def Crossover(chromosome1,chromosome2):
#设置为双点交叉
Point1=np.random.randint(1,14)
segment1=chromosome1[0:Point1]
segment2=chromosome2[Point1:16]
chromosome1=segment1+segment2
return chromosome1
def Variation(PoP,population,arguments,VariationRate):
for index in range(population):
for column in range(arguments):
TempS=PoP.loc[index,column]
TempSList=list(TempS)
Positions=np.random.randint(0,16,4)
[rate1,rate2,rate3,rate4]=np.random.rand(4)
for position in Positions:
if rate1<VariationRate:
if TempS[position]=='0':
TempSList[position]='1'
else:
TempSList[position]='0'
PoP.loc[index,column]=''.join(TempSList)
return PoP
from numpy import sqrt,cos,sin,matrix,e,array,tan,log,floor
from numpy.linalg import eig
def inspiringfuction(parameters,Frequence,Ratio):
#这个函数是适应度计算函数,需要根据情况自己写。函数名字取岔了,懒得改了了。
return result
总结
这篇博文第一次发出来的时候,其实写错了一部分代码,重新写了之后,所以也没更新。