[置顶] 亲,这就是遗传算法

本文试图通过几幅简明的图来介绍遗传算法。

背景

当一些问题不存在确定性的最优解法,或者说最优解法的施展时间长的1-B,那我们就得开始考虑点其他路子了。

比如说旅行商问题:

旅行商要去很多城市卖货,为了节省时间,它一个城市只去一次,最后还得返回原城市,因为他老婆不允许他离开太久。 
它怎么走比较合算?

城市的分布可能会像下面这样: 
这里写图片描述

旅行商会想就是把所有城市路线做个排列(一半),然后看看哪条路线最短就按哪条路线来。

好吧,如果旅行商要去的城市只有3-5个还好说,如果旅行商生意太好,可能要去几十个城市,那这个方法行不通。

为什么呢?

O(1)<O(logN)<O(N)<O(N2)<O(N!)

如果你熟悉时间复杂度,一定明白我在说什么,不信,自己试试34的阶乘算出来是个什么,亲,如果钱包有那么多钱那该多好。

好在,达尔文总结出了自然界的一个不知确否的道理,就是生物通过优胜劣汰的自然选择过程,来完成进化。

这个过程,看起来像是一堆随机不确定的微小变化中,让确定而显著的优势变化延续下来。

谁强,谁就更有话语权,资源就该属于这种强强的亲,而弱弱的主因为无法抗拒灾难和考验,最终就被淹没在进化的过程中。

遗传算法

既然生命都可以进化,现存的生物都是摸爬滚打、出生入死过来的,那么解决点计算问题还有什么复杂的。

于是,我们想着用可以量化的数学的方式去表达这种进化过程,然后让计算机来模拟自然选择和种群的演化,看看会有什么样的优质个体(解)出现。

也许不能得到一个最优的解,但旅行商恐怕不得不接受一个差不多的解: 
这里写图片描述

好吧,那我们来认识一下所谓的遗传算法(genetic algorithms)。

遗传算法,是一种进化算法,进化大家都明白。 
那么生命的变化在于基因的变化,什么是基因呢,我们不关注真正的生物基因,毕竟这里不是讨论生殖问题: 
这里写图片描述

