本次推文为大家讲解免疫算法,隐约中记得一位小伙伴后台问我能否推出这样一篇推文,小编的参考资料很简单,依然是这本宝典。小编更新的推文都是一些最最基本的算法,解决的问题也是最最基本的问题。小编觉得算法的思想很重要,掌握住思想,无论问题怎么变,你都会自己定制出一份属于自己的代码。
免疫算法其实和基本的遗传算法大同小异,具体的差异体现在对个体的评价、选择以及产生的方式不同。
下面以书中的问题为例,来讲解免疫算法。
下面来讲一下如何用免疫算法求解上述问题:
一.解的编码形式
无论用免疫算法,还是用其他算法,第一件事是如何准确地用数字的形式表达问题中的解。这个问题中假设有31个需求点,对应数学模型中n=31,其中1,2,...,31代表需求点的序号。从中选出6个作为配送中心(注意这6个点是从这31个需求点选出来的),对应数学模型中p=6,则[11 7 21 26 5 19]代表一个可行解,他表示11,7,21,26,5,19被选为配送中心。
免疫算法中有“抗体”和“抗原”这两个术语,小编觉得不太习惯,决定不讲这来个术语,而且大家一看代码就会知道免疫算法和普通的遗传算法真的是大同小异。
二.解的体评价方法
免疫算法通过期望繁殖率的大小来产生后代种群,期望繁殖率越大,差生后代的可能性越大。这里先给出期望繁殖率的计算公式
书中染色体的适应度值计算公式如下:(但小编觉得不太对,后面再给出小编认为的公式)
其中代表染色体v适应度值,代表染色体v的浓度。我们先给出的计算公式:
第一项表示目标函数值,第二项表示对违反距离约束的惩罚,代码中C取的是4,假设存在5个违反距离约束的需求点(ps.违反距离约束就意味着不满足数学模型中的公式6,代码中的s取的是3000),则对每个违反距离约束的需求点而言,都等于0,最终等于-5。可以看出违反距离约束的需求点越少,目标函数值越小,则适应度值越大。
下面先给出一个小的定义,两个染色体之间的相似程度,顾名思义,比如说有两个染色体:[1 8 19 13 28 24] 和[7 3 19 24 301],这两个染色体有3个相同的基因,则这两个染色体的相似程度为3/6=0.5。因此两个染色体之间的相似程度的计算公式如下:
为染色体v与染色体s中相同基因的个数,L为染色体长度。
最后我们给出染色体v的浓度的计算公式:
代码中T设为0.7。其实染色体v的浓度就代表染色体v与种群中其他染色体的相似程度。
因此我们就得出了第一个公式:
小编认为这个计算公式应该是:
为什么是减第二项呢,小编认为书中既然说到个体适应值越高,期望繁殖概率越大;个体浓度越大,则期望繁殖概率越小(所以应该减第二项)。这样即鼓励了适应度值高的个体,同时抑制了浓度高的个体,从而确保种群的多样性。
三.种群组成
免疫算法的种群包括两部分:记忆库和抗体库,这两个名词不用记,主要是理解这两部分都是什么就OK了。举个例子,记忆库中有10个染色体,抗体库中有50个染色体,则种群的总数目为60。代码在执行过程中采用精英保留策略(假设保留精英染色体的数目为3),即每次更新记忆库和抗体库时都会先将这60个染色体中适应度值最大的3个染色体进行保留。然后无论是记忆库还是抗体库,其余的染色体都按照期望繁殖概率由大到小排序,依次存入记忆库和抗体库。这里大家可能会发现,抗体库中的前10个染色体与记忆库中的10个染色体完全一样,没错,你答对了。
四.免疫操作
注意:免疫操作这部分仅仅使用的是抗体库中的染色体,而不使用记忆库中的染色体。
这部分常规操作,小伙伴们可以参考遗传算法求解车间调度问题(附MATLAB代码),再重新复习一下。具体的操作在这里就一带而过了。
(1)选择:按照轮盘赌选择机制进行选择操作,个体被选择的概率即为期望繁殖概率P。
(2)交叉:单点交叉。
(3)变异:随机选择变异位进行变异。
五.效果展示
初始需求点分布图:
优化之后如下图所示: