题目:

定义一个二元函数,

。用遗传算法求全局最大值;

遗传算法简单介绍与MATLAB实现(二)

引入题目一

上一篇文章中我们简单的介绍了一了一下遗传算法,其中提到了多元函数f=f(x,y)f=f(x,y),所以在这里我们就定义一个二元函数,作为第一个练手的程序。

遗传算法MATLAB程序

设定参数

首先我们要确定一系列参数

N = 100; %种群内个体数目
N_chrom = 2; %染色体节点数
iter = 2000; %迭代次数
mut = 0.2; %突变概率
acr = 0.2; %交叉概率

其中突变概率指的是某个个体的染色体发生突变的概率。因为实际中并不可能每一个个体都会发生突变,而是存在一定的概率,因此我们在这里定义每一个个体突变发生的概率为0.2。

同理,交叉概率指的就是某个个体与另一个个体发生染色体交叉的概率。

迭代次数指的是整个种群迭代2000多次。

一般来说,并不是突变概率、交叉概率越小或者越大越好。比如说突变概率特别高的话,会让整个种群的最优适应度飘忽不定。如果特别小的话,会让种群迭代的速度特别慢,很难找到最优适应度。这里取0.2是我经过多次试验以后,觉得0.2是一个比较稳定不会乱飘且适应度收敛也不错的一个值。

迭代次数也同理,如果一个特别简单的模型去求最优解,可能五六次迭代就求出来了,那么2000次迭代纯属浪费时间。但是如果是一个特别复杂的模型,那么2000次迭代就有可能不够。具体迭代次数可以自己灵活决定。

chrom_range = [-10 -10; 10 10];%每个节点的值的区间
chrom = zeros(N, N_chrom);%存放染色体的矩阵
fitness = zeros(N, 1);%存放染色体的适应度
fitness_ave = zeros(1, iter);%存放每一代的平均适应度
fitness_best = zeros(1, iter);%存放每一代的最优适应度
chrom_best = zeros(1, N_chrom+1);%存放当前代的最优染色体与适应度

其中的chrom_range指的是每个节点值的区间。在我们的这个模型中,x∈[−10,10],y∈[−10,10]x∈[−10,10],y∈[−10,10]。第一行放的是两个变量的区间下限,第二行放的是区间上限。

chrom和fitness两个矩阵你们可以自己理解一下为什么这样子写。

fitness_ave用来存放每一代的平均适应度,主要是用来最后画图,观察种群在每一次迭代中适应度的变化情况。fitness_best同理。

chrom_best用来存放最优适应度对应的最优染色体与适应度,可以回想一下上一章染色体变异中需要最优适应度,优胜劣汰中需要最优染色体,这个矩阵作用就是如此。

初始化种群

接下来开始初始化参数

chrom = Initialize(N, N_chrom, chrom_range); %初始化染色体
fitness = CalFitness(chrom, N, N_chrom); %计算适应度
chrom_best = FindBest(chrom, fitness, N_chrom); %寻找最优染色体
fitness_best(1) = chrom_best(end); %将当前最优存入矩阵当中
fitness_ave(1) = CalAveFitness(fitness); %将当前平均适应度存入矩阵当中

Initialize函数是我自定义的一个函数,用于初始化染色体。具体操作就是用一个for循环对每个个体的染色体进行随机赋值,并利用chrom_range将其限定在变量规定的区间之内。

function chrom_new = Initialize(N, N_chrom, chrom_range)
chrom_new = rand(N, N_chrom);
for i = 1:N_chrom %每一列乘上范围
chrom_new(:, i) = chrom_new(:, i)*(chrom_range(2, i)-chrom_range(1, i))+chrom_range(1, i);
end

CalFitness函数则是计算chrom内每个个体的适应度,并将其保存在fitness中。这个函数很重要,请着重理解这个函数的用法。

function fitness = CalFitness(chrom, N, N_chrom)
fitness = zeros(N, 1);
%开始计算适应度
for i = 1:N
x = chrom(i, 1);
y = chrom(i, 2);
fitness(i) = sin(x)+cos(y)+0.1*x+0.1*y;
end

FindBest函数寻找出当前种群中的最优染色体,并将其保存在chrom_best。

function chrom_best = FindBest(chrom, fitness, N_chrom)
chrom_best = zeros(1, N_chrom+1);
[maxNum, maxCorr] = max(fitness);
chrom_best(1:N_chrom) =chrom(maxCorr, :);
chrom_best(end) = maxNum;

