「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战」

前言

明天就除夕了,该过年了,所以明天就不更新博文了。那么本博文呢,是我无意中逛B站,然后发现这个UP主的一个关于遗传算法的视频的讲解(莫烦python),然后看了看他写的代码,然后对比了一下我的代码发现我的代码有不少可python怎么读以优化的点。同时也是做一个小记录,细说一下实现遗传算法的步骤,以及一些在python当中可以直接开挂的写法(我先前写的代码是直接使用list实现的在很多部分的代码实现都在造轮子,淦~),然后代码也是以那个UP主的代码进行讲解,说明,优化。

那么首先我们要了解什么是遗传算法

遗传算法

遗传算法其实是在用计算机模拟我们的物种进化。其实更加通俗的矩阵的乘法运算说法是筛选,这个就源码时代和我们袁隆平老爷爷种植水稻一样。有些个体发育良好,有些个体发育不好,那么我就先筛选出发育二进制八进制十进制十六进制转换好的,然后让他们去源码编程器繁衍后代,然后再筛选,最后得到高产水稻。其实也和我们社会一样,不努力就木有二进制女朋友就不能保留自己的基因,然后剩下的人就是那些优秀的人和富二代的基因,这就是现实呀。所以得好好学习,天天向python123上!算法的有穷性是指 那么回到主题,我们的遗传算法就是在模拟这一个过程,模拟一个物竞天择源码是什么意思的过程。

所以在我们的算法里面也是分为几大块

繁殖

首先我们的种群需要先繁殖。这样才能不断产生优良基于,那么对应我们的算法,假设我们需要求取

Y = np.sin(10 * x) * x + np.cos(2 * x) * x

的最大值(在一个范围内)那么我们的个体就是一组(X1)的解。好的个体就源码时代会被保留,不好的就会被pass,选择标准就是我们的函数 Y 。那么问题来了如何模拟这个过程?矩阵乘法我们都知道在繁殖后代的时候我们是通过DNA来保留我们的基因信息,在这个过程当中,父母的DNA交互,并且在这个过程当中会产生变异,这样一来,父母双方矩阵乘法的优秀基于会被保python123平台登录存,并且产生的变异有可能诞生更加优秀的后代。 所以接下来我们需算法的有穷性是指要模python是什么意思拟我们的DNA,进行交叉和变异。

交叉

这个交叉过程和我们的生物其实很像,当然我们在我们的计算机里面对于数字我们可以将其转化为二进制,当做我们的DNA

遗传算法&代码小讲解
交叉的方算法的五个特性式有很多,我们这边选择矩阵这一个,进行交叉。

变异

那这个在我们这里就更加简单了 我们只需要在交叉之后,再随机选择几个位置进行改变值就python是什么意思可以了。当然变异的概率是很小的,并且是随机的,这一点要注意。并且由于变异是随机的,所以不排除生成比原来还更加糟糕的个体。

选择

最后我们按照一定的规则去筛选这个些个体就可以了,然后淘汰原来的个体。那么在我们的计算机里Python面是使用了二进制转换器两个东西,首先我们要把原来二进制的玩意,给转化为我们原来的十进制然后带入我们的函数运算,然后二进制保存起来,之后再每一轮python下载统一筛选一下就好了。

代码编写

“开挂的API”

在开始编写我们的代码之前,我们必须要介绍几个API,这几个numpy的API简直就是开挂,同时也真是这几个API导致我们最难编写算法的部分变得相当简单。同时也正矩阵乘法是这几个API导致不少人读不懂代码,因为代码没有解释,甚至在源码里面的解释也不清楚。

numpy.random.randint()

这个API的用法没有我先前说的那么简单。它的用法相当巧妙。

**low: int

生成的数值最低要大于等于lo二进制八进制十进制十六进制转换w。 (hign = N算法分析的目的是one时,生成的数值要在[0, low)区间内) high: int (可选) 如果使用这个值,则生成的数值在[low, high)区间。 size: int or tuple of ints(可选) 输出随机数的尺寸,比如size = (m * n* k)则输出同规模即m * n* k个随机数。默认是None的,仅仅返回满足要求的单一随机数。 dtype: dtype(可选): 想要输出的格式。如int64、int等等 输出: out: int or ndarray of ints 返回一个随机数或随机数数组**

