美文网首页
遗传算法

遗传算法

作者: momo猪 | 来源:发表于2016-01-20 12:20 被阅读81次

    利用遗传算法计算x10+ex=100的解

    照例,import一些必要的库

    %matplotlib inline 
    import numpy as np
    import matplotlib.pyplot as plt
    import random
    

    不管怎么着,先把图画出来,看一下大概的取值区间

    x=np.linspace(0,2,100)
    def y(x):
        return np.abs(x**10+np.exp(x)-100)
    
    plt.plot(x,y(x))
    plt.show()
    

    为了方便编码(其实是我懒),决定取值区间为[0,2]。

    下面进行编码,采用32位的编码。也就是将[0,2]分割成2^32个小区段。

    比如[0,0,0,...,0]是0,[1,0,0,...0]是2^(-31)

    sons=np.zeros([100,32])
    values=np.zeros([100])
    results=np.zeros([100])
    sort_index=np.zeros([100])
    

    初始化函数,先随机生成100个点。

    def init():
        global sons
        for i in range(100):
            for j in range(32):
                sons[i][j]=random.randint(0,1)
    

    计算函数,将对应的编码转换成相应的数值

    def cmp(son):
        value=0
        temp=2**(-31)
        for i in son:
            value+=i*temp
            temp*=2
        return value
    

    更新数值的函数

    def update():
        global sons,values
        for i in range(100):
            values[i]=cmp(sons[i])
    

    遗传算法的核心函数,首先找出最接近解的10个值,然后利用这十个值的编码产生其余九十个值的编码。

    具体操作是,随机选取前十个中的两个,分别将他们的奇数编码和偶数编码组合生成一个新的编码。

    为了能够进化,也就是不局限于起初产生的编码,加入了突变这一因素。

    同时为了确保函数的收敛速度,针对不同的编码提供不同的突变。

    较接近解的编码,不允许出现大突变,其余允许大突变,防止陷入局部最优解。(在求最大值最小值的时候)

    def gen():
        global values,sort_index,results,sons
        results=np.abs(values**10+np.exp(values)-100)
        sort_index=np.argsort(results)
        for i in range(100):
            if i in sort_index[:10]:
                continue
            else:
                sam=random.sample(list(sort_index[:10]),2)
                sons[i][::2]=sons[sam[0]][::2]
                sons[i][1::2]=sons[sam[1]][1::2]
        for i in range(500):
            index=random.randint(0,99)
            if index in sort_index[0:3]:
                flag=random.randint(0,1)
                sons[index][flag]=1-sons[index][flag]
            elif index in sort_index[3:10]:
                flag=random.randint(0,7)
                sons[index][flag]=1-sons[index][flag]
            else:
                flag=random.randint(0,31)
                sons[index][flag]=1-sons[index][flag]   
        return(results[sort_index[0]],values[sort_index[0]])
        
    

    main函数

    def main():
        init()
        for i in range(1001):
            update()
            a,b=gen()
            if i%250==0:
                print(a,b)
                plt.plot(values,y(values),'.',x,y(x))
                plt.show()
    
    main()
    
    4.53816371162 1.58435669821
    
    0.000244704122139 1.57704925584
    
    0.000244420886716 1.57704925537
    
    0.000244420886716 1.57704925537
    
    2.94243349686e-07 1.57704885304
    

    可以看到,函数迅速收敛,最后的误差已经很小了,只有10^(-7)这个数量级。

    如果想要更精确的结果可以多迭代几次,可以很快地找出在32位精度下的最优解。

    请不要在意那些离散在外面的点,那是因为允许大的突变而产生的,在有多个极值的情况下,它们的作用就大了。

    相关文章

      网友评论

          本文标题:遗传算法

          本文链接:https://www.haomeiwen.com/subject/nkklkttx.html