CalAveFitness函数用于计算当前种群中的平均适应度。

function fitness_ave = CalAveFitness(fitness)
[N ,~] = size(fitness);
fitness_ave = sum(fitness)/N;

迭代开始

初始化完以后就开始迭代,为了保证迭代次数和iter一致,这里我们就直接令t从2开始迭代。

再一次迭代过程中,一个种群执行操作顺序为:染色体变异,染色体交叉,计算适应度,寻找最优染色体,替换当前存储的最优染色体,优胜劣汰。

需要注意的是这里替换当前最优染色体。因为我们将这个种群的个个个体的染色体重新变异、交叉过了,所以最优染色体也会变化。但是这一代的最优染色体不一定比上一次迭代的最优染色体好,所以需要判定是否将最优染色体这个位置给换掉。

因此迭代过程中的代码为

for t = 2:iter
chrom = MutChrom(chrom, mut, N, N_chrom, chrom_range, t, iter); %变异
chrom = AcrChrom(chrom, acr, N, N_chrom); %交叉
fitness = CalFitness(chrom, N, N_chrom); %计算适应度
chrom_best_temp = FindBest(chrom, fitness, N_chrom); %寻找最优染色体
if chrom_best_temp(end)>chrom_best(end) %替换掉当前储存的最优
chrom_best = chrom_best_tem

其中MutChrom函数用来对种群进行染色体变异操作。这里面的操作比较多,主要可以分为三步:

判断某节点是否变异;

判断变异是增加还是减少;

判断变异后的值是否越界。

用流程图表示为下图所示。

下面代码表示为

function chrom_new = MutChrom(chrom, mut, N, N_chrom, chrom_range, t, iter)
for i = 1:N
for j = 1:N_chrom
mut_rand = rand; %是否变异
if mut_rand <=mut
mut_pm = rand; %增加还是减少
mut_num = rand*(1-t/iter)^2;
if mut_pm<=0.5
chrom(i, j)= chrom(i, j)*(1-mut_num);
else
chrom(i, j)= chrom(i, j)*(1+mut_num);
end
chrom(i, j) = IfOut(chrom(i, j), chrom_range(:, j)); %检验是否越界
end
end
end
chrom_new = chrom;

越界函数IfOut函数我们看它是左越界还是右越界,如果是左越界,则让节点值等于区间下限;如果是右越界,则让节点值等于区间上限。

function c_new = IfOut(c, range)
if c<range(1) || c>range(2)
if abs(c-range(1))<abs(c-range(2))
c_new = range(1);
else
c_new = range(2);
end
else
c_new = c;
end

AcrChrom函数是染色体交叉函数。逻辑相较染色体变异来说比较简单,大致可以分为以下几点

判断该节点是否交叉;

随机寻找一个与其交叉的节点;

对两个节点进行交叉。

function chrom_new = AcrChrom(chrom, acr, N, N_chrom)
for i = 1:N
acr_rand = rand;
if acr_rand<acr %如果交叉
acr_chrom = floor((N-1)*rand+1); %要交叉的染色体
acr_node = floor((N_chrom-1)*rand+1); %要交叉的节点
%交叉开始
temp = chrom(i, acr_node);
chrom(i, acr_node) = chrom(acr_chrom, acr_node);
chrom(acr_chrom, acr_node) = temp;
end
end
chrom_new = chrom;

ReplaceWorse函数则是优胜劣汰这个过程,将种群中的最劣染色体替换掉。这里是直接用最优染色体替换,并且替换掉的是最后几个染色体,目的是加快收敛速度,但可能会陷入局部最优解。

function [chrom_new, fitness_new] = ReplaceWorse(chrom, chrom_best, fitness)
max_num = max(fitness);
min_num = min(fitness);
limit = (max_num-min_num)*0.2+min_num;
replace_corr = fitness<limit;
replace_num = sum(replace_corr);
chrom(replace_corr, :) = ones(replace_num, 1)*chrom_best(1:end-1);
fitness(replace_corr) = ones(replace_num, 1)*chrom_best(end);
chrom_new = chrom;
fitness_new = fitness;
end

输出遗传算法迭代图

在这里我们只输出一个标准图为迭代过程中种群的平均适应度与最优适应度。

在之前我们已经得到了每一代的平均适应度fitness_ave与最优适应度fitness_best,所以可以直接输出图像

figure(1)
plot(1:iter, fitness_ave, 'r', 1:iter, fitness_best, 'b')
grid on
legend('平均适应度', '最优适应度')

