一周前,我的遗传算法在数值优化上再次失败。在此之前我尝试过遗传算法结合局部搜索(随机爬山、SQP、模式搜索),由于INTJ型人格认为结合局部信息的进化不是好进化,转而尝试了其他的方法:小生境技术(niching),以适应度共享的手段来维持种群的多样性——在某些函数上取得了极好的效果,而参数的自适应控制却非常困难;多种群技术(MPGA)——由于我的迁徙算法错误使得我的程序本质上就是用不同的控制参数进行多次计算;正交技术(OGA),通过构造正交矩阵,使得在初始化种群和产生子代时能够均匀搜索整个解空间——在几个测试函数上都取得了不错的成果,但是后来我意识到这明明就是带启发式策略的网格搜索(grid
search),以及在一次离散事件仿真模拟的优化上得到了很糟糕的结果,加上计算开销大、运算速度慢,很快被我打入冷宫。再加上遗传算法在集合覆盖问题、TSP、Packing问题上令我蛋疼的表现,一度我对遗传算法的态度是“鸡肋,还不如用分支定界”,转而研究传统优化算法——序列二次规划(sequential
quadratic programming,SQP),在组合优化上也开始关注遗传算法结合回溯搜索。
由于在五月份的对仿真模拟的优化问题上,我使用的NPMEA算法在处理带约束的问题上让我印象深刻(之前我只用著名的G8函数做过测试),上周我怀着极大的信心采用它的单纯形交叉算子和自适应的高斯变异来做无约束优化(或者说是bound
constraint),但令人失望的是在某个五元函数上几乎连全局最优点的附近都搜索不到,增加了多种群和小生境运算速度又太慢,实在令人垂头丧气。
最后我抱着死马当活马医的态度打开gatool——我对这东西从来不屑一顾的,花里胡哨,不如自己coding来得快——结果太可怕了,一切参数采用默认设置,Schaffer函数以1的概率收敛到全局最优,颠覆三观!!我当时又是失落又是激动,心里只有两个字:“GADST,你为何这么叼?”一怒之下,把GADST的ga.m拆了,恍然大悟。
二、拆ga.m
step1:ga.m设置默认defaultopt
%-----------------------------e.g.---------------------------------
%代码取自ga.m 181th~202th rows
%默认编码类型为双精度编码
%默认生成初始种群向量下界为0上界为1
%默认种群大小为20
%默认使用gacreationuniform函数来生成均匀随机分布的初始种群
defaultopt = struct('PopulationType', 'doubleVector', ...
'PopInitRange', [0;1],
...
'PopulationSize', 20,
...
'CreationFcn',@gacreationuniform);
step2:ga.m作各种检查和判断
%-----------------------------e.g.---------------------------------
%代码取自ga.m 251th~277th rows
%检查第十个输入变量,若存在且是结构体,则为整数约束规划
if nargin == 10 &&
isstruct(intcon)
options = intcon;
intcon = [];
end
%检查输入的FitnessFcn是不是function handles或者inlines,若不是则返回error
if isempty(FitnessFcn) ||
~(isa(FitnessFcn,'inline') ||
isa(FitnessFcn,'function_handle'))
error(message('globaloptim:ga:needFunctionHandle'));
end
st