Python实现简单遗传算法

  本程序用于遗传算法求解函数最大值:f(x)=x+10sin(5x)+7cos(4x),0<=x<=9

  主要过程有初始化种群,基因编码,计算目标函数值,求解适应度函数,自然选择(采用轮盘赌算法),基因交换,基因突变。

  初始化种群:

pop = [[0, 1, 0 , 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] for i in range(popsize)]  # 初始化种群

  改进的初始化种群方式:

pop = [[0, 0, 0 , 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] for i in range(m)]  # 初始化种群
pop.extend([[0, 0, 1 , 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] for i in range(m)])
pop.extend([[0, 1, 0 , 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] for i in range(m)])
pop.extend([[0, 1, 1 , 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] for i in range(m)])
pop.extend([[1, 0, 0 , 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] for i in range(m)])
pop.extend([[1, 0, 1 , 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] for i in range(m)])
pop.extend([[1, 1, 0 , 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] for i in range(m)])
pop.extend([[1, 1, 1 , 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] for i in range(m)])

  基因编码:

def b2d(b): #将二进制转化为十进制
    y = 0
    for j in range(len(b)):
        y=y+b[j]*(math.pow(2,len(b)-j-1))
    y = y * 9 / ( 2**genelength- 1)
    return y
def b2t(pop):  # 将种群的二进制基因转为十进制数,位于[0,9]
    temp = []
    for i in range(len(pop)):
        t=b2d(pop[i])
        temp.append(t)
    return temp

  计算目标函数值:  

def objvaluefunc(pop):  # 计算目标函数值
    objvalue = []
    temp1 = b2t(pop)
    for i in range(len(temp1)):
        x = temp1[i]
        p=x+10*math.sin(5*x)+7*math.cos(4*x)
        objvalue.append(p)
    return objvalue

  求解适应度函数:

def fitvaluefunc(objvalue):  # 本例中适应函数即为所求函数本身,也可以重新更改定义,
    # 重新修订一下,当objvalue的值低于0时,设为0。
    fitvalue = []
    for i in range(len(objvalue)):
        if (objvalue[i] > 0):
            fitvalue.append(objvalue[i])
        else:
            fitvalue.append(0)
    return fitvalue

  自然选择:

def selection(pop, fitvalue):  # 自然选择,轮盘赌算法
    totalvalue = sumfitvalue(fitvalue)
    newfitvalue = []
    for i in range(len(fitvalue)):
        m=fitvalue[i]/totalvalue
        newfitvalue.append(m)
    cumsumfitvalue(newfitvalue)
    ms = []
    poplen = len(pop)
    for i in range(poplen):
        ms.append(random.random())
    ms.sort()
    msin = 0
    fitin = 0
    newpop = pop  while msin < poplen:
        if(ms[msin] < newfitvalue[fitin]):
            newpop[msin] = pop[fitin]
            msin = msin + 1
        else:
            fitin = fitin + 1
    pop = newpop

  基因交换:

def cross(pop, pgc):  # 基因交换
    for i in range(len(pop) - 1):
        if (random.random() < pgc):
            cnum = random.randint(0, len(pop[i]))
            t1 = []
            t2 = []
            t1.extend(pop[i][0:cnum])
            t1.extend(pop[i + 1][cnum:len(pop[i])])
            t2.extend(pop[i + 1][0:cnum])
            t2.extend(pop[i][cnum:len(pop[i])])
            pop[i] = t1
            pop[i + 1] = t2

  基因突变:

def muta(pop, pgm):  # 基因突变
    for i in range(len(pop)):
        if (random.random() < pgm):
            mnum = random.randint(0, len(pop[i]) - 1)
            if (pop[i][mnum] == 0):
                pop[i][mnum] = 1
            else:
                pop[1][mnum] = 0

  实验结果:

[24.850529722506916, 7.851576626408588, [1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]]

  完整代码实现:

  统一初始化:

https://github.com/xiyanjun/GeneticAlgorithm/blob/master/Genetic%20Algorithm.py

  分段初始化代码:

https://github.com/xiyanjun/GeneticAlgorithm/blob/master/Genetic%20Algorithm%EF%BC%88initchange).py

    原文作者:遗传算法
    原文地址: https://blog.csdn.net/tifosiboy/article/details/79374878
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