遗传算法的matlab初步实现
2018.7.20
做了7个小时,终于搞出来了一个可行的遗传算法
本遗传算法用于实现了
这比昨天的粒子群算法复杂多了。。
而且出了一大堆问题。。。
不过呢。。写完就好。。。哈哈哈
主函数部分
clear;
clc;
popsize=20;%种群大小
chromlength=10;%二进制编码长度
pc = 0.7;%交叉概率
pm = 0.005;%变异概率
pop = initpop(popsize,chromlength);%初始种群
for i = 1:2000 % 迭代次数
[objvalue] = calobjvalue(pop); %计算目标函数
fitvalue = calfitvalue(objvalue); %计算适应度值(函数值)
[newpop] = selection(pop,fitvalue); % 选择操作
[newpop] = crossover(newpop,pc); %交叉操作
[newpop] = mutation(newpop,pm); %变异操作
[bestindividual,bestfit] = best(newpop,fitvalue); %更新种群
%寻找最优解
y(i)=max(bestfit);
n(i)=i;
pop5=bestindividual;
x(i)=decodechrom(pop5,1,chromlength)*10/1023;
pop=newpop;
end
fplot(@(x)9.*sin(5.*x)+8.*cos(4.*x))
hold on
plot(x,y,'r')
hold off
function [bestindividual bestfit] = best(pop,fitvalue)
%求最优适应度函数
%输入变量:pop:种群,fitvalue:种群适应度
%输出变量:bestindividual:最佳个体,bestfit:最佳适应度值
%function [bestindividual bestfit] = best(pop,fitvalue)
[px,py] = size(pop);
bestindividual = pop(1,:);
bestfit = fitvalue(1);
for i = 2:px
if fitvalue(i)>bestfit
bestindividual = pop(i,:);
bestfit = fitvalue(i);
end
end
function fitvalue = calfitvalue(objvalue )
% 本函数用于计算个体的适应度
global Cmin;
Cmin=0;
[px,py]=size(objvalue);
for i=1:px
if objvalue(i)+Cmin>0
temp=Cmin+objvalue(i);
else
temp=0.0;
end
fitvalue(i)=temp;
end
end
function [ objvalue ] = calobjvalue(pop) *此目标函数是可以改动的,是我们适应度函数的一部分,中间有一步二值域转化为变量域的操作。。看不懂。。。不清楚
% 本函数用于实现目标函数的计算
% function [ objvalue ] = calobjvalue(pop)
temp1=decodechrom(pop,1,10);
x=temp1*10/1023;
objvalue=10*sin(5*x)+7*cos(4*x);
end
function [newpop ] = crossover( pop,pc )
% 本函数用于实现个体的交叉
% function [newpop ] = crossover( pop,pc )
%输入变量:pop:二进制的父代种群数,pc:交叉的概率
%输出变量:newpop:交叉后的种群数
[px,py] = size(pop);
newpop = ones(size(pop)); %预分配内存
for i = 1:2:px-1 %选择奇数位个体
if(rand<pc) %进行交叉
cpoint = round(rand*py); %round towards nearest decimal or integer 选择交叉点
newpop(i,:) = [pop(i,1:cpoint),pop(i+1,cpoint+1:py)]; %交换
newpop(i+1,:) = [pop(i+1,1:cpoint),pop(i,cpoint+1:py)];
else
newpop(i,:) = pop(i,:);
newpop(i+1,:) = pop(i+1,:);
end
end
function pop2 = decodebinary( pop )
%本函数用于实现二进制数转化为二进制数
% pop为种群矩阵
[px,py]=size(pop);
for i=1:py
pop1(:,i)=2.^(py-i).*pop(:,i);%用于实现pop1为pop的十进制数储存
end
pop2=sum(pop1,2); %求pop1的每行之和
end
function pop2 = decodechrom( pop,spoint,length )
% 将二进制编码转化成十进制数
% function pop2 = decodechrom( pop,spoint,length )
% spoint 表示待解码的二进制串的起始位置
% length表示所截取的长度
pop1=pop(:,spoint:spoint+length-1);
pop2=decodebinary(pop1);
end
function pop = initpop( popsize,chromlength )
% 本函数用于实现遗传算法初始化
% popsize为种群的大小,也为随机矩阵的行数
% chromlength为列数,也为二进制编码
%function pop = initpop( popsize,chromlength )
pop=round(rand(popsize,chromlength));
end
function [newpop] = mutation(pop,pm)
%本函数进行变异操作
%输入变量:pop:二进制种群,pm:变异概率
%输出变量:newpop变异以后的种群
[px,py] = size(pop);
newpop = ones(size(pop));
for i = 1:px
if(rand<pm)
mpoint = round(rand*py);
if mpoint <= 0;
mpoint = 1;
end
newpop(i,:) = pop(i,:);
if any(newpop(i,mpoint)) == 0
newpop(i,mpoint) = 1;
else
newpop(i,mpoint) = 0;
end
else
newpop(i,:) = pop(i,:);
end
end
function [ newpop ] = selection( pop,fitvalue ) ( 最重要的主体部分)
% 本函数实现选择复制,决定哪些个体可以进入下一代
% function [ newpop ] = selectiom( pop,fitvalue )
% 输出变量:newpop选择以后的二进制种群
totalfit=sum(fitvalue);
fitvalue=fitvalue/totalfit; %单个个体被选择的概率
fitvalue=cumsum(fitvalue); %如fitvalue=[1 2 3 4],cumsum(fitvalue)=[1,3,6,10]
[px,py]=size(pop);
ms=sort(rand(px,1)); %产生[0,1]随机数从小到大排列
fitin=1;
newin=1; %newin为转动次数
while newin<=px %(f1+...fk)>=s的最小的k,即被选中
if(ms(newin))<fitvalue(fitin) %选中
newpop(newin,:)=pop(fitin,:);
newin=newin+1;
else %淘汰
fitin=fitin+1;
end
end
今天是7月20日,明天想进入一下Arduino的学习