如果把基因(gene)当做一个经过编码的元素,用一个数组或者列表来存储一组基因,这组基因就是染色体(chromosome)

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">    <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
     * 基因
     */</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Gene</span> {</span>
        <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
         * 编码
         */</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> value;
        <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
         * 等位基因(编码的值)
         */</span>
        Integer Allele;
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">interface</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">IChromosome</span> {</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Genes[];
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul>

好,有了这个表达基础,就可以很好的描述进化过程了。 
为了简化问题,突出本质,我们简化种群(population)的描述: 
这里写图片描述

这张图告诉我们

种群包含了若干个个体(染色体),一次又一次的进化,让种群规模变大,个体数目变多,优质个体也越来越多。

那么我们的解可能就蕴藏其中呢?

这幅图没有告诉我们关于进化的细节信息,显然,我们需要了解进化到底是什么东东。

这里写图片描述

你可能觉得我骗了你,但事实上,进化只有三维,就是选择(select)、交叉(crossover)和变异(mutate)。

让我们继续认识进化。

选择

选择就是选择,为什么选择,因为要优胜劣汰: 
这里写图片描述 
个体们在种群内部,不能闲着,都得上学打工养老婆,所以它们需要通过各种考试和考核。 
通过考核的加薪升职,否则就扫地出门。 
上面的图可以告诉我们,选择是针对种群的操作,选择的目的是为了确保下一代种群的质量更佳。

交叉

那么,个体之间又如何出现了差异?这要从个体的爸爸妈妈说起,现在不是都搞什么优质基因人工D孕吗,好吧,个体的差异就是因为繁殖而出现的。

人家都会说,哇,这孩子长得跟花儿似的! 
其实,可能是这孩子他妈妈很漂亮,优秀的基因得以传递。 
也有人会说,哦哟,这孩子眼睛跟他爹一样乌黑乌黑的,说明他爹可能是个码农,而且孩子不幸遗传了他爹的这些个…

下面将进入少儿不宜环节: 
这里写图片描述

至于激情的细节如何,本篇不打算讨论交叉的具体算法,但要说明它的意思:

交叉就是对两组父个体进行基因交叉,从而形成1个或者1组新的基因序列或染色体。 
交叉可以随机,但尽量要避免无意义的交叉。 
交叉的目的是在个体中增加大幅度的变化,并集成父母的优质基因。 
交叉是遗传算法最重要的一步操作。

变异

也许孩子是个富二代,也许孩子是个官二代,但有可能就是一个普通的孩子,令人遗憾的是,他比较喜欢他爸,他幼稚的心灵觉得他爸挺牛X的,所以他觉得码农挺牛X的。

不同的,这孩子喜欢汇编,囧~ 
这是他的个性,谁也阻止不了,人家会说,这孩子一点都不像他妈妈。 
那么这种个性,虽然不全是,但基因方面的原因可能是: 
这里写图片描述 
变异其实没有交叉重要,而且可能产生极坏的变异。 
但变异是一种对交叉的补充和完善,也是一种有风险的创新。

旅行商

现在我们回到旅行商问题,如果对城市进行编号,比如 123...N ,那么一条路线就是这样:

3,10,2,1,...,20,3  
每个城市的编号就是一个基因,城市的排列就是一个染色体(基因序列)。

那么,在经过若干次进化之后,优质染色体就可以被挑选出来,旅行商也就得到了一个接近最短的旅行路线: 
这里写图片描述

亲,这就是遗传算法。

遗传算法(Genetic Algorithm,GA)是一种启发式搜索算法,受到生物进化的启发。它通过模拟自然选择和遗传学中的杂交过程来寻找问题的最优解或近似最优解。遗传算法通常用于优化和搜索问题,例如函数优化、调度问题、机器学习等。 遗传算法包括以下几个步骤: 1. 初始化种群:生成一个包含一定数量个体的种群,每个个体代表问题的一个可能解。个体通常由染色体组成,染色体是一个有序的基因序列,对应于问题的参数或变量。 2. 评估适应度:计算每个个体的适应度值,表示该个体在当前问题环境下的优劣程度。适应度高的个体更有可能生存下来并传递其基因。 3. 选择(Selection):基于个体的适应度值,选择一定比例的个体作为父代和母代。常见的选择策略包括轮盘赌选择、锦标赛选择等。 4. 杂交(Crossover):将父代和母代的基因进行交叉,生成新的个体。交叉操作模拟生物的杂交过程,通过交换基因来产生新的基因组合。 5. 变异(Mutation):对生成的个体进行变异,即以一定概率随机改变某些基因的值。变异操作模拟生物的突变现象,增加种群的多样性,防止早熟收敛。 6. 替换(Replacement):将生成的新的个体替换旧的个体,更新当前种群。常见的替换策略包括最佳保留策略、最佳淘汰策略等。 7. 迭代(Iteration):重复执行选择、杂交、变异和替换操作,直到满足终止条件,如达到预定的迭代次数,或种群的适应度值不再显著提高。 遗传算法的优点包括: 不需要问题的数学模型,仅需要定义适应度函数; 可以处理多变量、非线性、不连续的问题; 可以找到全局最优解或近似最优解; 简单易行,实现原理清晰。 然而,遗传算法也存在一些缺点: 对于大规模问题,遗传算法的计算复杂度较高; 需要调参,如选择合适的种群大小、迭代次数、交叉概率、变异概率等; 结果具有一定的随机性,不同的运行结果可能不同。 因此,在应用遗传算法时,需要仔细评估问题的特点和约束条件,并进行适当的参数调优和结果分析。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值