之后我们还想要看得出的点在实际图像中哪个位置,所以我们可以增加一个用来作图的函数PlotModel

function y = PlotModel(chrom)
x = chrom(1);
y = chrom(2);
z = chrom(3);
figure(2)
scatter3(x, y, z, 'ko')
hold on
[X, Y] = meshgrid(-10:0.1:10);
Z =sin(X)+cos(Y)+0.1*X+0.1*Y;
mesh(X, Y, Z)
y=1;

遗传算法主程序

上面就是所有程序片段,因此把主程序的代码联立起来为

clc, clear, close all
%%基础参数
N = 100; %种群内个体数目
N_chrom = 2; %染色体节点数
iter = 2000; %迭代次数
mut = 0.2; %突变概率
acr = 0.2; %交叉概率
best = 1;
chrom_range = [-10 -10;10 10];%每个节点的值的区间
chrom = zeros(N, N_chrom);%存放染色体的矩阵
fitness = zeros(N, 1);%存放染色体的适应度
fitness_ave = zeros(1, iter);%存放每一代的平均适应度
fitness_best = zeros(1, iter);%存放每一代的最优适应度
chrom_best = zeros(1, N_chrom+1);%存放当前代的最优染色体与适应度
%%初始化
chrom = Initialize(N, N_chrom, chrom_range); %初始化染色体
fitness = CalFitness(chrom, N, N_chrom); %计算适应度
chrom_best = FindBest(chrom, fitness, N_chrom); %寻找最优染色体
fitness_best(1) = chrom_best(end); %将当前最优存入矩阵当中
fitness_ave(1) = CalAveFitness(fitness); %将当前平均适应度存入矩阵当中
for t = 2:iter
chrom = MutChrom(chrom, mut, N, N_chrom, chrom_range, t, iter); %变异
chrom = AcrChrom(chrom, acr, N, N_chrom); %交叉
fitness = CalFitness(chrom, N, N_chrom); %计算适应度
chrom_best_temp = FindBest(chrom, fitness, N_chrom); %寻找最优染色体
if chrom_best_temp(end)>chrom_best(end) %替换掉当前储存的最优
chrom_best = chrom_best_temp;
end
%%替换掉最劣
[chrom, fitness] = ReplaceWorse(chrom, chrom_best, fitness);
fitness_best(t) = chrom_best(end); %将当前最优存入矩阵当中
fitness_ave(t) = CalAveFitness(fitness); %将当前平均适应度存入矩阵当中
end
%%作图
figure(1)
plot(1:iter, fitness_ave, 'r', 1:iter, fitness_best, 'b')
grid on
legend('平均适应度', '最优适应度')
e = PlotModel(chrom_best)
%%输出结果
disp(['最优染色体为', num2str(chrom_best(1:end-1))])
disp(['最优适应度为', num2str(chrom_best(end))])

输出结果

我们运行一下, 可以得到最大点为(7.9541,6.3834)(7.9541,6.3834),最大值为3.4237。

可以做出最大值点在空间中的位置如图所示。证明我们的结论比较正确,起码没有落到周围的极大值的峰上。

原文链接:CSDN-专业IT技术社区-登录

读者想要更加详细理解遗传算法可以看看这个:

炫云:遗传算法的实现过程炫云:遗传算法(附Python实现)​zhuanlan.zhihu.com

炫云:遗传算法(附Python实现)​zhuanlan.zhihu.com

