前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >遗传算法程序设计

遗传算法程序设计

作者头像
不断折腾
发布2019-09-23 11:31:21
8270
发布2019-09-23 11:31:21
举报

遗传算法程序思路

代码语言:javascript
复制
Begin
      t=0 % 遗传代数
      初始化P(t)
      计算P(t)的适应值
      while(不满足条件时)
          begin
          t=t+1
          从P(t-1)中选择P(t) %选择
          重组P(t)           %交叉和变异
          计算P(t)的适应值
          end

遗传算法参数设计原则

在单纯的遗传算法中,并不是总是收敛的,即使在单峰或者单调也是如此。这是因为种群的进化能力消失种群早熟。为避免这种现象,参数设计一般遵循以下原则:

(1)种群规模

当群体规模太小时,很明显会出现近亲交配,产生病态基因,生存和竞争的较小。而且太小的种群使得进化不能按照模式定理产生所预测的期望数量。种群规模太大时,结果难以收敛,浪费计算资源,结果稳健性下降,所以规模建议40-100。

(2)变异概率

概率太小时,种群多样性下降太快,容易导致有效基因丢失;变异概率太大时,具有竞争力的基因被破坏的概率又会有所增大。所以一般选择位于0.001-0.2。

(3)交配概率

交配是新种群最重要的手段。交配概率一般选择0.4-0.99

(4)进化代数

迭代次数小,算法不容易收敛;迭代次数大,算法早早收敛,后续过程除了浪费时间没有任何意义。进化代数建议100-500。

(5)种群初始化

初始化种群完全是随机的。在初始化种群的赋予之前,尽量进行一个大概的区间估计,以免偏差太大,增加算法的计算负担。

虽然遗传算法在matlab里面有工具箱,但是工具箱并不是万能的,很多情况下需要具体问题具体对待。另外,过度依赖于工具箱会使得无益于我们理解算法。现在我们用遗传算法来解决一个求最大值的问题。

求解函数最大值:

遗传算法程序设计

代码语言:javascript
复制
import numpy as np
import random
from math import *

bounds=[-2,2]             #一维变量的取值范围
precision=0.0001          #运算精度
bounds_begin ,bounds_end = bounds[0] ,bounds[1]

#计算满足所需精度需要至少多少染色体
BitLength=ceil(log((bounds_end-bounds_begin)/precision ,2))
popsize=50 #初始种群大小
Generationmax=200 #最大代数
pcrossover=0.9 #交配概率
pmutation=0.09 #变异概率
#产生初始种群
population = np.rint(np.random.rand(popsize,BitLength))

def func(x):
    
    """
        目标函数: y=200exp(-0.05x)*sin(x)  x∈[-2,2]
        参数:x 自变量
        返回值:y 因变量
    """

    y = 200*exp(-0.05*x)*sin(x)
    
    return y


def fitnessfun(population):
    
    """
        计算种群适应度和累计概率函数 fitnessfun()
        参数:population 种群的染色体
        返回值:[Fitvalue,cumsump] 适应度和累计概率
    """
    popsize=population.shape[0]
    Fitvalue=[]
    for i in range(0,popsize):
        x=0
        for j in range(BitLength-1,-1,-1):
            x += population[i,j]*2**j
        xx=bounds_begin + x*(bounds_end-bounds_begin)/(2**BitLength-1)
        y=func(x)+230 #保证适应度为正值
        Fitvalue.append(y)
        
    #计算选择概率
    fsum=sum(Fitvalue)
    Perpopulation=[item/fsum for item in Fitvalue]
        
        
    #计算累计概率
    cumsump=[Perpopulation[0]]
    for i in range(1,popsize):
        cumsump.append(cumsump[i-1]+Perpopulation[i])
        
    return [Fitvalue,cumsump]


def IfCroIfMut(mutorcro):
    """
        根据概率判断是否应该发生交叉或变异
        轮盘赌算法
    """
    test=np.zeros(100)
    l=round(100*mutorcro)
    for i in range(l):test[i]=1
    n=random.randint(0,99)
    
    return test[n]
    
    
    

def mutation(snew,pmutation):
    """
        变异函数,使染色体发生变异
        参数:snew,pmutation 种群染色体,变异概率
        返回值:snnew 变异后的染色体
    """
    BitLength=snew.shape[0]
    snnew=snew
    pmm=IfCroIfMut(pmutation)
    if pmm:
        chb=random.randint(0,BitLength-1)
        snnew[chb]=1-snew[chb]
    
    return snnew

def crossover(population,seln,pc):
    """
        交叉函数,使得两个染色体进行交叉
        参数:population,seln,pc 种群染色体,交叉个体,交叉概率
        返回值:交叉后的染色体
    """
    
    BitLength=population.shape[1]
    pcc=IfCroIfMut(pc)
    if pcc:
        chb=random.randint(0,BitLength-1)
    
        a=np.append(population[seln[0],0:chb],population[seln[1],chb:])
        b=np.append(population[seln[1],0:chb],population[seln[0],chb:])
    else:
        a=population[seln[0],:]
        b=population[seln[1],:]
    a1=a.reshape(1,a.shape[0])
    b1=b.reshape(1,b.shape[0])
    return np.append(a1,b1,axis=0)

def Selection(population,cumsump):
    """
        新种群选择操作
        
    """
    i_,j_=np.random.rand(1,2)[0,0],np.random.rand(1,2)[0,1]
    prand1=[item - i_ for item in cumsump]
    prand2=[item - j_ for item in cumsump]
    i,j = 0,0

    while prand1[i]<0 : i = i+1
    while prand2[j]<0 : j = j+1

    return [i,j]

            
        
    
#计算适应度,返回适应度Fitvalue和累计概率cumsump
[Fitvalue , cumsump] = fitnessfun(population)

Generation=1
ymax=[]
xmax=[]
ymean=[]
scnew=np.empty(shape=[0,16])
while Generation < Generationmax + 1:
    scnew=[]
    flag=1
    for j in range(0,popsize,2):
        #选择操作
        seln=Selection(population,cumsump)
        #交叉操作
        scro=crossover(population,seln,pcrossover)
        
        a=mutation(scro[0,:],pmutation)
        b=mutation(scro[1,:],pmutation)
        
        a1=a.reshape(1,a.shape[0])
        b1=b.reshape(1,b.shape[0])
        
        if flag == 1:
            flag -=1
            scnew=np.append(a1,b1,axis=0)
        else:
            scnew=np.append(scnew,a1,axis=0)
            scnew=np.append(scnew,b1,axis=0)
            
    population=scnew #产生了新的种群
    [Fitvalue,cumsup]=fitnessfun(population)
    fmax,index=np.max(Fitvalue),np.argmax(Fitvalue)
    fmean=np.mean(Fitvalue)
    ymax.append(fmax)
    ymean.append(fmean)
    
    x=0
    for j in range(BitLength-1,-1,-1):
        x += population[index,j]*2**j
    xx=bounds_begin + x*(bounds_end-bounds_begin)/(2**BitLength-1)
    xmax.append(xx)
    Generation += 1

print(func(xx))

以上就是今天的全部内容了,如果你喜欢的话,点个在看吧,你的支持是我最大的动力

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-09-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 python入门到放弃 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档