这也是一个听起来很神奇,实现起来挺容易,内部机制很深邃的方法。和模拟退火算法一样,遗传算法也是求解NP难问题近似解的一种常见手段(当然,其应用远远不止解决这些问题。后面慢慢谈)。下面就以0-1背包问题为例(0-1背包问题用动态规划可以取到多项式时间复杂度的解,这里只是用这个举例),演示遗传算法该怎么玩。
-
0-1背包问题
简略的计算一下0-1背包问题,就是一个人有一个最多能装N公斤东西的包裹,然后有M个货物,每个货物都有不同的重量Mi和价值Wi,求怎样组合能在不超重的情况下,货物的价值最高。
例如包裹最多能装10Kg的东西,一共有5个货物其重量和价值分别为
重量 | 1 | 2 | 3 | 4 | 5 |
价值 | 5 | 3 | 6 | 2 | 9 |
-
算法基本步骤
(1)基因编码
针对0-1背包问题,编码很简单,就是1-5号货物是否放入包中,例如
01001就是将,2,5号放入包裹中。
(2)初始群体
随机生成群体里的一个个体。需要注意的是如果某一个个体所要放入的包中货物超过了上限,就随机放弃一个货物。
例如,随机产生的编码为01011,显然超重了,则随机将某个1置0,变成01010.
(3)适应度计算
对于0-1背包问题,适应度计算函数也很简单,就是看携带货物的价值。
(4)选择
根据进化论,具有高适应度的个体应该有更高的可能性活下来。选择算法有很多,比较常见的有轮盘赌法,或者简单粗暴的把适应度最高的几个选择下来。轮盘度法比较常用,效果也比较好。其公式为
也就是每个个体的存货概率Pi,等于它的适应性f(i)除以整个群体的总适应性。
(5)交叉(也就是繁衍后代)
本例中使用单点交叉。从群体中随机抽取两个个体,假设是01001和10110,随机产生交叉点假设是2.这样就把两个个体的前两个数互相交换。
就变成了10001和01110. 如果某一个个体所要放入的包中货物超过了上限,就随机删掉一个。
(6)突变(或者叫变异)
以一个较低的概率让一个个体进行变异,本例中就可以随产生一个变异点,然后这个点如果只1就置0,如果是0就置1.当然,不是每一个个体都需要突变。
接下来就是重复3-6步了,这个问题比较简单,大概几代十几代就可以找到最优解了。