使用遗传算法求解函数最大值
题目
使用遗传算法求解函数
在 及y 的最大值。
解答
算法
使用遗传算法进行求解,篇末所附源代码中带有算法的详细注释。算法中涉及不同的参数,参数的取值需要根据实际情况进行设定,下面运行时将给出不同参数的结果对比。
定义整体算法的结束条件为,当种群进化次数达到maxGeneration时停止,此时种群中的最优解即作为算法的最终输出。
设种群规模为N,首先是随机产生N个个体,实验中定义了类型Chromosome表示一个个体,并且在默认构造函数中即进行了随机的操作。
然后程序进行若干次的迭代,在每次迭代过程中,进行选择、交叉及变异三个操作。 一 选择操作
首先计算当前每个个体的适应度函数值,这里的适应度函数即为所要求的优化函数,然后归一化求得每个个体选中的概率,然后用轮盘赌的方法以允许重复的方式选择选择N个个体,即为选择之后的群体。
但实验时发现结果不好,经过仔细研究之后发现,这里在x、y取某些值的时候,目标函数计算出来的适应值可能会出现负值,这时如果按照把每个个体的适应值除以适应值的总和的进行归一化的话会出现问题,因为个体可能出现负值,总和也可能出现负值,如果归一化的时候除以了一个负值,选择时就会选择一些不良的个体,对实验结果造成影响。对于这个问题,我把适应度函数定为目标函数的函数值加一个正数,保证得到的适应值为正数,然后再进行一般的归一化和选择的操作。实验结果表明,之前的实验结果很不稳定,修正后的结果比较稳定,趋于最大值。
二 交叉操作
首先是根据交叉概率probCross选择要交叉的个体进行交叉。
这里根据交叉参数crossnum进行多点交叉,首先随机生成交叉点位置,允许交叉点重合,两个重合的交叉点效果互相抵消,相当于没有交叉点,然后根据交叉点进行交叉操作,得到新的个体。
三 变异操作
首先是根据变异概率probMutation选择要变异的个体。
变异时先随机生成变异的位置,然后把改位的01值翻转。
经过一定的进化之后得到最终种群,从中选择最优的个体即可得到最终的结果。
运行结果
借助matlab软件,我们可以知道该函数在该定义域下的图像为:
以下设置不同的参数值进行对比试验:
表1 不同参数的对比实验
1 2 3 4 5 6 N 10 50 200 200 200 300 len 10 10 20 30 30 40 crossnum maxGeneration probCross probMutate 4 4 4 4 5 4 1000 5000 5000 10000 10000 100000 0.85 0.85 0.85 0.85 0.8 0.85
0.15 0.15 0.15 0.15 0.2 0.15 实验一 实验二 2.61433204 2.74697117 2.87176512 2.88383150 2.89202745 2.89307359 2.89440656 2.88852551 2.88806821 2.89165073 2.89363739 2.89445359 以上我们主要对种群规模N,个体染色体长度len,迭代次数maxGeneration进行比较。可以看出,随着种群规模的增大,染色体长度的增长,迭代次数的增加,算法得到的结果越来越精确。当参数规模达到一定程度时,再增加参数的值会明显地增加程序运行时间,但却不一定能明显改善解的质量,反而可能因为一些随机因数而产生质量更差的解,如第6组实验一所示。
同时也大概比较了一下多点交叉的交叉点个数crossnum,交叉概率probCross,变异概率probMutate等参数,由于参数太多,这里没有一一进行控制变量的比较。大致估算可知,交叉概率及交叉点的个数影响交叉操作产生新个体的质量,过多的交叉及变化过大的交叉可能会产生不好的结果,而过多的变异也应该会造成算法的不稳定。
下面给出以上几个实验结果的实验截图,其中到现在为止结果最好的一个为:
其余若干个为:
算法改进
以上实验得到的最好结果仍然是差强人意,这里对算法做一个小的优化,即添加防止种群退化的操作。记录当前位置所得到的最优值及对应的个体,每次更新种群之后,计算新种群的最优值,如果最优值变差了,则把之前较优的个体替换进新种群,防止种群退化;否则