遗传算法简介
百度上讲的很清楚,笔者这里就不一一赘述了,故附上网址。
https://baike.baidu.com/item/%E9%81%97%E4%BC%A0%E7%AE%97%E6%B3%95/838140?fr=aladdin#2
下面是一般遗传算法的流程图,编程的思想就算基于这个的。
题目与分析
代码
clear
clc
gen = 30;
popsize = 50;
cp = 0.9;
mp = 0.05;
% 个体初始化
chrome = [];
fitness = [];
avgfitness = [];
bestfitness = [];
bestchrome = [];
for i = 1:popsize
chrome(i,:) = randn(1,2);
fitness(i) = fx2(chrome(i,:));
end
% 进化开始
for i = 1:gen
[m,n] = size(chrome);
% 选择
chrome = select2(chrome);
% 交叉
chrome = cross2(cp,chrome);
% 变异
chrome = mutate2(mp,chrome);
for j = 1:m
fitness(i) = fx2(chrome(i,:));
end
avgfitness(i) = sum(fitness)/m;
bestfitness(i) = min(fitness);
[t,u] = min(fitness);
bestchrome(i,:) = chrome(u,:);
end
plot(avgfitness)
hold on
plot(bestfitness)
plot(bestchrome)
function fval=fx2(x)
% 计算目标函数值即适应度
fval = -20*exp(-0.2*sqrt((x(1)*x(1)+x(2)*x(2))/2))-exp((cos(2*pi*x(1))+cos(2*pi*x(2)))/2)+20+2.71289;
function ret=select2(chrome)
% 采用轮盘赌对种群chrome进行选择
[m,n] = size(chrome);
for i = 1:m
fitness(i) = fx2(chrome(i,:));
end
sumfitness = sum(fitness);
sumf = fitness/sumfitness;
index = [];
for i = 1:m
pick = rand;
while pick == 0
pick = rand;
end
for j = 1:m
pick = pick - sumf(j);
if pick < 0
index = [index j];
break;
end
end
end
for i = 1:length(index)
ret(i,:) = chrome(i,:);
end
function ret=cross2(pc,chrome)
% 进行种群的交叉
[m,n] = size(chrome);
for i = 1:m
pick = rand(1,2);
while prod(pick) == 0
pick = rand(1,2);
end
index = ceil(pick.*m);
pick = rand;
while pick == 0
pick = rand;
end
if pick > pc
continue;
end
% 进行交叉
v1 = chrome(index(1),:);
v2 = chrome(index(2),:);
temp1 = v1(1);
temp2 = v2(1);
v1(1) = temp2;
v2(1) = temp1;
if fx2(v1) < fx2(v2)
v = v1;
else
v = v2;
end
ret(i,:) = v;
end
function chrome=mutate2(mp,chrome)
% 该函数用来对种群进行变异
[m,n] = size(chrome);
for i = 1:m
pick = rand;
while pick == 0
pick = rand;
end
index = ceil(pick*m);
pick = rand;
if pick > mp
continue;
end
while pick == 0
pick = rand;
end
pos = ceil(pick*n);
chrome(pos) = randn;
end
结果分析
收敛过早可能是交叉和遗传时没有采用二进制编码,所以过程比较简单,且没有使用工具箱造成的结果。但是大体的趋势是一样的,最终都趋于0这个值,在第六代左右时x的值也趋近于0。