只写一个low参数

遗传算法&代码小讲解

两个 low源码时代 和 height

遗传算法&代码小讲解
遗传算法&代码小讲解

元素替换

这个其实主要是和numpy有关,这玩意支持布尔运算。

也就是这样。

遗传算法&代码小讲解
所以如果我们想要交换我们两个arry数组的元素的话可以直接这样干 这里注意一下维度就行了
遗传算法&代码小讲解
遗传算法&代码小讲解

这样一算法的有穷性是指来是不是直接完成了元素交换,也就是DNpython可以做什么工作A交叉。

np.random.choice

这个也是开挂的玩意,我们先前说了我们要筛选也就算法的空间复杂度是指是select。直接二进制转化为十进制使用这个函数,就帮助我们搞定了。

python怎么读先是最算法的五个特性基本的用法。

np.random.choice(5)#从[0, 5)中随机输出一个随机数
L = [1, 2, 3, 4, 5]#list列表
np.random.choice(L, 5)
>>>array([4, 3, 5, 3, 3])
L = [1, 2, 3, 4, 5]#list列表
np.random.choice(L, 5, replace=True)#可以看到有相同元素

权重 接下来就是我们的重点了

遗传算法&代码小讲解
所以接下来怎么选择元素一目了然算法是什么了吧。

当然我们这边其实选择的目的是去除不好的个体,那么其实就是选择好的个体。具体的看代码喽。

代码结构

好了废话了那么多,我们终于可以开始编矩阵相似码了。 这里其实也是分几块,就是我们前面的那几算法的特征块。

遗传算法&代码小讲解

python123整代码

里面都有注释就不在说明了

import numpy as np
import matplotlib.pyplot as plt
Population_Size = 100
Iteration_Number = 200
Cross_Rate = 0.8
Mutation_Rate = 0.003
Dna_Size = 10
X_Range=[0,5]
def F(x):
    '''
    目标函数,需要被优化的函数
    :param x:
    :return:
    '''
    return np.sin(10 * x) * x + np.cos(2 * x) * x
def CrossOver(Parent,PopSpace):
    '''
    交叉DNA,我们直接在种群里面选择一个交配
    然后就生出孩子了
    :param parent:
    :param PopSpace:
    :return:
    '''
    if(np.random.rand()) < Cross_Rate:
        cross_place = np.random.randint(0, 2, size=Dna_Size).astype(np.bool)
        cross_one = np.random.randint(0, Population_Size, size=1) #选择一位男/女士交配
        Parent[cross_place] = PopSpace[cross_one,cross_place]
    return Parent
def Mutate(Child):
    '''
    变异
    :param Child:
    :return:
    '''
    for point in range(Dna_Size):
        if np.random.rand() < Mutation_Rate:
            Child[point] = 1 if Child[point] == 0 else 0
    return Child
def TranslateDNA(PopSpace):
    '''
    把二进制转化为十进制方便计算
    :param PopSpace:
    :return:
    '''
    return PopSpace.dot(2 ** np.arange(Dna_Size)[::-1]) / float(2 ** Dna_Size - 1) * X_Range[1]
def Fitness(pred):
    '''
    这个其实是对我们得到的F(x)进行换算,其实就是选择的时候
    的概率,我们需要处理负数,因为概率不能为负数呀
    pred 这是一个二维矩阵
    :param pred:
    :return:
    '''
    return pred + 1e-3 - np.min(pred)
def Select(PopSpace,Fitness):
    '''
    选择
    :param PopSpace:
    :param Fitness:
    :return:
    '''
    '''
    这里注意的是,我们先按照权重去选择我们的优良个体,所以我们这里选择的时候允许重复的元素出现
    之后我们就可以去掉这些重复的元素,这样才能实现保留良种去除劣种。100--》70(假设有30个重复)
    如果不允许重复的话,那你相当于没有筛选
    '''
    Better_Ones = np.random.choice(np.arange(Population_Size), size=Population_Size, replace=True,
                           p=Fitness / Fitness.sum())
    # np.unique(Better_Ones) #这个是我后面加的
    return PopSpace[Better_Ones]
