MATLAB实现智能计算方法实验:实验七 遗传算法
作者:互联网
资源链接
MATLAB实现智能计算方法课程所有实验代码资源链接为:MATLAB实现智能计算方法课程所有实验代码资源
实验目的
- 通过本次实验,进一步理解遗传算法的计算过程;
- 掌握手工计算过程和编码,并能够解决实际问题;
- 掌握MATLAB工具箱gatool的使用,并学会参数调整方法,解决实际优化问题。
实验内容
-
利用遗传算法,解决下列函数优化求解:
{ min F ( x , y ) = ( x − 3.5 ) 2 + ( y + 4 ) 2 1 < x , y < 10 \left\{ \begin{array}{l} \min F(x,y) = {(x - 3.5)^2} + {(y + 4)^2}\\ 1 < x,y < 10 \end{array} \right. {minF(x,y)=(x−3.5)2+(y+4)21<x,y<10
-
利用遗传算法,求函数 f ( x ) = x + 10 sin ( 5 x ) + 7 cos ( 4 x ) f(x) = x + 10\sin (5x) + 7\cos (4x) f(x)=x+10sin(5x)+7cos(4x) 的最大值,其中 0 ≤ x ≤ 9 {\rm{0}} \le x \le 9 0≤x≤9 。
实验步骤
1. 函数优化
1. 保存求解函数
将要求解的函数保存到工作空间中,代码如下:
function z = f1(x)
a = (x(1) - 3.5).^2;
b = (x(2) + 4).^2;
z = a + b;
2. 遗传算法工具箱优化求解
利用遗传算法工具箱进行优化求解,相关参数设置如下图1.1,options中plot function选择best fitness。
单击Start开始求解,求解过程中best fitness变化如下图1.2,最优解的值及此时变量取值如下图1.3。
由图1.3可知,最优解为25.0003,变量x的取值为3.484,y的取值为1,易知x=3.5, y=1时取到最优解为25,所求结果接近目标结果,效果较好。
3. 手工编码实现遗传算法
串位数、最大迭代次数等基本属性代码如下:
bn = 22;
inn = 50; %初始种群大小
gnmax = 500; %最大代数
pc = 0.75; %交叉概率
pm = 0.05; %变异概率
选择、变异、交叉等基本函数的编码如下:
%根据变异概率判断是否变异
function pcc = pro(pc)
test(1: 100) = 0;
l = round(100*pc);
test(1: l) = 1;
n = round(rand*99) + 1;
pcc = test(n);
end
%“选择”操作
function seln = sel(s, p)
inn = size(p, 1);
%从种群中选择两个个体,最好不要两次选择同一个个体
for i = 1: 2
r = rand; %产生一个随机数
prand = p - r;
j = 1;
while prand(j) < 0
j = j + 1;
end
seln(i) = j; %选中个体的序号
if i == 2 && j == seln(i - 1) %%若相同就再选一次
r = rand; %产生一个随机数
prand = p - r;
j = 1;
while prand(j) < 0
j = j + 1;
end
end
end
end
%“交叉”操作
function scro = cro(s, seln, pc)
[~, bn] = size(s);
pcc = pro(pc); %根据交叉概率决定是否进行交叉操作,1则是,0则否
scro(1, :) = s(seln(1), :);
scro(2, :) = s(seln(2), :);
if pcc == 1
chb = round(rand*(bn - 2)) + 1; %在[1,bn-1]范围内随机产生一个交叉位
scro(1, :) = [s(seln(1), 1: chb) s(seln(2), chb + 1: bn)];
scro(2, :) = [s(seln(2), 1: chb) s(seln(1), chb + 1: bn)];
end
end
%“变异”操作
function snnew = mut(snew, pm)
r = size(snew);
bn = r(2);
snnew = snew;
pmm = pro(pm); %根据变异概率决定是否进行变异操作,1则是,0则否
if pmm == 1
chb = round(rand*(bn - 1)) + 1; %在[1,bn]范围内随机产生一个变异位
snnew(chb) = abs(snew(chb) - 1);
end
end
计算所有种群的适应度的函数如下:
%计算所有种群的适应度
function [f, p] = objf(s, a)
r = size(s); %读取种群大小
inn = r(1);
bn = r(2);
for i = 1: inn
x = bin2dec(num2str(s(i, :))); %将二进制转换为十进制
xx = 1 + 9*x/(power(2, bn)-1); %转化为[0,9]区间的实数
if(a == 1)
f(i) = ft1(xx);
f(i) = f(i);
else
f(i) = ft2(xx);
f(i) = f(i);
end
end
f = f'; %取距离倒数
%根据个体的适应度计算其被选择的概率
fsum = 0;
for i = 1: inn
fsum = fsum + f(i)*f(i);% 让适应度越好的个体被选择概率越高
end
for i = 1: inn
ps(i) = f(i)*f(i)/fsum;
end
%计算累积概率
p(1) = ps(1);
for i = 2: inn
p(i) = p(i-1) + ps(i);
end
p = p';
end
将所求函数分为两个适应度函数,分别求解最小值,最后计算二者的和从而得到所求函数的最小值,代码如下:
%适应度函数1
function y1 = ft1(x1)
y1 = 42.25 - (x1 - 3.5).^2;
end
%适应度函数2
function y2 = ft2(x2)
y2 = 196 - (x2 + 4).^2;
end
求解器函数及绘图曲线函数代码如下:
[ymax1, ymean1, xmax1, ~] = solver(1);
[ymax2, ymean2, xmax2, gn] = solver(2);
ymax = - (ymax1 + ymax2 - 42.25 - 196);
ymean = - (ymean1 + ymean2 - 42.25 - 196);
gn = gn - 1;
%绘制曲线
subplot(3, 1, 1);
plot(1: gn, [ymax; ymean]);
title('历代适应度变化', 'FontSize', 10);
legend('最大适应度', '平均适应度', 'Location', 'southeast');
string1 = ['最终适应度为', num2str(ymax(gn))];
subplot(3, 1, 2);
plot(1: gn, xmax1, 'r-');
legend('自变量x', 'Location', 'southeast');
string2 = ['最终自变量x为', num2str(xmax1(gn))];
subplot(3, 1, 3);
plot(1: gn, xmax2, 'g-');
legend('自变量y', 'Location', 'southeast');
string3 = ['最终自变量y为', num2str(xmax2(gn))];
gtext(string1);
gtext(string2);
gtext(string3);
%定义求解器
function [ymax, ymean, xmax, gn] = solver(a)
inn = 50; %初始种群大小
bn = 22;
gnmax = 500; %最大代数
pc = 0.75; %交叉概率
pm = 0.05; %变异概率
gn = 1;
s = round(rand(inn, bn));
[f, p] = objf(s, a);
while gn < gnmax + 1
for j = 1: 2: inn
seln = sel(s, p); %选择操作
scro = cro(s, seln, pc); %交叉操作
scnew(j, :) = scro(1, :);
scnew(j + 1, :) = scro(2, :);
smnew(j, :) = mut(scnew(j, :), pm); %变异操作
smnew(j + 1, :) = mut(scnew(j + 1, :), pm);
end
s = smnew; %产生了新的种群
[f, p] = objf(s, a); %计算新种群的适应度
%记录当前代最好和平均的适应度
[fmax, nmax] = max(f);
fmean = mean(f);
ymax(gn) = fmax;
ymean(gn) = fmean;
%记录当前代的最佳个体
x = bin2dec(num2str(s(nmax, :)));
xx1 = 1 + 9*x/(power(2, bn)-1);
xmax(gn) = xx1;
gn = gn + 1;
end
end
smnew(j, :) = mut(scnew(j, :), pm); %变异操作
smnew(j + 1, :) = mut(scnew(j + 1, :), pm);
end
s = smnew; %产生了新的种群
[f, p] = objf(s); %计算新种群的适应度
%记录当前代最好和平均的适应度
[fmax, nmax] = max(f);
fmean = mean(f);
ymax(gn) = fmax;
ymean(gn) = fmean;
%记录当前代的最佳个体
x = bin2dec(num2str(s(nmax, :)));
xx = 9*x/(power(2, bn)-1);
xmax(gn) = xx;
gn = gn + 1;
end
gn = gn - 1;
%绘制曲线
subplot(2, 1, 1);
plot(1: gn, [ymax; ymean]);
title('历代适应度变化', 'FontSize', 10);
legend('最大适应度', '平均适应度', 'Location', 'southeast');
string1 = ['最终适应度为', num2str(ymax(gn))];
subplot(2, 1, 2);
plot(1: gn, xmax, 'r-');
legend('自变量', 'Location', 'southeast');
string2 = ['最终自变量为', num2str(xmax(gn))];
gtext(string1);
gtext(string2);
运行程序,最终结果如下图1.4。
2. 求解函数最大值
1. 保存求解函数
将要求解的函数保存到工作空间中,代码如下:
function y = f2(x)
y = -(x + 10*sin(5*x) + 7*cos(4*x));
2. 遗传算法工具箱求解
利用遗传算法工具箱进行优化求解,相关参数设置如下图2.1。
由图2.3可知,x=7.779时, f ( x ) = − ( x + 10 s i n ( 5 x ) + 7 c o s ( 4 x ) ) f\left(x\right)=-(x+10sin{(}5x)+7cos{(}4x)) f(x)=−(x+10sin(5x)+7cos(4x))取到最小值为-23.7807,即 f ( x ) = x + 10 s i n ( 5 x ) + 7 c o s ( 4 x ) f\left(x\right)=x+10sin{(}5x)+7cos{(}4x) f(x)=x+10sin(5x)+7cos(4x)在x=7.779时取到最大值23.7807。
为进行结果的验证,我们绘制所求函数在[0, 9 ]区间的图像如下图2.4,
3. 手工编码实现遗传算法
定义适应度函数代码如下:
function y = ft(x)
y = x + 10*sin(5*x) + 7*cos(4*x);
end
计算种群适应度的函数代码如下:
%计算所有种群的适应度
function [f, p] = objf(s)
r = size(s); %读取种群大小
inn = r(1);
bn = r(2);
for i = 1: inn
x = bin2dec(num2str(s(i, :))); %将二进制转换为十进制
xx = 9*x/(power(2, bn)-1); %转化为[0,9]区间的实数
f(i) = ft(xx); %计算函数值,即适应度
end
f = f'; %取距离倒数
%根据个体的适应度计算其被选择的概率
fsum = 0;
for i = 1: inn
fsum = fsum + f(i)*f(i);% 让适应度越好的个体被选择概率越高
end
for i = 1: inn
ps(i) = f(i)*f(i)/fsum;
end
%计算累积概率
p(1) = ps(1);
for i = 2: inn
p(i) = p(i-1) + ps(i);
end
p = p';
end
计算的主函数及绘图函数代码如下:
%产生初始种群
s = round(rand(inn, bn));
[f, p] = objf(s);
gn = 1;
while gn < gnmax + 1
for j = 1: 2: inn
seln = sel(s, p); %选择操作
scro = cro(s, seln, pc); %交叉操作
scnew(j, :) = scro(1, :);
scnew(j + 1, :) = scro(2, :);
smnew(j, :) = mut(scnew(j, :), pm); %变异操作
smnew(j + 1, :) = mut(scnew(j + 1, :), pm);
end
s = smnew; %产生了新的种群
[f, p] = objf(s); %计算新种群的适应度
%记录当前代最好和平均的适应度
[fmax, nmax] = max(f);
fmean = mean(f);
ymax(gn) = fmax;
ymean(gn) = fmean;
%记录当前代的最佳个体
x = bin2dec(num2str(s(nmax, :)));
xx = 9*x/(power(2, bn)-1);
xmax(gn) = xx;
gn = gn + 1;
end
gn = gn - 1;
%绘制曲线
subplot(2, 1, 1);
plot(1: gn, [ymax; ymean]);
title('历代适应度变化', 'FontSize', 10);
legend('最大适应度', '平均适应度', 'Location', 'southeast');
string1 = ['最终适应度为', num2str(ymax(gn))];
subplot(2, 1, 2);
plot(1: gn, xmax, 'r-');
legend('自变量', 'Location', 'southeast');
string2 = ['最终自变量为', num2str(xmax(gn))];
gtext(string1);
gtext(string2);
运行程序,最终结果如下图2.5。
标签:seln,end,bn,inn,适应度,实验,MATLAB,gn,遗传算法 来源: https://blog.csdn.net/qq_36949278/article/details/122014034