数学算法之遗传算法

本文深入讲解遗传算法原理,包括算法的起源、工作流程、组成要素及优缺点,并通过MATLAB实例演示遗传算法求解函数最大值的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

遗传算法是由John Holland与其同事、学生在20世纪60年代末70年代初提出来的算法,是模拟自然界生物遗传所得的算法,所以它具有很高的智能性,在处理复杂非线性的工程问题时,体现了很大优势,能保证其快速精确地收敛到所需要的精度,能达到工程所需要的结果。

遗传算法原理

遗传算法是根据生物进化论演化而来.它的工作原理是,产生一个原始种群,通过达尔文提出的优胜劣汰的自然原则,把不适应环境的个体淘汰,留下适应的个体,通过一代代的繁衍,不断的选择(selection),交叉(crossover),变异(muta-tion),最后得到可以完全适应所需环境的个体,而这个个体就是我们所要求的解.具体说来可分以下步骤:

1)产生初始种群,初始化相关参数,包括最大遗传代数(maxgen)、种群规模(sizepop)、交叉概率、变异概率以及个体上下限,计算初始适应度值(fitness),得到初始种群的最佳个体(bestchrom)及其适应度值(bestfitness).
2)for i= 1 to maxgen.循环执行第3到第5步.
3)对每一代的种群进行选择、交叉、变异.
4)计算每一代所产生的新种群适应度值fitness.
5)根据fitness来判断是否得到所需的解.
6)得出全局的bestchrom以及bestfitness.
通过实验我们发现,遗传算法对初始值的要求不是很高,只需给出大致的范围即可求解,而何选择适当的fitness函数对结果能否收敛且达到所需精度非常重要。

遗传算法的组成

遗传算法可以定义为一个八元组
八元组公式
式中:C表示个体的编码方法,可分为浮点编码和二进制编码;E表示个体适应度评价函数,它在遗传算法中起环境的作用,是选择的依据;P0表示初始群体;M表示初始群体的大小,一般为20~ 100;phi表示选择算子,选择方法主要有轮盘选择法、随机遍历抽样、波尔兹曼选择法、锦标赛选择法等;Γ表示交叉算子,主要有离散交叉、中间交叉、线性交叉、单点交叉、多点交叉等; 表示变异算子,主要有边界变异、非均衡变异、多重均衡变异等;T表示算法的终止条件,可以规定最大遗传代数或最小偏差等条件来终止遗传算法,一般情况下,最大代数可取为100~ 500.

遗传算法流程
其间完整的过程解释:确定编码方式,对问题的解进行编码;初始化种群(种群中每一个个体均编码完成);评价种群中的个体(采用适应度函数进行评估,位串的解码值,目标函数值,目标函数值向适应值映射,适应值调整);判断是否满足要求(满足结束迭代,获取最优解,不满足继续进行迭代过程);进行遗传操作:选择、交叉、变异;产生新的一代种群;继续进行评价种群的个体。

遗传算法实操

该案例参考了目前为止看到比较清楚明白的一篇文章[遗传算法介绍-]。(https://blog.youkuaiyun.com/weixin_30352645/article/details/98830852)

首先,用matlab绘制了想求解函数的图象
绘制图象
接下来要做的是,用遗传算法求解最大值。

function main()
%主函数,初始化
%此处显示详细说明
%种群大小
popsize=100;
%二进制编码长度
chromlength=10
%交叉概率
pc=0.6;
%变异概率
pm=0.001;
%初始种群
pop=initpop(popsize,chromlength);

for i = 1:100
    %计算适应度值(函数值)
    objvalue=cal_objvalue(pop);
    fitvalue=objvalue;
    %选择操作
    newpop=selection(pop,fitvalue);
    %交叉操作
    newpop=crossover(newpop,pc);
    %变异操作
    newpop=mutation(newpop,pm);
    %更新种群
    pop=newpop;
    %寻找最优解
    [bestindividual,bestfit]=best(pop,fitvalue);
    x2=binary2decimal(bestindividual);
    x1=binary2decimal(newpop);
    y1 = cal_objvalue(newpop);
    if mod(i,10) == 0 %绘图,没什么用
        figure;
        fplot(@(x)10.*sin(5*x)+7.*abs(x-5)+10);
        hold on;
        plot(x1,y1,'*');
        title(['迭代次数为n=' num2str(i)]);
        %plot(x1,y1,'*');
    end
end
fprintf('The best X is --->>%5.2f\n',x2);
fprintf('The best Y is --->>%5.2f\n',bestfit);

function pop=initpop(popsize,chromlength)
%初始化种群大小
%输入变量:
%popsize:种群大小
%chromlength:染色体长度-->>转化的二进制长度
%输出变量:
%pop:种群
pop=round(rand(popsize,chromlength)); %返回的每行是一个个体

function pop2=binary2decimal(pop)
%二进制转化成十进制函数
%输入变量:
%二进制种群
%输出变量
%十进制数值
[px,py]=size(pop);
for i=1:py
    pop(:,i)=2.^(py-i).*pop(:,i);
end
%sum(.,2)对行求和,得到列向量
temp=sum(pop,2);
pop2=temp*10/1023;

function[objvalue]=cal_objvalue(pop)
%计算函数目标值,输入:二进制,输出:目标函数值
x=binary2decimal(pop);
%转化二进制数为x变量的变化域范围的数值
objvalue=10*sin(5*x)+7*abs(x-5)+10;

function [newpop]=selection(pop,fitvalue)
%选择新的个体,构造轮盘
[px,~] = size(pop);
totalfit = sum(fitvalue);
p_fitvalue = fitvalue/totalfit;
p_fitvalue = cumsum(p_fitvalue);%概率求和排序
ms = sort(rand(px,1));%从小到大排列
fitin = 1;
newin = 1;
while newin<=px
    if(ms(newin))<p_fitvalue(fitin)
        newpop(newin,:)=pop(fitin,:);
        newin = newin+1;
    else
        fitin=fitin+1;
    end
end

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);
        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 [newpop] = mutation(pop,pm)
%变异
[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 newpop(i,mpoint) == 0
            newpop(i,mpoint) = 1;
        else newpop(i,mpoint)==1
            newpop(i,mpoint) = 0;
        end
    else newpop(i,:) = pop(i,:);
    end
end

%求最优适应度函数
%输入变量:pop:种群,fitvalue:种群适应度
%输出变量:bestindividual:最佳个体,bestfit:最佳适应度值
function [bestindividual,bestfit] = best(pop,fitvalue)
[px,~] = size(pop);
bestindividual = pop(1,:);
bestfit = fitvalue(1);
for i = 2:px
    if fitvalue(i)>bestfit
        bestindividual = pop(i,:);
        bestfit = fitvalue(i);
    end
end

结果随机性较大

遗传算法优缺点

优点:编码、解码操作简单易行;交叉、变异等遗传操作便于实现;合最小字符集编码原则;利用模式定理对算法进行理论分析。
缺点:对于一些连续函数的优化问题,由于其随机性使得其局部搜索能力较差,如对于一些高精度的问题,当解迫近于最优解后,由于其变异后表现型变化很大,不连续,所以会远离最优解,达不到稳定。

这个案例只是初步掌握了遗传算法原理,具体怎样真正寻找到最优解,还需要其他小技巧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值