kiayun手机版登录下载 10分钟搞懂遗传算法
来自于转载,其链接为:https://blog.csdn.net/u010425776/article/details/79155480 ,这句话的意思是,它不是原创内容。它原本出自该链接所指向的文章,是从那里被搬运过来的。这个链接所。

自然当中存在着一种神奇无比的力量,这般力量能够把优良的基因留存下来,进而进化生成更为强大、更适宜生存的基因。遗传算法是依据达尔文所提出的进化论,模拟了自然选择的过程,也就是物竞天择、适者生存,历经N代的遗传、变异、交叉以及复制,最终进化寻觅到问题的最优解决方案。遗传算法表面上看起来神奇非凡,然而其实现的思路却算是比较简单的了。本篇文章会先针对大家介绍遗传算法的基本思想,接着运用遗传算法去解决一个实际问题,最后给出遗传算法的代码实现以及解析。闲话不再多说了,现在赶紧开始吧~。
遗传算法
在开始之前,我们先来了解下遗传算法中的几个概念。
概念1:基因和染色体
在应用遗传算法里头,我们首先得出需要对有待解决的那个问题进行映射,使之成为一个数学问题,此即所谓的“数学建模”,如此一来这个问题那些解决方案里可行的一个就被称作是一条“染色体”。一个可行的解决方案通常是由多个元素构建起来的,这样的话这每一个元素就被叫做染色体上面的一个“基因”。
比如说,对于如下函数而言,
1,2,3
1,3,2
3,2,1
假设,均是这个函数的可行解,也就是代进去成立的那种可行解,那么,这些可行解在遗传算法里均被叫做染色体。
3x+4y+5z
这些可行解是由三个元素构成的,在遗传算法里,每个元素都被称作是组成染色体的一个基因 。
概念2:适应度函数
在自然界里头,好像有个上帝存在着,它可以挑出每一代里相对优良的个体喽,还会淘汰掉一些环境适应度欠佳的个人呢。那么在遗传算法当中,怎么去衡量染色体的好坏优劣呢?这是由适应度函数来达成的哟。适应度函数在遗传算法里充当着这个“上帝”的角色呀。
遗传算法于运行进程里会开展N次迭代,每一次进行迭代时,都会产生若干条染色体。适应度函数会针对本次迭代期间所生成的全部染色体给出一个分数,以此来评判这些染色体的适应度,接着把适应度较低的染色体予以淘汰,仅仅保留适应度较高的染色体,进而历经若干次迭代之后,染色体的质量将会越发优良 。
概念3:交叉
在下述遗传算法里,每经历一回迭代,便会产生N条染色体,于遗传算法范畴内,这般的每一回迭代,皆被称作一次“进化”,那么,每回进化新近生成的染色体究竟是经由怎样的方式而来的呢?——其答案即为“交叉”,你能够将其理解成交配 。
交叉过程要从长辈的染色体里找两条,一条来自爸爸,一条来自妈妈,接着把这两条染色体某个位置切断,再拼接起来,以此生成一条新染色体,这条新染色体既含有一定数量爸爸的基因,又含有一定数量妈妈的基因。
那么,怎样去从上一代染色体之中挑选出爸爸以及妈妈的基因呢?这并非是随机进行选择的,通常情况下是借助轮盘赌算法来达成的。
在每一回达成一次进化之后,都得去计算每一条染色体的适应度,而后运用如下公式来算每一条染色体的适应度概率。那么在开展交叉过程之际,就需要依据这个概率来挑选父母染色体。适应度相对较大的染色体被挑中的概率就越高。这正是遗传算法能留存优良基因的缘由所在。
染色体i被选中的可能性,等于染色体i的适应程度,除以全部染色体适应程度的总和,。
概念4:变异
交叉能够确保每一次进化都留下优良的基因,然而它仅仅是针对原有的结果集展开选择,基因依旧是那几个,只是交换了它们的组合顺序,这仅能保证历经 N 次进化后,计算结果更趋近于局部最优解,却永远无法达成全局最优解,为了解决这一问题,我们需要引入变异。
变异这件事,相对而言还是比较容易理解的。在进行交叉操作从而生成了一条全新的染色体之后,此时需要在这条新产生的染色体之上,随机地挑选若干个基因。紧接着对所挑选出来的这些基因的值,进行随机的修改。通过这样的做法,进而给现有的染色体引入了全新的基因。如此一来,便突破了当前搜索所存在的限制。这对于算法而言,更加有利于寻找到全局最优解。
概念5:复制
在每一次的进化里头,要想把上一代那些优良的染色体给保留下来,就得把上一代里面适应度最高的那几条染色体直接完完整整照旧原样不做任何改变地复制到下一代去。
假定每一回进化均要去生成N条染色体,那么在每一回进化期间,采用交叉方式是需要生成N-M条染色体的,而其余的M条染色体是经由复制上一代适应度最高的M条染色体而得来的。
遗传算法的流程
基于上面所提及的那些概念,想必遗传算法的大概原理你都已经知晓了,接下来我们要把这些概念相互连接起来,进而介绍遗传算法的执行流程 。
上面都是准备过程,下面正式进入“进化”过程。
在这个阶段,N条染色体的生成过程宣告结束!随后,针对这N条染色体,分别开展适应度的计算操作,以及对其下次被选中概率的计算工作。
这就是一次进化的过程开·云app体育登录入口kiayun手机版登录app游戏登录入口.手机端安装.cc,紧接着进行新一轮的进化。
究竟需要进化多少次?
历经多次演变才逐渐趋向越来越优的状态,所以从理论层面来说,进行演变的次数无疑是越多更有利,然则于实际落实环节当中,通常会在最终呈现所具备的精准程度以及实际操作开展当中的效率之间寻觅到一个能够达成平衡的点,一般来讲存在着两种具体的途径。
1. 限定进化次数
在某些实际运用当中,能够预先计算出进化的频率。举例来说,你借助诸多实验发觉:不论输入的数据怎样变动,算法于进化N回之后便能够获取到最优解,如此你就能够把进化的次数设定为N 。
然而,并非如此理想,确实不同输入致使获取最优解之际的迭代次数差异极大,此情下你能够思索选用第二种方式。
2. 限定允许范围
哪怕算法要达成全局最优解会历经特别多许多非常多次的进化,这对系统性能有着极大影响,那我们能够于算法的精确度跟系统效率之间寻觅一个平衡点,我们能够预先设定一个能够接纳的结果范围,当算法开展X次进化后,一旦发觉当前结果处于误差范围之中,那就终止算法。
不过呢,这种方式存在着一个缺点,在某些情形下,或许稍微进化几次便进入了误差允许范围,然而,在另一些情形下,却需要进化极多极多极多极多次才能够进入误差允许范围。这种不确定性致使算法的执行效率是不可控的。
如此一来,则究竟要挑选哪一种方式用以把控算法的迭代次数呢,这是需要你依据具体的业务场景去合理地进行挑选的。在此处没办法给出普遍适用的方式,需要你自身在真实的实践当中找寻到答案。
采用遗传算法解决负载均衡调度问题
算法都是用以处理实际问题的,就此打住,我觉得你对于遗传算法已然有了一番全盘的认知,接下来我们就要运用遗传算法去解决一个实际问题,也就是负载均衡调度问题。
假设存在N个任务,这些任务需交由负载均衡器分配给M个服务器节点来处理,每个任务都有其特定的任务长度,每台服务器节点也就是下面所说的“节点”,其处理速度是已知的,那么请给出一种任务分配方式,凭借此方式从而能够让所有任务的总处理时间达到最短 。
数学建模
把这个问题拿到手后,我们首要的是,得把这个实际存在的问题,映射成为遗传算法的数学模型 。
任务长度矩阵(简称:任务矩阵)
我们将所有任务的任务长度用矩阵tasks表示,如:
Tasks={2,4,6,8}
那么,tasks
中的i表示任务的编号,而tasks
表示任务i的任务长度。
节点处理速度矩阵(简称:节点矩阵)
我们将所有服务器节点的处理速度用矩阵nodes表示,如:
Nodes={2,1}
那么,nodes
中的j表示节点的编号,而nodes
表示节点j的处理速度。
任务处理时间矩阵
当用来表示所有任务分配给所有节点的任务处理时间的矩阵timeMatrix确定下来之后,那么任务矩阵Tasks和节点矩阵Nodes才可以确定,矩阵timeMatrix是一个二维数组 。
1 2
2 4
3 6
4 8
timeMatrix
它用来体现以把任务i分发给节点j去处理时所需耗费的时间,而这个时间是借助如下的公式来进行计算的:
timeMatrix
= tasks
/nodes
染色体
上面的内容让我们明白,每一次进行进化的时候,都会出现N数量的染色体,其中的每一条染色体,都是当下问题的一个能够行得通的解决办法,这个可行的解决办法是由多个元素所共同组构而成的,而其中的每一个元素,都被称作是染色体的一个基因。接下来,我们会采用一个染色体矩阵,去记录算法在每一次进化进程当中的可行解。
一条染色体的构成如下:
chromosome={1,2,3,4}
一条染色体,它等同于一个一位数组,这个一位数组呢,其下标所起到的作用是用来表示任务的编号,而数组的值所对应表示的乃是节点的编号。那么chromosome。
=j的含义就是:将任务i分配给了节点j。
在前述的例子当中,任务集合被设定为Tasks={2,4,6,8},节点集合被确定为Nodes={2,1},如此一来,染色体chromosome={3,2,1,0}所具备的含义便是:
适应度矩阵
上文表明,于遗传算法里充当“上帝”角色的乃是适应度函数,它会对每一条染色体的适应度予以评判,且保留适应度高的染色体,淘汰适应度差的染色体。如此一来,在算法实现之际,我们需要一个适应度矩阵,用以记录当前N条染色体的适应度,情况如下所示:
适应能力等于,零点六,二,三点二,一点八 。
adaptability数组的下标,用来表示染色体的编号kiayun手机版登录打开即玩v1011.速装上线体验.中国,然而adaptability ,。
则表示编号为i的染色体的适应度。
于负载均衡调度此实例当中,我们把N个任务执行的总时长充当适应度评判的标准。当所有任务都分配完毕后,要是总时长比较长,那么适应度就越糟糕;而总时长越短,如此适应度就越高。
选择概率矩阵
依上文能够知道,于每一回进化进程当中,都得依据适应度矩阵去计算每一条染色体在紧接着的下一次进化里被挑选的概率,此矩阵如下所呈现:
选择概率等于,零点一,逗号,零点四,逗号,零点二,逗号,零点三句号。
矩阵的下标用来表示染色体的编号,矩阵当中的值代表该染色体对应的选择概率,其计算公式如下:
selectionProbability
= adaptability
/ 适应度之和
遗传算法的实现
经过上述所有知识点的铺垫达成之后,紧接着我们便能够着手弄代码了,坚信空谈无济于事,给你展现代码才是关键!
/\*\* \* 关于用遗传算法来进行相关操作的内容 \* @param 用于表示迭代次数的iteratorNum \* @param 指明染色体数量的chromosomeNum \*/ function gaSearch(iteratorNum, chromosomeNum) { // 针对第一代染色体进行初始化动作 var chromosomeMatrix = createGeneration(); // 开启迭代繁衍的进程 for (var itIndex = 1; itIndex (由于示例本身不完整,这里暂且按照要求拆分到这里)。- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
代码一来,一切都清晰了,似乎不需要过多的解释了。
那上边呈现的是遗传算法最为主要的框架,其当中的某些具体细节被封装于一个个子函数之内。在对遗传算法的原理获得理解之后,我觉得代码无需我进行过多的阐释了吧~完整的代码处于我的Github之上,欢迎给予Star 。
结果展示
上面提到的算法总体进行了100回进化,每一回进化都能够产生100条染色体。图里的横坐标所代表的是进化的次数,然而纵坐标所代表的是任务执行所需要的时间。
从那个图当中,我们能够看到,那时候是处于进化大概20次的情况,算法逐渐地朝着最优解的方向进行会聚 。
写在最后
完整的代码在我的Github上,欢迎下载,欢迎Star!
https://github.com/bz51/GeneticAlgorithm
代码中包含三个文件: