热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

遗传算法matlab_三分钟学会遗传算法

遗传算法此节介绍最著名的遗传算法(GA)。遗传算法属于进化算法,基本思想是取自“物竞天泽、适者生存”的进化法则。简单来说,遗传算法就是将问题编码成为染色
3bd4a351e7ea6608d1285258bfe4dc22.png

遗传算法

此节介绍最著名的遗传算法(GA)。遗传算法属于进化算法,基本思想是取自“物竞天泽、适者生存”的进化法则。简单来说,遗传算法就是将问题编码成为染色体,然后经过不断选择、交叉、变异等操作来更新染色体的编码并进行迭代,每次迭代保留上一代好的染色体,丢弃差的染色体,最终达到满足目标的最终染色体。整个流程由下图构成(手写,见谅 -_-!!)

337b02735fe65b0704da0728ad67eabd.png

流程图

步骤由以下几步构成:

编码(coding)——首先初始化及编码。在此步,根据问题或者目标函数(objective function)构成解数据(solutions),在遗传算法中,该解数据就被称为染色体(chromosome)。值得一提的是,遗传算法为多解(population based)算法,所以会有多条染色体。初始化中会随机生成N条染色体,, 这里表示染色体包含了n条。其中 ,这里表示第i条染色体由d维数值构成。GA会以这个N个数据作为初始点开始进行进化。

评估适应度(evaluate fitness)——这一步用染色体来进行目标函数运算,染色体的好坏将被指明。

选择(selection)——从当前染色体中挑选出优良的个体,以一定概率使他们成为父代进行交叉或者变异操作,他们的优秀基因后代得到保留。物竞天择这里得以体现。

交叉(crossover)——父代的两个两个染色体,通过互换染色体构成新的染色体。例如下图,父亲母亲各提供两个基因给我。这样我既保留了父母的基于,同时又有自己的特性。

a0a9d620c943fce0dc8bf927e4e3106a.png

交叉

变异(mutation)——以一定概率使基因发生突变。该算子一般以较低概率发生。如下图所示:

7f74679213ac5278179ffafb8cd93784.png

变异

下面我们将一步一步为各位呈现如何用matlab编写一个简单的GA算法。

本问题为实数最小化minimization问题。我们需要在解空间内找到最小值或近似最小值,此处我们使用sphere函数作为目标函数(读者可以自行修改为其他的目标函数)。

e22d134875c1532ac861cc7a386b0d63.png

sphere function

  • 初始化:在这一步中,我们将在给定问题空间内生成随机解,代码如下:

% %% 初始化% % 输入:chromes_size,dim维数,lb下界,ub上界% % 输出:chromes新种群function chromes=init_chromes(chromes_size,dim,lb,ub) % 上下界中随机生成染色体 chromes = rand(chromes_size,dim)*(ub-lb)+lb;end

  • 选择:选择是从当前代中挑选优秀的染色体保留以繁殖下一代。我们这里采取的方法是俄罗斯轮盘选择方式。谁的解优,谁获得选中的概率越高。首先,我们需要先求出各染色体的fitness倒数。
  • ,然后求出各染色体的比重,比重越大,被保留机会越大。。代码如下:

%% 选择%俄罗斯轮盘赌function [newchromes,newfitness] = selection(chromes,fitness) weights = 1./fitness; % fitness倒数 totalfit=sum(weights); % 累加所有weights totalf = weights./totalfit; %求出各染色体比重 index = []; for i = 1:size(chromes,1) % 循环选出较优染色体 pick = rand; while pick == 0 pick = rand; end for j = 1:size(chromes,1) pick = pick - totalf(j); if pick<0 index = [index j]; break end end end newchromes =chromes(index,:); newfitness = fitness(index);end

  • 交叉:此步会随机选取两个选择过后的染色体作为父代,从两个染色体中各截取一部分基因生成新的染色体,代码如下:

