遗传算法入门(连载之七)

2024-06-10 14:08

本文主要是介绍遗传算法入门(连载之七),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

    最近在学习有关遗传算法和神经网络方面的知识,网上查看了很多这方面的秘笈,只怪小生天生愚钝、才疏学浅,不能很好的领悟秘笈中的真谛,往往被弄得晕头转向、不知所措快哭了委屈。直到有一天无意中看到了博主zzwu写的有关这方面的文章,初读之,如温旧习;渐深入,觉甚好;遂一气呵成,犹如拨云见日、茅塞顿开。余甚怕在茫茫Internet中再无机会拜读之,遂收藏于此,以便众人观之,绝无其他不良用途。在此对博主再次深表感谢。

博文转自:http://blog.csdn.net/zzwu/article/details/561626





(连载之七)
.
扎自<游戏编程中的人工智能技术>第三章
.
 清华大学出版社
.

3.4.2 Epoch (时代)
         遗传算法类中最烩灵人口的内容就是 Epoch()方法。这就是我们前面3.3节讲过的遗传算法的那个循环。它是这个类的工作部门(workhorse)。这一方法与所有工作或多或少都有连系。下面就让我们来更近距离地考察它 ...  void CgaBob::epoch()  {  UpdateFitnessScores();  
在每一个 epoch 循环内所要做的第一件事情,就是测试染色体群中每一个成员的适应性分数。 UpdateFitnessScores() 是用来对每个基因组的二进制染色体编码进行译码的函数,而由它再把译码所得到的一系列结果,也就是由代表东、南、西、北四个方向的整数,发送给 CBobsMap::TestRoute 。后者检查Bob在地图中游走了多远,并根据Bob离开出口的最终距离,返回一个相应的适应性分数。让我通过很少几行源码来告诉你怎样计算Bob的适应性分数:    int DiffX = abs(posX - m_iEndX);  int DiffY = abs(posY - m_iEndY); 
      这里,DiffX和DiffY 就是Bob所在格子相对于迷宫出口的水平和垂直偏离值。试考察图 3.6 的例子。灰色小格代表Bob通过迷宫的路程,上面写着B的小格是他最终所到达的地方。在这一位置上,Diffx = 3,而 DiffY = 0。
    return 1/(double)(DiffX+DiffY+1);    上面一行程序就是计算Bob的适应性分数,它把DiffX,DiffY这两个数字加起来,然后求倒数。DiffX,DiffY的和中还加了一个1,这是为了避免分母出现0的错误。如果Bob到达出口,DiffX+DiffY=0. UpdateFitnessScores 也保持对每一代适应性分数最高的基因组以及所有与基因组相关的适应性分数的跟踪。这些数值在执行赌轮选择要使用。

图 3.6 Bob尝试寻找迷宫出口

      这最后一行式子就是计算 Bob 的适应性分数。它把 DiffX与DiffY 两个数字加起来然后求倒数。DiffX与DiffY的和数中还加了一个1,这是为了确保除法不会出现一个分母为零的错误,如果 Bob到达出口,Diffx + DiffY = 0。

     UpdateFitnessScores 也保持对每一代里适应分最高的基因组、以及与所有基因组相关的适应性分数的跟踪。这些数值在执行轮盘赌选择时需要使用。到此,你已经知道了函数 UpdateFitnessScores() 所做的全部工作,让我们回到 Epoch 函数的讨论 ...

     由于在每一个Epoch中都需要创建一个新的基因组群,因此,当它们在创建出来时(每次2个基因组),我们需要寻找一些地方来保存它们。

   //现在创建一个新的群体

   int NewBabies = 0;   

  //为婴儿基因组创建存储器  

   vector<SGenome> vecBabyGenomes;

现在继续讨论遗传算法循环中所处理的各种事务。

   while (NewBabies < m_iPopSize)    

   {

    //用轮盘赌法选择 2 个上辈(parents)

     SGenome mum = RouletteWheelSelection();   

     SGenome dad = RouletteWheelSelection();

    在每次迭代过程中,我们需要选择 2 个基因组来作为 2 个新生婴儿的染色体的上辈。我今后常喜欢把这2个上辈分别称为 dad (父亲)和 mum (母亲)因为他们将来就是要生孩子的)。你应该回忆得起来,一个基因组的适应性愈强,则由轮盘赌方法选择作为父母的几率也愈大。

   //杂交操作    

     SGenome baby1, baby2; 

     Crossover(mum.vecBits ,dad.vecBits, baby1.vecBits, baby2.vecBits);

    以上2行的工作是:创建 2 个空白基因组,这就是2个婴儿;它们与所选的上辈一起传递给杂交函数Crossover() 。这一函数执行了杂交(需要依赖于所设杂交率m_dCrossoverRate来进行),并把新的染色体的2进制位串存放到2个新生婴儿 baby1和baby2之中。

   // 变异操作  

    Mutate(baby1.vecBits);  

    Mutate(baby2.vecBits);

    以上这 2 步是对婴儿实行突变!这听起来可怕,但这对他们是有利的。一个婴儿的位的突变概率依赖于所选的参数 m_dMutationRate(突变率)。

   // 把2个新生因个婴儿加入新群体 

    vecBabyGenomes.push_back(baby1); 

    vecBabyGenomes.push_back(baby2); 

    NewBabies += 2; 

  }

    这 2 个新生后代最终要加入到新的群体中,这样就完成了一次 Loop 的迭代过程。这一过程需要不断重复,直到创建出来的后代总量和初始群体的大小相同。

   // 把所有婴儿复制到初始群体 

    m_vecGenomes = vecBabyGenomes; 

   // 代的计数加1 

   ++m_iGeneration; 

 }

    这里,原有的那个群体由新生一代所组成的群体来代替,并把代的计数器加1,以跟踪当前的代。就是这么一些了!呵呵,不难吧?

    这一 Epoch函数将无止境地重复,直到染色体收敛到了一个解,或到用户要求停止时为止。下面我将会向你显示上述各种操作(算子)的代码,但在此首先让我们来聊聊,应该如何确定使用的参数值。

