首先使用 open ga命令打开遗传算法源代码,依次顺序阅读
defaultopt结构体给出了默认设置的代码m文件名称,可以查看默认的选择函数selectionstochunif(随机均匀选择),默认的交叉函数crossoverscattered(散点随机)等等
文件的最后给出了调用的主体函数gaunc,进入这个函数后可以看到一个和种群数目有关的for循环
for pop = 1:length(totalPop),
在循环中找到主要的函数:stepGA,进入这个函数
到这里就比较清楚了,可以看到遗传算法各个组成部分的数目,精英数目nEliteKids,用于产生交叉的2 * nXoverKids,用于产生变异的nMutateKids
nEliteKids = options.EliteCount;
nXoverKids = round(options.CrossoverFraction * (size(thisPopulation,1) - nEliteKids));
nMutateKids = size(thisPopulation,1) - nEliteKids - nXoverKids;
nParents = 2 * nXoverKids + nMutateKids;
可以看到用于交叉的父代数目是2倍的nXoverKids
parents(1:(2 * nXoverKids))
也可以看到下一代的组成
nextPopulation = [ eliteKids ; xoverKids ; mutateKids ];
同时通过打断点可以具体看数值;通过之前预设的交叉函数代码等可以看具体交叉函数如何实现。比如可以看到随机均匀选择函数内部是按步长逐步前进,总共2 * nXoverKids步,这样交叉后的子代就是nXoverKids个子代。通过源代码就看出来了随机均匀和轮盘赌的区别,其实二者都是类似的,都存在一个和适应度成比例的轮盘/线,只不过一个是按步长均匀前进,一个是不断的摇轮盘。其核心思路都蕴含了被选择概率与适应度成比例的思想,都有可能多次选中同一父辈。
具体各个选择/交叉/突变的函数名称可以通过help ga,然后在input arguments的options选项中找到
比如双点交叉函数crossovertwopoint
PS:
一些debug的小tips
1. 遗传算法处理不了复数,复数无法比大小,因此ga的原理无非实现,尽管理论上正定矩阵二次型结果为实数,目标函数一定要加一个real函数把虚部去掉
2.ga为最小化函数,如果要求最大值,目标函数记得加负号
3. 如果优化后的结果和随机生成的变量实现的结果类似,基本需要怀疑优化的代码写错了,优化算法并未有效执行,原因包括收敛条件>、<写反,目标函数正负搞错、函数结果为复数等,其中收敛判断函数和目标函数值得重点检查
4. 使用命令optimtool可以打开优化工具,选择GA,fitness function输入@func,func是你定义的句柄函数,输入变量数目,输入上下界,在右边的options里面选best fitness,可以可视化观察随着种群迭代fitness的变化