【国赛培训】遗传算法

时间:2019.8.13
老师:姚香娟
内容:遗传算法基本原理
个性:和蔼、娓娓道来

感想:遗传早有接触,这次再来参加,主要是想能够在理论介绍方面,对遗传算法有一个较为详细的学习。另一个就是希望能够针对写作,对流程再次熟悉,在国赛前复现准备。果然一些数值计算需要线性代数的知识,当时大一时候,看了好多次的遗传,总是不够通透。

1.遗传算法起源与发展

  • 遗传算法是模拟达尔文生物进化论的自然选择和孟德尔遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。

1975年密西根大学的J.Holland教授提出一种简单遗传算法(simple genetic algorithm, SGAran'se)由编解码、个体适应度评估和遗传运算三大模块构成,而遗传算法又包括染色体复制、交叉、变异甚至到位等。

改良的遗传算法和融合新型技术的遗传算法都是简单遗传算法的变异形式。

20世纪60年代,Holland教授及其学生和同事提出,一种全局概率搜索优化算法,借鉴生物。
1975 De Jong建立了著名的五函数测试平台。
1983 Goldberg第一次把遗传算法用于实际工程应用。

2.遗传算法基本原理

三大模块:编解码,个体适应度评估,遗传运算

数学模型
max\ f(X) \\ {s.t.}\left\{ \begin{aligned} X\in{U} \\ U\in{R}^n \end{aligned} \right.
编码:把问题的解从其解空间转换到遗传算法的搜索空间的转换方法。
最常用的是二进制编码,构成的个体基因型是二进制符号串。
个体适应度:对应个体表现型X的目标函数值相关联,X越接近于目标函数的最优值,适应度越大。
个体基因型:编码之后的个体表示方法a_1a_2a_3La_n
个体表现型:原来的个体表现方法x_1x_2x_3Lx_n

3.遗传算法基本步骤

step1: 初始种群,生成X_i
step2: 个体评价f(X_i)适应值函数
step3: 是否满足终止条件
step4: 选择、交叉、变异
step5: 得到子代种群
step6: 子代代替父代,重复step2及之后,直到找到需要解为止

考虑:

  • 解的遗传表示
  • 初始种群的产生
  • 个体的评价函数
  • 遗传算子(选择、交叉、变异)
  • 算法的控制参数(种群规模、交叉和变异概率等)

4.遗传算法的特点

传统算法
模型结构固定,有较为精确的问题描述
给出精确解
如:线性规划、整数规划、运输问题……

智能优化方法
对优化模型没有结构上的要求
在可接受的时间里找到满意解(可以使用机器学习的方法进行评价)
如:遗传算法、蚁群算法、粒子群算法】免疫算法……

适合组合优化问题:装箱,着色,匹配,TSP,工业设计(电路板,洗衣液配方,轮胎橡胶设计)

5.实例分析

  • 采用米哈来维茨的范式
  • 求解如下约束条件下的最优解
  • 个体表示(考虑精度要求)
    eg.精度小数点后4位,x_{j}取值范围[a,b]
    则设需要m_j位二进制,需满足2^{m_j-1}<(b-a)×10^4<=2^{m_j}-1
  • 从二进制到十进制实数x_j的映射为:
    x_{i}=a_{i}+decimal(substring_i)×\frac{b-a}{2^{m_j}-1}最低值+小区间个数×小区间长度

每个解的二进制编码位数即:m_1+m_2+m_3+.....+m_n
比如001,100,010 6位

  • 随机初始种群
  • 实施个体评价(终止条件设定为1000代)
  • 遗传算子,使用轮盘赌算法,选择概率和适应值成正比。
    交叉和变异依交叉和变异概率对基因进行操作
  • 用当前种群代替初始种群,循环操作。

7.调用MATLAB的GA工具箱实现遗传算法

调用命令:

{min}\ f(x) \\ s.t.\left\{ \begin{aligned} Ax\le{B} \\ Aeq\cdot{x}=Beq \\ C(x)\lt0 \\ Ceq(x)=0 \end{aligned} \right.
其中,f(x)是标量函数;A,B,Aeq,Beq是相应维数的矩阵和向量(构成约束),C(x)和Ceq(x)是非线性向量函数
[X,FVAL]=GA(FITNESSFCN, NVARS,A,B,Aeq,Beq,lb,ub,NONLCON,options)

example
 function f = myfit(x)
         f = exp(x(1))*(4*x(1)^2 + 2*x(2)^2 + 4*x(1)*x(2) + 2*x(2) + 1);

 function [c,ceq] = myconstr(x) %约束条件列表
         c = [1.5 + x(1)*x(2) - x(1) - x(2);
               -x(1)*x(2) - 10];
         % No nonlinear equality constraints:
          ceq = [];

[x,fval]= ga(@(x)myfit(x),2,[],[],[],[],[],[],@(x)myconstr(x))

可视化工具箱界面配置

选择GA
function [ y ] = target(x)
% 工具箱只支持求解最小值,将求解最大值变成求解最小值
y = -x-10*sin(5*x)-7*cos(4*x);
end

下面设置参数,关于一些约束条件的理解需要参考上面公式,完全理解需要线性代数的知识,犹记得去年大一的时候,那时没有学习线性代数,建了四五次模型,经常想着去使用遗传算法,然而总没能实现完全复现。当然,当时资料相比于现在,还是很残缺的。如今互联网上,更多人愿意去做详细的教程型博客了,这是一个巨大的改观。我的话,现在仍以记录自己的总结为主,主要是帮自己梳理一下。


设置参数,约束条件的理解参考上面的公式

8.编写.m函数实现遗传算法

学习参考博客:遗传算法介绍及详尽代码
学习推荐参考博客:很详尽
代码参考博客:遗传算法流传版本改错

% 下面举例说明遗传算法 %
% 求下列函数的最大值 %
% f(x)=10*sin(5x)+7*cos(4x) x∈[0,10] %
% 将 x 的值用一个10位的二值形式表示为二值问题,一个10位的二值数提供的分辨率是每为 (10-0)/(2^10-1)≈0.01 
% 将变量域 [0,10] 离散化为二值域 [0,1023], x=0+10*b/1023, 其中 b 是 [0,1023] 中的一个二值数。 %
% %
%--------------------------------------------------------------------------------------------------------------%
%--------------------------------------------------------------------------------------------------------------

% 2.0 主程序
%遗传算法主程序
%Name:genmain05.m
%要求精度不大于0.01,
function []=yichuan()
popsize=20;                         %群体大小
chromlength=10;                  %字符串长度(个体长度)
pc=0.6;                                %交叉概率,只有在随机数小于pc时,才会产生交叉
pm=0.001;                           %变异概率

pop=initpop(popsize,chromlength);               %随机产生初始群体
for i=1:20                                                        %20为遗传代数
        [objvalue]=calobjvalue(pop);                  %计算目标函数
        fitvalue=calfitvalue(objvalue);                 %计算群体中每个个体的适应度

        [newpop]=selection(pop,fitvalue);                 %复制
        [newpop1]=crossover(newpop,pc);               %交叉
        [newpop2]=mutation(newpop1,pc);               %变异
        
        [objvalue]=calobjvalue(newpop2);                 %计算目标函数
        fitvalue=calfitvalue(objvalue);                       %计算群体中每个个体的适应度
        
        [bestindividual,bestfit]=best(newpop2,fitvalue);     %求出群体中适应值最大的个体及其适应值
        y(i)=bestfit;                                                              %返回的 y 是自适应度值,而非函数值
        x(i)=decodechrom(bestindividual,1,chromlength)*10/1023;      %将自变量解码成十进制
        pop=newpop2;
end
fplot(@(x)10.*sin(5.*x)+7.*cos(4.*x))
hold on
plot(x,y,'r*')                                          
hold on

[z, index]=max(y);             %计算最大值及其位置
x5=x(index)                     %计算最大值对应的x值
ymax=z

% 2.1初始化(编码)
% initpop.m函数的功能是实现群体的初始化,popsize表示群体的大小,chromlength表示染色体的长度(二值数的长度),
% 长度大小取决于变量的二进制编码的长度(在本例中取10位)。
function [pop]=initpop(popsize,chromlength) 
pop=round(rand(popsize,chromlength)); 
% rand随机产生每个单元为 {0,1} 行数为popsize,列数为chromlength的矩阵,
% round对矩阵的每个单元进行圆整。这样产生的初始种群。

% 2.2.3 计算目标函数值
% calobjvalue.m函数的功能是实现目标函数的计算,其公式采用本文示例仿真,可根据不同优化问题予以修改。
%遗传算法子程序
%Name: calobjvalue.m
%实现目标函数的计算,将 二值域 中的数转化为 变量域的数
function [objvalue]=calobjvalue(pop)
temp1=decodechrom(pop,1,10);   %将pop每行转化成十进制数
x=temp1*10/1023;                         %在精度不大于0.01时,最小整数为1023,即需要10位二进制
objvalue=10*sin(5*x)+7*cos(4*x);   %计算目标函数值

% 2.3 计算个体的适应值
%遗传算法子程序
%Name:calfitvalue.m
%计算个体的适应值
function fitvalue=calfitvalue(objvalue)

[px,~]=size(objvalue);                   %目标值有正有负
for i=1:px
        if objvalue(i)>0                    
                temp=objvalue(i);          
        else
                temp=0.0;
        end
        fitvalue(i)=temp;
end
fitvalue=fitvalue';

% 2.4 选择复制
% 选择或复制操作是决定哪些个体可以进入下一代。程序中采用赌轮盘选择法选择,这种方法较易实现。
% 根据方程 pi=fi/∑fi=fi/fsum ,选择步骤:
% 1) 在第 t 代,由(1)式计算 fsum 和 pi 
% 2) 产生 {0,1} 的随机数 rand( .),求 s=rand( .)*fsum
% 3) 求 所有fi≥s 中最小的 k ,则第 k 个个体被选中
% 4) 进行 N 次2)、3)操作,得到 N 个个体,成为第 t=t+1 代种群
%遗传算法子程序
%Name: selection.m
%选择复制
function [newpop]=selection(pop,fitvalue) 
totalfit=sum(fitvalue);                   %求适应值之和
fitvalue=fitvalue/totalfit;                %单个个体被选择的概率
fitvalue=cumsum(fitvalue);            %如 fitvalue=[1 2 3 4],则 cumsum(fitvalue)=[1 3 6 10],不明白为什么要累加 
[px,~]=size(pop);                       %20*10
ms=sort(rand(px,1));                   %从小到大排列
fitin=1;
newin=1;
while newin<=px                          %选出20个新个体,有重复情况,和上面介绍的方法不太一样
        if(ms(newin))<fitvalue(fitin)
                newpop(newin,:)=pop(fitin,:);
                newin=newin+1;
        else
                fitin=fitin+1;
        end
end

% 2.5 交叉
% 交叉(crossover),群体中的每个个体之间都以一定的概率 pc 交叉,即两个个体从各自字符串的某一位置
% (一般是随机确定)开始互相交换,这类似生物进化过程中的基因分裂与重组。例如,假设2个父代个体x1,x2为:
% x1=0100110,x2=1010001
% 从每个个体的第3位开始交叉,交又后得到2个新的子代个体y1,y2分别为:
% y1=0100001,y2=1010110
% 这样2个子代个体就分别具有了2个父代个体的某些特征。利用交又我们有可能由父代个体在子代组合成具有更高适合度的个体。
% 事实上交叉是遗传算法区别于其它传统优化方法的主要特点之一。
%遗传算法子程序
%Name: crossover.m
%交叉
function [newpop]=crossover(pop,pc)          %pc=0.6
[px,py]=size(pop);
newpop=ones(size(pop));
for i=1:2:px-1                                             %步长为2,是将相邻的两个个体进行交叉
        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

% 2.6 变异
% 变异(mutation),基因的突变普遍存在于生物的进化过程中。变异是指父代中的每个个体的每一位都以概率 pm 翻转,
%即由“1”变为“0”,或由“0”变为“1”。
%遗传算法的变异特性可以使求解过程随机地搜索到解可能存在的整个空间,因此可以 在一定程度上 求得全局最优解。
%遗传算法子程序
%Name: mutation.m
%变异
function [newpop]=mutation(pop,pm)
        [px,py]=size(pop);
        newpop=ones(size(pop));
        for i=1:px
                if(rand<pm)
                        mpoint=round(rand*py);     %产生的变异点在1-10之间
                        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

% 2.7 求出群体中最大得适应值及其个体
%遗传算法子程序
%Name: best.m
%求出第 t 代群体中适应值最大的值
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

% 2.2 计算目标函数值
% 2.2.1 将二进制数转化为十进制数(1)
%遗传算法子程序
%Name: decodebinary.m
%产生 [2^n 2^(n-1) ... 1] 的行向量,然后求和,将二进制转化为十进制
function pop2=decodebinary(pop)
[~,py]=size(pop);                   %求pop行和列数
for i=1:py
pop1(:,i)=2.^(py-i).*pop(:,i);
end
pop2=sum(pop1,2);                 %求pop1的每行之和

% 2.2.2 将二进制编码转化为十进制数(2)
% decodechrom.m函数的功能是将染色体(或二进制编码)转换为十进制,参数spoint表示待解码的二进制串的起始位置
% (对于多个变量而言,如有两个变量,采用20为表示,每个变量10为,则第一个变量从1开始,另一个变量从11开始。本例为1),
% 参数1ength表示所截取的长度(本例为10)。
%遗传算法子程序
%Name: decodechrom.m
%将二进制编码转换成十进制
function pop2=decodechrom(pop,spoint,length)          %1  10
pop1=pop(:,spoint:spoint+length-1);
pop2=decodebinary(pop1);                                           %将pop每行转换成十进制值,结果是20*1的矩阵
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容