人工智能应用-实验1-遗传算法求函数最大值实验

🧡🧡实验内容🧡🧡

用遗传算法求解下列函数的最大值,设定求解精度到15位小数


函数1

f ( x , y ) = 6.452 ( x + 0.125 y ) ( cos ⁡ ( x ) − cos ⁡ ( 2 y ) ) 2 0.8 + ( x − 4.2 ) 2 + 2 ( y − 7 ) 2 + 3.226 y f(x, y) = \frac{6.452(x + 0.125y)(\cos(x) - \cos(2y))^2}{\sqrt{0.8 + (x - 4.2)^2 + 2(y - 7)^2}} + 3.226y f(x,y)=0.8+(x4.2)2+2(y7)2 6.452(x+0.125y)(cos(x)cos(2y))2+3.226y
x ∈ [ 0 , 10 ] ,   y ∈ [ 0 , 10 ] x \in [0, 10], \, y \in [0, 10] x[0,10],y[0,10]

函数2

f ( x 1 , x 2 ) = 20 + x 1 2 + x 2 2 − 10 ( cos ⁡ ( 2 π x 1 ) + cos ⁡ ( 2 π x 2 ) ) f(x_1, x_2) = 20 + x_1^2 + x_2^2 - 10(\cos(2\pi x_1) + \cos(2\pi x_2)) f(x1,x2)=20+x12+x2210(cos(2πx1)+cos(2πx2))


🧡🧡源码🧡🧡

function f = lab1_fun(x)
    x1=x(1);
    x2=x(2);
    % ga默认求最小值,因此加个负号,表示求最大值
    f = - ( 6.452*( (x1+0.125*x2) * (cos(x1)-cos(2*x2)) )^2 / ((0.8+(x1-4.2)^2+2*(x2-7)^2)^0.5) + 3.226*x2 );
end
function f = lab1_fun2(x)
    x1=x(1);
    x2=x(2);
    f = 20 + x1^2 + x2^2 - 10 * ( cos(2*pi*x1) + cos(2*pi*x2) )
end
clear all;
close all;
clc;

fitness = @(x) lab1_fun(x)
fitness2 = @(x) lab1_fun2(x)

%% 画图
% 定义参数范围
x1 = linspace(-10, 10, 200);
x2 = linspace(-10, 10, 200);
[X1, X2] = meshgrid(x1, x2);

% 计算函数值
F = zeros(size(X1));
for i = 1:size(X1, 1)
    for j = 1:size(X1, 2)
        F(i, j) = fitness2([X1(i, j), X2(i, j)]);
    end
end

% 绘制函数图像
figure;
surf(X1, X2, F);
xlabel('x1');
ylabel('x2');
zlabel('f(x1,x2)');

%% 开始计时
tic

% 定义变量范围和精度
lb = [-10, -10];
ub = [10, 10];


% 配置参数
options = optimoptions(@ga,'MaxGenerations', 100, 'FunctionTolerance', 1e-15); % 最大迭代数,终止时的变化精度

options.PopulationType='doubleVector'; % 编码方式
options.PopulationSize=100; % 种群规模
options.InitialPopulationRange=[lb(1);ub(1)] % 初始种群的个体取值范围

options.FitnessScalingFcn = @fitscalingrank; % 个体选择概率分配策略:排序选择
% options.FitnessScalingFcn = @fitscalingprop; % 个体选择概率分配策略:比例选择

options.SelectionFcn = @selectionroulette; % 个体选择方法:轮盘赌
% options.SelectionFcn = @selectiontournament; % 个体选择方法:锦标赛

options.CrossoverFcn = @crossovertwopoint; % 交叉方式 单点
% options.CrossoverFcn = @crossovertwopoint; % 交叉方式 双点

options.EliteCount = 5; % 精英个体数量 5
options.CrossoverFraction = 1 ; % 交叉概率


% options.MutationFraction = 0.1 % 变异概率
options.MutationFcn = @mutationuniform % 变异方式 均匀变异
% options.MutationFcn = @mutationgaussian % 变异方式 高斯变异

options.TimeLimit = 20  % 最大运行时间限制 (秒)
options.FitnessLimit = -1000 % 最小适应度限制
options.PlotFcn={ @gaplotbestf,  @gaplotdistance} % 画出每一代最佳适应度值的变化曲线 、 最佳个体、 各个体平均距离
% @gaplotbestindiv,

% 使用遗传算法进行优化
% rng default % 设置随机数种子以确保结果可重复
[x, fval] = ga(fitness2, 2, [], [], [], [], lb, ub, [], options);
disp(['最优解 x = ', num2str(x, '%.15f  ')]);
disp(['最优值 fval = ', num2str(fval, '%.15f')]);

% 结束计时并输出运行时间
elapsedTime = toc;
disp(['程序运行时间:', num2str(elapsedTime), ' 秒']);

🧡🧡结果分析🧡🧡

函数1

对于函数
在这里插入图片描述
先画出大概的函数图像,可以看到,最优适应度值接近-3.462左右,此时x和y分别取1.809和0.1005左右。
在这里插入图片描述
在这里插入图片描述

采用matlab的gaoptimize工具箱,对遗传算法相关参数设置如下
在这里插入图片描述
求得结果如下:
在这里插入图片描述
在这里插入图片描述
最优适应度结果为-530,离理想结果-3.4差别很多,考虑可能是因为初始种群的个体取值范围取了[0,10],导致它获得的个体并不理想(x,y取了6.5、7.8,与最优x和y差别也很大)。

