8.3.2.3 使用遗传算法工具的参数和问题结构
利用函数gaoptimset创建一个参数结构体,在遗传算法工具中设置参数的值,然后在MATLAB工作窗中输出参数给结构体。如果想在遗传算法工具中输出缺省值,则导出的结构体的参数与由命令行得到的缺省结构体的参数一致。
options = gaoptimset
如果想从遗传算法工具输出一个问题结构体ga_problem,可用下面的语句调用函数ga
[x fval] = ga(ga_problem)
问题结构体包含:
? fitnessfcn — 适应度函数。 ? nvars — 问题的变量数。 ? options — 参数结构体。 8.3.2.4 复现运行结果
因为遗传算法是随机性方法,也就是说,产生随机机率,即每次运行遗传算法得到的结果都会略有不同。算法利用MATLAB随机数产生器函数rand和randn,在每一次迭代中,产生随机机率。每一次函数ga调用rand和randn,它们的状态都可能发生改变,以便下一次再被调用时,它们返回不同的随机数。这就是为什么每次运行后ga输出的结果会略有不同。
如果需要准确复现运行结果,可以在调用函数ga时包含rand和randn的当前状态。在又一次运行ga之前,重新设置这些值的状态。例如,要复现Rastrigin函数的ga的输出,可以利用下面的语句调用ga
[x fval reason output] = ga(@rastriginsfcn,2);
假设某次运行的返回结果为
x =
0.0027 -0.0052 fval =
0.0068
则随机函数rand和randn两者的状态被保存在output结构中。
output =
randstate: [35x1 double] randnstate: [2x1 double] generations: 100 funccount: 2000
message: [1x64 char]
然后,重新设置状态,输入
rand('state',output.randstate); randn('state',output.randnstate);
如果现在再次运行ga,就会得到相同的结果。
注意:如果没有必要复现运行结果,最好不要设置rand和randn的状态,以便能够得到遗传算法随机搜索的益处。
8.3.2.5 以前一次运行的最后种群重新调用函数ga
缺省情况下,每次运行ga时都生成一个初始种群。然而,可以将前一次运行得到的最后种群作为下一次运行的初始种群,这样做能够得到更好的结果。这可以利用下面语句实现:
[x,fval,reason,output,final_pop] = ga(@fitnessfcn,nvars);
最后一个输出变量final_pop返回的就是本次运行得到的最后种群。将final_pop再作为初始种群运行ga,语句为:
165
options = gaoptimset('InitialPop',final_pop);
[x,fval,reason,output,final_pop2] = ga(@fitnessfcn,nvars);
还可以将第二次运行ga得到的最后种群final_pop2作为第三次运行ga的初始种群。 8.3.2.6 从M文件运行ga
利用命令行可以运行遗传算法。使用M文件可以有不同的参数设置。例如,可以设置不同的交叉概率来运行遗传算法,观察、比较每次运行的结果。下面的代码是运行ga函数21次,变量options.CrossoverFraction从0到1,间隔为0.05,所记录的运行结果。
options = gaoptimset('Generations',300);
rand('state',71); % These two commands are only included to randn('state',59); % make the results reproducible. record=[ ]; for n=0 : .05 : 1
options = gaoptimset(options,'CrossoverFraction',n); [x fval]=ga(@rastriginsfcn,10,options); record = [record;fval]; end
可以利用下列语句,以不同概率画出fval值的曲线图形:
plot(0 : .05 : 1,record);
xlabel('Crossover Fraction'); ylabel('fval')
显示结果参见图8.34所示。
图8.34 从M文件运行遗传算法时fval值的曲线图形
从图形显示可以看出,options.CrossoverFraction的值为0.6~ 0.95时,可得到最好结果。 取每次运行得到的fval的平均值,就可以画出fval的光滑曲线,如图8.35所示。
166
图8.35 从M文件运行遗传算法时fval平均值的曲线图形
曲线最凹的部分对应options.CrossoverFraction的值为0.7~ 0.9。
8.3.3 遗传算法举例
为了得到遗传算法的最好结果,一般需要以不同的参数实验。通过不断实验,选择针对问题的最佳参数。有效参数的完整描述可参见 “8.4.1 遗传算法参数”一节。
本节介绍几种能够提高运算效果的参数改变方法,内容包括:种群多样性;适应度测量;选择;复制参数;变异与交叉;设置变异大小;设置交叉概率;相对于全局的局部最小值;使用混合函数;设置最大代数;向量化适应度函数。 8.3.3.1 种群的多样性
决定遗传算法的一个重要性能是种群的多样性。个体之间的距离越大,则多样性越高;反之,个体之间的距离越小,则多样性越低。由试验得到种群的适当多样性。如果多样性过高或者过低,遗传算法都可能运行不好。这里介绍如何设置种群的初始范围来控制种群的多样性,并介绍如何设置种群尺度。
? 举例——设置初始范围
遗传算法工具在默认情况下利用生成函数随机生成一个初始种群。使用者可以在“Population”的“Initial range”文本框中指定初始种群的向量范围。
注意:初始范围仅仅限制在初始种群中的点的范围。后续各代包含的点可以不在初始种群的范围之内。
如果知道问题解的大概范围,计算时就可以指定包含问题解的初始范围。但是,假设种群具有足够的多样性,遗传算法就可以找到不在初始范围的解。下面的例子显示初始范围对遗传算法性能的影响。这个例子利用Rastrigin函数,函数在原点取得最小值为0。运行之前在遗传算法工具中设置下列参数:
? 设置适应度函数为 @Rastriginsfcn。
167
? 设置“Number of variables”为 2。
? 在“Plots”窗格选择“Best fitness(最佳适应度)”。 ? 在“Plots”窗格选择“Range”。 ? 设置“Initial range”为 [1;1.1]。
然后,单击Start按钮。遗传算法返回最佳适应度值为2,其显示图形如图8.36所示。
图8.36 初始范围为[1; 1.1]时最佳适应度值和平均距离
图8.38上面为每代最佳适应度值变化图,下面为每代个体之间平均距离图,它可以很好地用来衡量种群的多样性。对于初始范围的设置,由于多样性太小,算法进展很小。
第二次,尝试设置“Initial range”为 [1; 100] ,运行算法,得到最佳适应度值大约为3.9,如图图8.37所示。
168