-连载7完- 

这篇关于遗传算法入门(连载之七)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1048377

相关文章

C++必修:模版的入门到实践

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:C++学习 贝蒂的主页:Betty’s blog 1. 泛型编程 首先让我们来思考一个问题,如何实现一个交换函数? void swap(int& x, int& y){int tmp = x;x = y;y = tmp;} 相信大家很快就能写出上面这段代码,但是如果要求这个交换函数支持字符型

零基础STM32单片机编程入门(一)初识STM32单片机

文章目录 一.概要二.单片机型号命名规则三.STM32F103系统架构四.STM32F103C8T6单片机启动流程五.STM32F103C8T6单片机主要外设资源六.编程过程中芯片数据手册的作用1.单片机外设资源情况2.STM32单片机内部框图3.STM32单片机管脚图4.STM32单片机每个管脚可配功能5.单片机功耗数据6.FALSH编程时间,擦写次数7.I/O高低电平电压表格8.外设接口

ps基础入门

1.基础      1.1新建文件      1.2创建指定形状      1.4移动工具          1.41移动画布中的任意元素          1.42移动画布          1.43修改画布大小          1.44修改图像大小      1.5框选工具      1.6矩形工具      1.7图层          1.71图层颜色修改          1

C++入门01

1、.h和.cpp 源文件 (.cpp)源文件是C++程序的实际实现代码文件,其中包含了具体的函数和类的定义、实现以及其他相关的代码。主要特点如下:实现代码: 源文件中包含了函数、类的具体实现代码,用于实现程序的功能。编译单元: 源文件通常是一个编译单元,即单独编译的基本单位。每个源文件都会经过编译器的处理,生成对应的目标文件。包含头文件: 源文件可以通过#include指令引入头文件,以使

LVGL快速入门笔记

目录 一、基础知识 1. 基础对象(lv_obj) 2. 基础对象的大小(size) 3. 基础对象的位置(position) 3.1 直接设置方式 3.2 参照父对象对齐 3.3 获取位置 4. 基础对象的盒子模型(border-box) 5. 基础对象的样式(styles) 5.1 样式的状态和部分 5.1.1 对象可以处于以下状态States的组合: 5.1.2 对象

C语言入门系列:探秘二级指针与多级指针的奇妙世界

文章目录 一,指针的回忆杀1,指针的概念2,指针的声明和赋值3,指针的使用3.1 直接给指针变量赋值3.2 通过*运算符读写指针指向的内存3.2.1 读3.2.2 写 二,二级指针详解1,定义2,示例说明3,二级指针与一级指针、普通变量的关系3.1,与一级指针的关系3.2,与普通变量的关系,示例说明 4,二级指针的常见用途5,二级指针扩展到多级指针 小结 C语言的学习之旅中,二级

打造坚固的SSH防护网:端口敲门入门指南

欢迎来到我的博客,代码的世界里,每一行都是一个故事 🎏:你只管努力,剩下的交给时间 🏠 :小破站 打造坚固的SSH防护网:端口敲门入门指南 前言什么是端口敲门端口敲门的优点1. 增强安全性2. 动态防火墙规则3. 隐匿服务4. 改善日志管理5. 灵活性和兼容性6. 低资源消耗7. 防御暴力破解和扫描8. 便于合法用户访问9. 适用于不同类型的服务 端口敲

好书推荐《深度学习入门 基于Python的理论与实现》

如果你对Python有一定的了解,想对深度学习的基本概念和工作原理有一个透彻的理解,想利用Python编写出简单的深度学习程序,那么这本书绝对是最佳的入门教程,理由如下:     (1)撰写者是一名日本普通的AI工作者,主要记录了他在深度学习中的笔记,这本书站在学习者的角度考虑,秉承“解剖”深度学习的底层技术,不使用任何现有的深度学习框架、尽可能仅使用基本的数学知识和Python库。从零创建一个

手把手教你入门vue+springboot开发(五)--docker部署

文章目录 前言一、前端打包二、后端打包三、docker运行总结 前言 前面我们重点介绍了vue+springboot前后端分离开发的过程,本篇我们结合docker容器来研究一下打包部署过程。 一、前端打包 在VSCode的命令行中输入npm run build可以打包前端代码,出现下图提示表示打包完成。 打包成功后会在前端工程目录生成dist目录,如下图所示: 把

CALayer入门

iOS开发UI篇—CALayer简介 一、简单介绍 在iOS中,你能看得见摸得着的东西基本上都是UIView,比如一个按钮、一个文本标签、一个文本输入框、一个图标等等,这些都是UIView。 其实UIView之所以能显示在屏幕上,完全是因为它内部的一个图层,在创建UIView对象时,UIView内部会自动创建一个图层(即CALayer对象),通过UIView的layer属性可