多种群的遗传算法

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

遗传算法是和粒子群算法、蚁群算法等归于一类的自启发式算法。 通过给定方向的随机迭代过程对多维方程进行求解。 遗传算法的实现过程包括了对染色体的编码,迭代过程中的交叉变异,以及所谓的自然选择。

以上都是废话,能看到这篇文字的人怎么会不知道这个呢。


一、遗传算法通用基础

染色体的编码

通常采用二进制编码的方式。
将方程中一个未知数当做一个染色体,整个方程的解构成一个个体,则染色体上的二进制位就称之为基因。

示例:
假设一个参数的取值范围为 ( 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)×(220ba)+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

总结

这篇博文第一次发出来的时候,其实写错了一部分代码,重新写了之后,所以也没更新。

  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值