if __name__ == '__main__':
    PopSpace = np.random.randint(2, size=(Population_Size, Dna_Size))  # initialize the PopSpace DNA
    plt.ion() 
    x = np.linspace(X_Range, 200)
    # plt.plot(x, F(x))
    plt.xticks([0,10])
    plt.yticks([0,10])
    for _ in range(Iteration_Number):
        F_values = F(TranslateDNA(PopSpace))  
        # something about plotting
        if 'sca' in globals():
            sca.remove()
        sca = plt.scatter(TranslateDNA(PopSpace), F_values, s=200, lw=0, c='red', alpha=0.5)
        plt.pause(0.05)
        # GA part (evolution)
        fitness = Fitness(F_values)
        print("Most fitted DNA: ", PopSpace[np.argmax(fitness)])
        PopSpace = Select(PopSpace, fitness)
        PopSpace_copy = PopSpace.copy()
        for parent in PopSpace:
            child = CrossOver(parent, PopSpace_copy)
            child = Mutate(child)
            parent[:] = child
    plt.ioff()
    plt.show()

总结

遗传算法的优点:

  1. 与问题领域无关切快矩阵的秩速随机的搜索能力。
  2. 算法的空间复杂度是指索从群体出发,具有潜在的并行性,源码交易平台可以进行多个二进制怎么算个体的同时比较,robust.
  3. 搜索使用评价函数启发,过程简单
  4. 使用概率机制进行迭代,具有随机性。
  5. 具有可扩展性,容易与其他算法结合。

遗传算法的缺点:

  1. 遗传算法的编程实现比较二进制转换器复杂,首先需要对问题进行编码,找到最优解之后还需要对问题二进制转换器进行解码
  2. 另外三个算子的实现也有许多参数,如交叉率和变异率,并且这些参数的选择严重影响解的品质,而目前这些参数的选择大部分是依靠经验.
  3. 没有能算法的有穷性是指够及时利用网络的反馈信息,故算法的搜索速度比较慢,要得要较精确的解需要较多的训练时间。
  4. 算法对初始种群的选择有一矩阵的迹定的依赖性,能够结合一些启发算法进行改进。
  5. 算法的并行机制的潜在能力没有得到充分的利用,这也是当前遗传算法的一个研究热点方向。
在现在的工作中,遗传算法(1972年提出)已经不能很好的解决大规模计算量问题,它很容易陷入“早熟”。常用混合遗传算法,合作型协同进化算法等来替代,这些算法都是GA的衍生算法。

遗传算法具有良好的全局搜索能力,可以快速地将解空间中的全体解搜索出,而不会陷入局部最优解的快速下降陷阱;并且利用它的内在并行性,可以方便地进行分布式计算法的五个特性算,加快求解速度。但是遗传算法的局部搜索能力较差,导致单纯的遗二进制计算器传算法比较费时,在进化后期搜算法的五个特性索效率较低。源码编辑器手机版下载在实际应用中,遗传算法容易产生早熟收敛的问题源码资本。采用何种选择方法既要使优良个体得以保留,又要维持群体的多样性,一直是遗传算法中较难解决的问题。

说人话就是 首先为了保证全局搜索性,这个收敛慢(没那么快找到点),为了提二进制转换器高速度,让这个算法跑快一点就容易跑太快(某一时刻富二代太多了都矩阵游戏是富二代基因陷入局部二进制亡者列车最优)。也就是二进制转换器这个参数不好设置

例如

遗传算法&代码小讲解

你不注释,种群个数没算法的五个特性变,在一定程度上有更多的可能变异。 你注释了,个数减少可能降低。当然100个不明显。 你可二进制小数转十进制以试试,如果是100个个体结果是不一样的,但是相差不大,如果是10000个那结果都是一样的。 此外包括你的变异率,交换率都有影响。