遗传算法matlab_遗传算法简单介绍与MATLAB实现相关推荐

  1. RBF神经网络简单介绍与MATLAB实现

    文章目录 RBF的直观介绍 1 RBF是一种两层的网络 2 RBF的隐层是一种非线性的映射 3 RBF输出层是线性的 4 RBF的基本思想是:将数据转化到高维空间,使其在高维空间线性可分 RBF学习算 ...

  2. matlab与python实现神经网络_Adaline神经网络简单介绍和MATLAB简单实现

    Adaline神经网络 Adaline利用了最小二乘法的思想,相较于感知机神经网络,对于数据的线性可分的要求更低一些,可以允许一些异常数据. 上面描述了迭代求解的过程,但是在 x0(k+1) 这里没看 ...

  3. Adaline神经网络简单介绍和MATLAB简单实现

    Adaline神经网络 Adaline利用了最小二乘法的思想,相较于感知机神经网络,对于数据的线性可分的要求更低一些,可以允许一些异常数据. 上面描述了迭代求解的过程,但是在x0(k+1)x_0(k+ ...

  4. 神经网络之感知器算法简单介绍和MATLAB简单实现

    Perceptron Learning Algorithm 感知机学习算法,在1943年被生物学家MeCulloch和数学家Pitts提出以后,面临一个问题:参数需要依靠人工经验选定,十分麻烦.因此人 ...

  5. 典型数据分析软件的简单介绍(MATLAB篇)

    软件概况 Matlab是MathWorks公司于1982年推出的一套高性能的数值计算和可视化软件.它集数值分析.矩阵运算.信号处理和图形显示于一体,构成了一个方便.界面良好的用户环境.它还包括了Too ...

  6. 牛顿法的简单介绍及Matlab实现

    目录 牛顿法原理简介 使用牛顿法求解一元方程 使用牛顿法求解平面定位问题 参考文献 牛顿法原理简介 牛顿法的原理是利用函数 f ( x ) f(x) f(x) 的泰勒级数的前几项来寻找方程 f ( x ...

  7. 遗传算法的简单介绍以及模式定理的简单证明

    遗传算法   遗传算法(Genetic Algorithm,GA),最早是由美国的John holland在20世纪70年代提出.算法通过模拟达尔文生物进化论的自然选择以及遗传学机理的生物进化过程来搜 ...

  8. 遗传算法matlab_史上最强的MATLAB自学网站,你收藏了吗???

    各位小伙伴可点击此处,即可进入到优化算法交流地官方账号主页(推荐),谨防上当受骗. hello,大家好!这几天是全国大学生数学建模竞赛的比赛时间,首先预祝各位参赛的同学能够取得好成绩.今天,网上浏览到 ...

  9. 进化计算之遗传算法的简单介绍

    作为一个算法的初学者,最近看了一下计算智能(人工智能的一个重要领域)的相关内容...在这里简单介绍一下进化计算中的遗传算法吧大概吧...这种综述性的暂且看看吧... 遗传算法(Genetic Algo ...

  10. 遗传算法matlab_科学与艺术的融合:遗传算法绘制蒙娜丽莎

    读研究生的时候上了智能控制的课,课上讲了遗传算法.粒子群算法还有模糊控制等等.我对遗传算法非常感兴趣,2018年的时候用MATLAB复现了遗传算法进化蒙娜丽莎,这也是我知乎头像的来源. 本文就来详细的 ...

最新文章

  1. mysql图片路径varchar大小_Mysqlvarchar大小长度问题_MySQL
  2. html ondrop未触发,javascript – TableDnD onDrop事件未触发
  3. android实现模拟自动点击_昆仑通态专题(十三):模拟实现全自动洗衣机系统的设计(案例)...
  4. mysql 分组top_MySQL:如何查询出每个分组中的 top n 条记录?
  5. mysql 保留5位小数_小猿圈分享-MySQL保留几位小数的4种方法
  6. 用MediaPlayer record audio简例
  7. MySQL 两个死锁样例
  8. 5.被动回复用户消息
  9. java jre 1.8_jre1.8官方下载
  10. Java基础——环境变量配置、注释、关键字、标识符
  11. 纪念feedsky彻底成为广告公司
  12. 领导人要读的10本管理学书籍
  13. finebi如何使用mysql_如何利用bi数据分析FineBI配置MySQL
  14. Android 实现adb手机投屏
  15. 蓝牙HC05模块探究-设置AT指令
  16. 钢琴 |《小汤普森简易钢琴教程》第一册
  17. 如果你的网站需要免费的 SVG 插图,一定不要错过 Undraw 这个网站
  18. 蓝桥杯嵌入式史上最全最详细教程教你快速入门
  19. 电磁兼容入门篇之基础知识
  20. 给你的PPT加上美观实用的导航自我介绍ppt模板

热门文章

  1. 【C语言新手】EasyX图形库使用
  2. 网页版bpc电波对时_BPC电波对时app下载|BPC电波对时安卓版下载 v1.04 - 跑跑车安卓网...
  3. Oracle 索引详解(index)
  4. C++ —— 句柄类的实现方式 —— 类实现的隐藏
  5. 编译原理c语言递归下降程序,编译原理(递归下降分析程序)
  6. Java写txt—读txt—清空txt文件
  7. win7鼠标指针主题包_轻松办公之全局鼠标手势软件
  8. 海康服务器找不到网卡驱动,驱动技巧:解决设备管理器中找不到网卡的问题
  9. smart原则_写给中学生:用SMART原则制定寒假计划
  10. XLINUX-FPGA开发-基础篇-数电-门电路