遗传算法 GA
基本遗传算法(SGA)由编码、适应度函数、遗传算子(选择、交叉、变异)及运行参数组成。 可能存在局部最优的问题
编码
二进制编码的字符串长度与问题所求解的精度有关。需要保证所求解空间内的每一个个体都可以被编码。
适应度函数
适应度函数要有效反映每一个染色体与问题的最优解染色体之间的差距。
选择算子
通过选择算子模拟“优胜劣汰”,适应度高的个体被遗传到下一代的概率较大,适应度低的算子被遗传到下一代的概率较小。
常用的选择算法:轮盘赌选择法,即令表示群体的适应度函数值的总和,表示群体中第i个染色体的适应度值,则它产生后代的能力刚好为其适应度值所占的份额
交叉算子
- 交叉运算是指对两个相互配对的染色体按某种方式相互交换其部分基因,从而形成两个新的个体;
- 交叉运算是遗传算法区别于其他进化算法的重要特征,是产生新个体的主要方法。
在交叉之前需要将群体中的个体进行配对,一般采取随机配对原则。
变异算子
遗传算法中的变异运算是指将个体染色体编码串中的某些基因座上的基因值用该基因座的其他等位基因来替换,从而形成一个新的个体。
代码
遗传参数设置
%%
%%遗传参数设置
NUMPOP=100;%初始种群大小
irange_l=-1; %问题解区间
irange_r=2;
LENGTH=22; %二进制编码长度
ITERATION = 10000;%迭代次数
CROSSOVERRATE = 0.7;%杂交率
SELECTRATE = 0.5;%选择率
VARIATIONRATE = 0.001;%变异率
初始化种群 随机选取x
function pop=m_InitPop(numpop,irange_l,irange_r)
%% 初始化种群
% 输入:numpop--种群大小;
% [irange_l,irange_r]--初始种群所在的区间
pop=[];
for i=1:numpop
pop(:,i)=irange_l+(irange_r-irange_l)*rand;
end
end
计算适应度 计算距离
function fitness=m_Fitness(pop)
%% Fitness Function
%y=xsin(3x)在[-1,2]上,最大值也不会超过2
%所以计算函数值到2的距离,距离最小时,即为最优解
%适应度函数为1/距离
for n=1:size(pop,2)
fitness(n)=1/(2-m_Fx(pop(:,n)));
end
end
选择 轮盘赌选择算法
function parentPop=m_Select(matrixFitness,pop,SELECTRATE)
%% 选择
% 输入:matrixFitness--适应度矩阵
% pop--初始种群
% SELECTRATE--选择率
sumFitness=sum(matrixFitness(:));%计算所有种群的适应度
accP=cumsum(matrixFitness/sumFitness);%累积概率
%轮盘赌选择算法
for n=1:round(SELECTRATE*size(pop,2))
matrix=find(accP>rand); %找到比随机数大的累积概率
if isempty(matrix)
continue
end
parentPop(:,n)=pop(:,matrix(1));%将首个比随机数大的累积概率的位置的个体遗传下去
end
end
编码 编码为pop_length长度的二进制
function binPop=m_Coding(pop,pop_length,irange_l)
%% 二进制编码(生成染色体)
% 输入:pop--种群
% pop_length--编码长度
pop=round((pop-irange_l)*10^6);
for n=1:size(pop,2) %列循环
for k=1:size(pop,1) %行循环
dec2binpop{k,n}=dec2bin(pop(k,n));%dec2bin的输出为字符向量;
%dec2binpop是cell数组
lengthpop=length(dec2binpop{k,n});
for s=1:pop_length-lengthpop %补零
dec2binpop{k,n}=['0' dec2binpop{k,n}];
end
end
binPop{n}=dec2binpop{k,n}; %取dec2binpop的第k行
end
交叉算子 某个位置进行交换二进制
%% 子函数
%
%题 目:Crossover
%
%%
%输 入:
% parentsPop 上一代种群
% NUMPOP 种群大小
% CROSSOVERRATE 交叉率
%输 出:
% kidsPop 下一代种群
%
%%
function kidsPop = Crossover(parentsPop,NUMPOP,CROSSOVERRATE)
kidsPop = {[]};n = 1;
while size(kidsPop,2)<NUMPOP-size(parentsPop,2)
%选择出交叉的父代和母代
father = parentsPop{1,ceil((size(parentsPop,2)-1)*rand)+1};
mother = parentsPop{1,ceil((size(parentsPop,2)-1)*rand)+1};
%随机产生交叉位置
crossLocation = ceil((length(father)-1)*rand)+1;
%如果随即数比交叉率低,就杂交
if rand<CROSSOVERRATE
father(1,crossLocation:end) = mother(1,crossLocation:end);
kidsPop{n} = father;
n = n+1;
end
end
变异算子 找到变异位置 对其做出更改
%% 子函数
%
%题 目:Variation
%
%
%输 入:
% pop 种群
% VARIATIONRATE 变异率
%输 出:
% pop 变异后的种群
%%
function kidsPop = Variation(kidsPop,VARIATIONRATE)
for n=1:size(kidsPop,2)
if rand<VARIATIONRATE
temp = kidsPop{n};
%找到变异位置
location = ceil(length(temp)*rand);
temp = [temp(1:location-1) num2str(~temp(location))...
temp(location+1:end)];
kidsPop{n} = temp;
end
end
解码
function pop=m_Incoding(binPop,irange_l)
%% 解码
popNum=1;
popNum = 1;%染色体包含的参数数量
for n=1:size(binPop,2)
Matrix = binPop{1,n};
for num=1:popNum
pop(num,n) = bin2dec(Matrix);
end
end
pop = pop./10^6+irange_l;
参考github
作者声明
如有问题,欢迎指正!