%% 交叉function newchromes = crossover(chromes,pc) % 生成一个新的解 newchromes = ones(size(chromes)); for i = 1:size(chromes,1) % 随机选取两个染色体 parents=randperm(10,2); %随机选取一个位置 pos = round(rand*size(chromes,2)); if(rand变异:以一各小概率生成随机变异一个gene,代码如下:

% 变异function newchromes= muatation(chromes,pm,lb,ub) for i = 1:size(chromes,1) newchromes(i,:) = chromes(i,:); if (rand主函数,首先初始化各参数,然后进行迭代,当满足终止条件停止:

% 清除workspace,清屏clearclc % 染色体数量chromes_size = 20;% 问题维数dim = 10;% 交叉概率pc =0.9;% 变异概率pm = 0.2;% 问题上下边界lb = -1;ub = 1;% 循环次数maxiter = 1000;% 目标方程namefunc= &#39;objfun&#39;;fd = str2func(namefunc);​% 初始化chromes = init_chromes(chromes_size,dim,lb,ub);% 求个染色体fitness for i = 1:chromes_size fitness(i)=feval(fd,chromes(i,:)); end% 求出最优解 [bestfitness bestindex]=min(fitness); bestchrome = chromes(bestindex,:); % 主循环for iter=1:maxiter % 选择 [chromes,newfitness] = selection(chromes,fitness); % 交叉 chromes= crossover(chromes,pc); % 变异 chromes= muatation(chromes,pm,lb,ub); % 更新最优 for i = 1:chromes_size fitness(i)=feval(fd,chromes(i,:)); if fitness(i)

运行之后生成一个fitness下降曲线,如下图:

2cf2ce7dc95afd559e8617085616c4bd.png

适应度下降曲线

遗传算法大大提升了寻优问题的通用性,因为遗传算法属于stochastic algorithm,不再是Deterministic algorithm(如果各位对此感兴趣,请留言,我可进一步讲解)。

但是有些显著缺陷还是明显影响该算法效率,主要问题如下:

premature,过早收敛,极易陷入局部最优解初始点对算法结果影响巨大,初始点好的解效果好,反之亦然。

下一节,将介绍群智能算法的代表之作——粒子群寻优算法。

如有任何疑问请留言,欢迎评论交流,创作不易,请勿抄袭,请收藏,关注,转发~



推荐阅读
  • Ihavetwomethodsofgeneratingmdistinctrandomnumbersintherange[0..n-1]我有两种方法在范围[0.n-1]中生 ... [详细]
  • 重要知识点有:函数参数默许值、盈余参数、扩大运算符、new.target属性、块级函数、箭头函数以及尾挪用优化《深切明白ES6》笔记目次函数的默许参数在ES5中,我们给函数传参数, ... [详细]
  • 本文总结了JavaScript的核心知识点和实用技巧,涵盖了变量声明、DOM操作、事件处理等重要方面。例如,通过`event.srcElement`获取触发事件的元素,并使用`alert`显示其HTML结构;利用`innerText`和`innerHTML`属性分别设置和获取文本内容及HTML内容。此外,还介绍了如何在表单中动态生成和操作``元素,以便更好地处理用户输入。这些技巧对于提升前端开发效率和代码质量具有重要意义。 ... [详细]
  • 在多线程并发环境中,普通变量的操作往往是线程不安全的。本文通过一个简单的例子,展示了如何使用 AtomicInteger 类及其核心的 CAS 无锁算法来保证线程安全。 ... [详细]
  • 本地存储组件实现对IE低版本浏览器的兼容性支持 ... [详细]
  • 本文提出了一种基于栈结构的高效四则运算表达式求值方法。该方法能够处理包含加、减、乘、除运算符以及十进制整数和小括号的算术表达式。通过定义和实现栈的基本操作,如入栈、出栈和判空等,算法能够准确地解析并计算输入的表达式,最终输出其计算结果。此方法不仅提高了计算效率,还增强了对复杂表达式的处理能力。 ... [详细]
  • 如何使用 `org.eclipse.rdf4j.query.impl.MapBindingSet.getValue()` 方法及其代码示例详解 ... [详细]
  • 在《Linux高性能服务器编程》一书中,第3.2节深入探讨了TCP报头的结构与功能。TCP报头是每个TCP数据段中不可或缺的部分,它不仅包含了源端口和目的端口的信息,还负责管理TCP连接的状态和控制。本节内容详尽地解析了TCP报头的各项字段及其作用,为读者提供了深入理解TCP协议的基础。 ... [详细]
  • 本指南从零开始介绍Scala编程语言的基础知识,重点讲解了Scala解释器REPL(读取-求值-打印-循环)的使用方法。REPL是Scala开发中的重要工具,能够帮助初学者快速理解和实践Scala的基本语法和特性。通过详细的示例和练习,读者将能够熟练掌握Scala的基础概念和编程技巧。 ... [详细]
  • 本文深入探讨了Ajax的工作机制及其在现代Web开发中的应用。Ajax作为一种异步通信技术,改变了传统的客户端与服务器直接交互的模式。通过引入Ajax,客户端与服务器之间的通信变得更加高效和灵活。文章详细分析了Ajax的核心原理,包括XMLHttpRequest对象的使用、数据传输格式(如JSON和XML)以及事件处理机制。此外,还介绍了Ajax在提升用户体验、实现动态页面更新等方面的具体应用,并讨论了其在当前Web开发中的重要性和未来发展趋势。 ... [详细]
  • 本文探讨了如何利用 jQuery 的 JSONP 技术实现跨域调用外部 Web 服务。通过详细解析 JSONP 的工作原理及其在 jQuery 中的应用,本文提供了实用的代码示例和最佳实践,帮助开发者解决跨域请求中的常见问题。 ... [详细]
  • async/await 是现代 JavaScript 中非常强大的异步编程工具,可以极大地简化异步代码的编写。本文将详细介绍 async 和 await 的用法及其背后的原理。 ... [详细]
  • 深入解析 Lifecycle 的实现原理
    本文将详细介绍 Android Jetpack 中 Lifecycle 组件的实现原理,帮助开发者更好地理解和使用 Lifecycle,避免常见的内存泄漏问题。 ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • 如何在Java中使用DButils类
    这期内容当中小编将会给大家带来有关如何在Java中使用DButils类,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。D ... [详细]
author-avatar
张嫱的小屋_133
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有