经典遗传算法及MATLAB实例
经典遗传算法及简单实例(MATLAB)
- 1. 遗传算法简单介绍
- 1.1 理论基础
- 1.2 算法要点
- 1.1 编码
- 1.2 适应度函数
- 1.3 基本流程
- 2. 代码实例(MATLAB)
- 2.1 代码汇总
- 2.1 初始化种群
- 2.2 计算适应度
- 2.3 迭代终止判断
- 2.4 自然选择(轮盘赌法)
- 2.5 配对交叉(单点)
- 2.6 变异(基本位变异)
- 2.7 获得最优解
- 2.8 雪兔遗传结果
- 2.9 改善遗传算法的方法
- 3. 多多交流!
1. 遗传算法简单介绍
1.1 理论基础
整个算法的基础就是达尔文的生物进化论,“物竞天择,适者生存” 这句话已经是常识了。
用雪兔做一个引子吧:
东北那旮瘩,有群原始雪兔,刚从未知物种进化而来,五颜六色(表现型)漂亮极了,称之为 I(0)。
(注意:种群初始化)
入夏了,雪兔们出来觅食,浅色兔在草地中无所遁形,被雪狐收割了一波(大批浅色+小批深色)。
入冬了,雪兔们出来觅食,深色兔在雪地中光彩夺目,被雪狐收割了一波(大批深色+小批浅色)。
(注意:自然选择过程)
春天到了,又到了兔兔们生孩的季节,雪兔们染色体内的基因进行 重组/不重组 ,产生一批受精卵。
(注意:交叉遗传过程)
受精卵内的生命活动非常强烈,造成了基因的 突变/不突变,产生了各种各样奇怪的小雪兔。
(注意:基因变异过程)
老雪兔们完成了自己繁衍的使命,全部不知所踪。留下新生代,继续在各种威胁下苟活,这一代叫 I(1)。
再次入冬入夏,雪兔们又出来觅食。。。。。。再次入冬,觅食。。。。。。入冬,觅食。。。。。。
就这样,50年后,基因突变和重组造就了种神奇的兔子:夏天褐色,冬天白色,可以轻易躲避雪狐的追捕
再次入冬入夏,雪兔们又出来觅食。。。。。。再次入冬,觅食。。。。。。入冬,觅食。。。。。。
这样,50年后,雪地里基本上见不到五颜六色的雪兔了,这时候雪兔们达到了兔生巅峰!
这就是遗传算法的理论基础,自然选择、交叉、变异、迭代,最终获得最优解。
注意:算法是根据表现型来进行选择,最终选出最优的表现型及其对应的基因。
1.2 算法要点
1.1 编码
编码是为了把我们的输入参数变成染色体(每个个体只有一条染色体),以便于进行交叉和遗传运算。
例如我们把雪兔的颜色进行划分, 0-255 (表现型)代表 黑->白 的不同程度,0就是纯黑的,255就是纯白的。
我们这里只谈一下简单的二进制编码,二进制编码中的每一个二进制位是一个基因,整个数字为染色体。
那么0-255共有256阶(表现型),我们可以用8位2进制数来表示(基因型)。
兔色为0的编码为 00000000,兔色为2的编码为 00000010,兔色为255的编码为 11111111。
1.2 适应度函数
适应度函数就是个体对环境的适应度,适应度越强的越能产生后代,保留自己的基因及表现型。
这里,我们假设灰色兔子的适应能力最强,即兔色为128的兔子不会被吃掉,设定函数为:
是一个最大值为128的分段函数,图像如下:
适应度函数的极值点一般是未知的,这里我们为了演示方便,就先展示出来。
1.3 基本流程
流程就和雪兔故事一样简单,如下所示:
注意:迭代的终止条件可以不是最大迭代次数,比如规定为种群适应度值的方差小于某个值(即种群表现型趋于一致)。
2. 代码实例(MATLAB)
2.1 代码汇总
遗传算法代码(通用代码):
function [bestChromosome,fitnessBest]=GA(numOfChromosome,numOfGene,iterationNum)
%% 函数功能:执行基于自适应遗传算法的卸载决策
% 输入:
% numOfChromosome:染色体数量,即迭代的种群大小
% numOfGene:基因的数量,即所用二进制编码的位数
% iterationNum:迭代的总次数,达到迭代次数即终止迭代
% 输出:
% bestChromosome:最优的染色体(即最优的输入)
% fitnessBest:最优的适应度值(即最优的结果)%% 随机生成初始种群,种群大小为numOfChromosome,染色体中基因数为numOfGene
% lastPopulation:上一代的种群(染色体)
% newPopulation:新一代的种群(染色体)
% randi([0,1])会产生0或1的整数
lastPopulation=randi([0,1],numOfChromosome,numOfGene);
newPopulation=zeros(numOfChromosome,numOfGene);%% 进行遗传迭代,直至达到最大迭代次数iterationNum
for iteration=1:iterationNum%% 计算所有个体(染色体)的适应度,一共有numOfChromosome个适应度值fitnessAll=zeros(1,numOfChromosome);for i=1:numOfChromosomeindividual=lastPopulation(i,:);fitnessAll(i)=fitnessFunc(individual);end%% 如果达到最大迭代次数,跳出(不能再进行选择遗传和变异了)if iteration==iterationNumbreak;end%% 使用轮盘赌法选择numOfChromosome条染色体,种群中个体总数不变fitnessSum=sum(fitnessAll);fitnessProportion=fitnessAll/fitnessSum;% 使用随机数进行numOfChromosome次选择,保持种群中个体数量不变for i=1:numOfChromosomeprobability=rand(1);proportionSum=0;chromosomeIndex=1;for j=1:numOfChromosomeproportionSum=proportionSum+fitnessProportion(j);if proportionSum>=probabilitychromosomeIndex=j;break;endendnewPopulation(i,:)=lastPopulation(chromosomeIndex,:);end%% 将染色体进行配对,执行单点交叉lastPopulation=newPopulation;% 生成从1到numOfChromosome的无序排列,每两个相邻数字进行配对coupleAllIndex=randperm(numOfChromosome);for i=1:floor(numOfChromosome/2)coupleOneIndex=coupleAllIndex(2*i-1:2*i);% 定义两条染色体交叉的概率,自己选择probability=0.6;% 如果生成的随机数在交叉概率内,执行交叉操作if rand(i)<probability% 随机生成交叉的基因点,将两条基因进行交叉crossPosition=randi([1,numOfGene],1);newPopulation(coupleOneIndex(1),crossPosition:end)=lastPopulation(coupleOneIndex(2),crossPosition:end);newPopulation(coupleOneIndex(2),crossPosition:end)=lastPopulation(coupleOneIndex(1),crossPosition:end);endend%% 对每条染色体执行基本位变异操作lastPopulation=newPopulation;for i=1:numOfChromosome% 定义染色体变异的概率,自己选择probability=0.2;% 如果生成的随机数在变异概率内,执行变异操作if rand(1)<probability% 选择变异的位置mutatePosition=randi([1,numOfGene],1);% 将对应基因位置的二进制数反转if(lastPopulation(i,mutatePosition)==0)newPopulation(i,mutatePosition)=1;elsenewPopulation(i,mutatePosition)=0;endendend %% 完成了一次迭代,更新种群lastPopulation=newPopulation;
end%% 遗传迭代结束后,获得最优适应度值和对应的基因
fitnessBest=max(fitnessAll);
bestChromosome=newPopulation(find(fitnessAll==fitnessBest,1),:);
雪兔例子的适应度计算代码:
function fitness=fitnessFunc(chromosome)
%% 函数功能:计算染色体的表现型及其适应度
% 输入:
% chromosome:染色体的基因序列
% 输出:
% fitness:染色体(个体)的适应度值%% 计算雪兔染色体对应表现型
len=length(chromosome);
numList=2.^(len-1:-1:0);
x=sum(chromosome.*numList);%% 计算表现型对应的适应度
if x<128fitness=x;
elseif x>128fitness=256-x;elsefitness=128;end
end
2.1 初始化种群
%% 随机生成初始种群,种群大小为numOfChromosome,染色体中基因数为numOfGene
% lastPopulation:上一代的种群(染色体)
% newPopulation:新一代的种群(染色体)
% randi([0,1])会产生0或1的整数
lastPopulation=randi([0,1],numOfChromosome,numOfGene);
newPopulation=zeros(numOfChromosome,numOfGene);
这里使用随机数生成函数生成了numOfChromosome条染色体,每条染色体有numOfGene个基因。
将生成的种群放入lastPopulation中,每一行是一条染色体。
newPopulation相当于一个辅助数组,存储生成种群的中间结果。
2.2 计算适应度
%% 计算所有个体(染色体)的适应度,一共有numOfChromosome个适应度值fitnessAll=zeros(1,numOfChromosome);for i=1:numOfChromosomeindividual=lastPopulation(i,:);fitnessAll(i)=fitnessFunc(individual);end
计算种群中所有个体的适应度,即把每一条染色体(个体)都放入适应度函数中,得到适应度结果。
2.3 迭代终止判断
%% 如果达到最大迭代次数,跳出(不能再进行选择遗传和变异了)if iteration==iterationNumbreak;end
计算完适应度,如果达到终止条件,就不再进行选择、遗传和变异了。
否则你跳出循环时,种群适应度与计算的的适应度不匹配。
另一种方案:执行选择、遗传、变异,跳出循环后再次计算适应度即可。
2.4 自然选择(轮盘赌法)
%% 使用轮盘赌法选择numOfChromosome条染色体,种群中个体总数不变fitnessSum=sum(fitnessAll);fitnessProportion=fitnessAll/fitnessSum;% 使用随机数进行numOfChromosome次选择,保持种群中个体数量不变for i=1:numOfChromosomeprobability=rand(1);proportionSum=0;chromosomeIndex=1;for j=1:numOfChromosomeproportionSum=proportionSum+fitnessProportion(j);if proportionSum>=probabilitychromosomeIndex=j;break;endendnewPopulation(i,:)=lastPopulation(chromosomeIndex,:);end
计算每个个体适应度占总适应度的比例,总适应度是一个饼图,每个个体占据一定的扇形区域。
然后生成numOfChromosome个0-1的随机数,随机数落在哪个区域,哪个个体便被生存,可重复选择。
显然,适应度高的个体容易被选择,将自己的基因和表现型遗传下去。
2.5 配对交叉(单点)
%% 将染色体进行配对,执行单点交叉lastPopulation=newPopulation;% 生成从1到numOfChromosome的无序排列,每两个相邻数字进行配对coupleAllIndex=randperm(numOfChromosome);for i=1:floor(numOfChromosome/2)coupleOneIndex=coupleAllIndex(2*i-1:2*i);% 定义两条染色体交叉的概率,自己选择probability=0.6;% 如果生成的随机数在交叉概率内,执行交叉操作if rand(i)<probability% 随机生成交叉的基因点,将两条基因进行交叉crossPosition=randi([1,numOfGene],1);newPopulation(coupleOneIndex(1),crossPosition:end)=lastPopulation(coupleOneIndex(2),crossPosition:end);newPopulation(coupleOneIndex(2),crossPosition:end)=lastPopulation(coupleOneIndex(1),crossPosition:end);endend
进行遗传的前提是配对,每两条染色体组合成一对,将两者的部分染色体进行交换。
单点交叉,顾名思义,选择染色体上的一个基因点,从这个基因点开始的两条染色体片段互换:
2.6 变异(基本位变异)
%% 对每条染色体执行基本位变异操作lastPopulation=newPopulation;for i=1:numOfChromosome% 定义染色体变异的概率,自己选择probability=0.2;% 如果生成的随机数在变异概率内,执行变异操作if rand(1)<probability% 选择变异的位置mutatePosition=randi([1,numOfGene],1);% 将对应基因位置的二进制数反转if(lastPopulation(i,mutatePosition)==0)newPopulation(i,mutatePosition)=1;elsenewPopulation(i,mutatePosition)=0;endendend
基本位变异就是选择一条染色体上的一个基因点,将其取反。
如染色体 11111111,选择其第四个基因进行基本位变异, 新染色体变为 11101111
2.7 获得最优解
%% 遗传迭代结束后,获得最优适应度值和对应的基因
fitnessBest=max(fitnessAll);
bestChromosome=newPopulation(find(fitnessAll==fitnessBest,1),:);
迭代结束之后,我们求出最大的适应度及其对应的染色体(个体),这就是我们需要的最优个体。
2.8 雪兔遗传结果
我们运行2.1给出的GA函数,在命令行输入以下代码运行:
[bestChromosome,fitnessBest]=GA(40,8,60)
40个染色体进行60次迭代。多次这行代码,发现结果可以不同,如下:
虽然结果不尽相同,但都接近最优解128,这是遗传算法本身的局限,不一定能获得最优解。
2.9 改善遗传算法的方法
通过2.8我们知道,遗传算法有时候只能逼近最优解,那么有什么方法能让他达到更好的逼近效果呢?
这里有几个方案:
- 使用自适应遗传和变异概率
- 增加种群中个体数量
- 增大迭代次数
- 使用双点交叉法
- 采用多样的变异方法
- 更改编码方式(某些情况)
- 更换适应度函数,将个体适应度的差距拉大
- 更换选择方法,轮盘赌法是最基本的方法,不科学
大家可以自行了解,以后可能会继续就这几个方面探讨。
3. 多多交流!
经典遗传算法及MATLAB实例相关推荐
- 智能优化算法及其MATLAB实例(第二版)——遗传算法2.1
一.遗传算法运算流程: (1)初始化.设置进化代数计数器g=0,设置最大进化代数G,随机生成NP个个体作为初始群体P(0). (2)个体评价.计算群体P( t)中各个个体的适应度. (3)选择运算.将 ...
- 龙格库塔法解微分方程组的matlab程序,MATLAB实例源码教程:龙格库塔法求解微分方程组源代码实例.doc...
MATLAB实例源码教程:龙格库塔法求解微分方程组源代码实例.doc MATLAB实例源码教程龙格库塔法求解微分方程组源代码实例题目用经典 Runge-Kutta方法求下列一阶微分方程组的近似解y1 ...
- Algorithm之PrA:PrA之IP整数规划(包括0-1整数规划)算法经典案例剖析+Matlab编程实现
Algorithm之PrA:PrA之IP整数规划算法经典案例剖析+Matlab编程实现 目录 分枝定界法 整数规划例题 0-1整数规划实例 分枝定界法 对有约束条件的最优化问题(其可行解为有限数)的所 ...
- 小波图像去噪及matlab实例
图像去噪 图像去噪是信号处理的一个经典问题,传统的去噪方法多采用平均或线性方法进行,常用的是维纳滤波,但是去噪效果不太好(维纳滤波在图像复原中的作用). 小波去噪 ...
- TSP问题遗传算法通用Matlab程序
程序一:主程序 %TSP问题(又名:旅行商问题,货郎担问题)遗传算法通用matlab程序 %D是距离矩阵,n为种群个数 %参数a是中国31个城市的坐标 %C为停止代数,遗传到第 C代时程序停止,C的具 ...
- Algorithm之PrA:PrA之nLP非线性规划算法经典案例剖析+Matlab编程实现
Algorithm之PrA:PrA之nLP整数规划算法经典案例剖析+Matlab编程实现 目录 有约束非线性规划案例分析 1.投资决策问题 2.利用Matlab实现求解下列非线性规划 无约束极值问题 ...
- c语言编程 输入螺旋数组,C语言 经典题目螺旋矩阵 实例详解
C语言 经典题目螺旋矩阵 实例详解 C语言 经典题目螺旋矩阵 //N阶螺旋矩阵 #include #include int main() { int N,i,j,n,num=1; int a[10][ ...
- bp神经网络matlab实例蚊子,bp神经网络matlab实例
bp神经网络matlab实例 采用 Matlab 工具箱函数建立神经网络,对一些基本的神经网络参数进行了说明,深入了解参考 Matlab 帮助文档.实例一% 例 1 采用动量梯度下降算法训练 BP 网 ...
- matlab指派问题求法,MATLAB实例:Munkres指派算法
MATLAB实例:Munkres指派算法 1. 指派问题陈述 指派问题涉及将机器分配给任务,将工人分配给工作,将足球运动员分配给职位等.目标是确定最佳分配,例如,使总成本最小化或使团队效率最大化.指派 ...
- matlab中二维散点图,MATLAB实例:二维散点图
MATLAB实例:二维散点图 用MATLAB实现简单的散点图的绘制,可以自行设置点的形状与颜色,可以去掉坐标轴边框. 数据来源:MATLAB高斯混合数据的生成 将二维数据保存为gauss.txt. 1 ...
最新文章
- linux-glibc内存管理小结2(内存相关系统调用的实现)
- coreutils-5.0中几个命令的执行过程
- python保存两位小数的几种方法,python2保留小数
- ubuntu安装pytorch镜像修改及下载
- 笑说设计模式-小白逃课被点名
- cocoapods安装速度慢,CDN: trunk Repo update failed等问题
- 经典神经网络 -- MobileNet : 设计原理与pytorch实现
- XP系统优化超简单实用版
- Kconfig 基本笔录
- 圣诞表白html,圣诞节表白,最浪漫的表白方式
- 浙江大学2020计算机考研复试线,浙江大学2020考研复试分数线已公布
- hdu 2665 Kth number(划分树模板)
- FME将用SHP数据对栅格影像数据进行裁剪
- linux大页卸载失败,Linux下CUDA卸载不完全与重装失败
- 极其简单的响应式的模块化布局、看板布局 js 工具
- 插值与拟合 (二) : 曲线拟合的线性最小二乘法
- SpringBoot整合thymeleaf及常用th:标签使用方法
- 网络I/O与磁盘I/O
- 小型企业网络设计与规划
- 据说这是北大教师孔庆东的韩国游记