调整种群规模为5,20,100,初始种群的个体取值范围为[0,1],计算最佳适应度、平均适应度、最佳个体的x和y如下表:
在这里插入图片描述
种群规模为5、20、100时:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
由以上结果分析可知:
随着种群规模增大,每一代最优fitness越来越平稳,且越来越接近理想最优值

  • 种群规模较小时:可搜索的空间比较小,从而降低了算法的全局搜索能力,并且很难接近理想最优fitness。
  • 种群规模较大时:有着更高的多样性(各个体的差异程度),减少早熟收敛的风险,如上结果中,种群规模100相比种群规模20,20容易陷入早熟,100随着迭代次数增加,可能会探索出新的更优局部值。

这里我继续保持种群规模为100,初始种群的个体取值范围为[0,1],交叉概率为0.8,通过组合不同的选择交叉变异策略,得到结果如下:
在这里插入图片描述
分析结果

  • 高斯变异通过对个体的基因进行随机扰动来变异,能保证变异过程中基因的连续性,但是在此问题中,由于函数值对于x的轻微变化容易收到较大幅度的改变,因此导致结果大幅差异。并且高斯变异容易限制空间的探索能力,导致陷入局部最优。而均匀变异具有跳出局部最优的能力,适合全局搜索。
  • 两点交叉相对单点交叉而言,能够更充分地交换父代个体的信息,从而增加了搜索空间,有助于更快地产生多样性,从实验结果也能看出:两点交叉最优fitness=-3.864优于单点交叉-3.909。
  • 实验结果还表明:改变个体选择方式为竞标赛选择,保持了种群的多样性,更有利于接近最优fitness。轮盘赌能够有效地保留较优的个体,但同时也容易导致适应度较低的个体被忽视。

函数2

在这里插入图片描述

它是一个无约束函数,先姑且取x1、x2范围为[-10,10],观察函数图像:
在这里插入图片描述
一眼望去,存在许多局部最小值,增大遗传算法的搜索难度。
凭直觉和观察可知,最优个体应接近(0,0)位置,最优适应度应接近0
在这里插入图片描述

设置基本参数如下:
在这里插入图片描述
结果如下:最优适应度0.863852724882126,最佳个体x = 0.043852278839774 ,0.049629792703598
在这里插入图片描述
在这里插入图片描述

设置不同的初始范围:
1到1.1
在这里插入图片描述
在这里插入图片描述
1到2
在这里插入图片描述
在这里插入图片描述
1到100
在这里插入图片描述
在这里插入图片描述
由以上结果分析可知:

  • 如果初始范围较小,种群可能无法覆盖整个搜索空间,导致算法陷入局部最优解。例如[1,1.1],结果直接选取了1作为最优个体。
  • 如果初始范围较大,则种群中的许多个体可能是无效的,浪费计算资源。

将初始范围调回[-10,10],设置不同的交叉概率0、0.8、1,观察每一代最佳适应度值和各个体平均距离图
交叉概率=0:
在这里插入图片描述
在这里插入图片描述
交叉概率=0.8:
在这里插入图片描述
在这里插入图片描述
交叉概率=1:
在这里插入图片描述在这里插入图片描述
由以上结果分析可知:
交叉概率为0.8的最佳适应度最小,最接近最优值0

  • 当交叉概率为0时,种群中的个体只会通过变异操作产生新的个体,而没有交叉操作,这可能导致种群缺乏多样性,难以进行有效的信息交流和组合。这会导致种群收敛速度较慢,同时容易陷入局部最优解(如上交叉概率为0的分析图中,迭代了100代仍然没有收敛现象)。
  • 当交叉概率为1时,种群中的个体只会通过交叉操作产生新的个体,而没有变异操作,这可能导致种群缺乏多样性,在算法的早期阶段,由于种群缺乏多样性,可能会导致收敛速度较慢,甚至陷入早熟收敛(如上交叉概率为1图中,在第10代时就已经收敛)。
  • 当交叉概率为0.8时,交叉操作有助于组合不同个体的优点,产生新的解,而变异操作有助于保持种群的多样性,避免早熟收敛,并且有机会引入新的优良个体。这样能够更好地维持种群的多样性,加快收敛速度,并且更有可能找到全局最优解。

🧡🧡实验总结🧡🧡

总结遗传算法的特点,并说明适应度函数在遗传算法中的作用
通过适应度函数计算得出个体的适应度,进而影响个体被选中的概率,从而影响到最优个体的取值,也即将解空间和适应度值建立了关联,指导着遗传算法的搜索方向。因此,总的来说,适应度函数旨在量化每个个体的优劣程度,使得适应度较高的个体在遗传操作中被更有可能地选择、交叉和变异,正因如此,才使得遗传算法能够对问题空间中优秀解的搜索和收敛。

心得
本次实验,进一步丰富了我对遗传算法的理论知识的理解和实际的实现过程。

  • 遗传算法的原理:了解了遗传算法的基本流程,以及各个流程中不同的策略的差异。(轮盘赌、锦标赛、实数编码、二进制编码、单点交叉、多点交叉、均匀变异、高斯变异等等)
  • 对matlab的遗传工具箱使用更加清晰熟悉,之前打数学建模时,也有自学这些启发式算法,但更多的是直接从可实现的代码方面进行直接使用,面对新的问题,可能代码要修改好一阵子,本次实验中,通过直接使用matlab的优化工具箱,大大减少了编写代码的时间。
  • 另外,感受到调参的不容易,不同的参数对结果都有一时无法准确确定的影响,只能通过多次调参,结合理论,总结经验,方便下次求解,
    另外,虽然遗传算法不能完全解决所有问题(大多时候只能找到局部最优),但对于那些精度要求不高的问题,遗传算法提供了一种高效而且易于实现的解决方案,大大减少了计算量和成本。
  • 36
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值