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

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

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

数论入门整理(updating)

一、gcd lcm 基础中的基础,一般用来处理计算第一步什么的,分数化简之类。 LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } <pre name="code" class="cpp">LL lcm(LL a, LL b){LL c = gcd(a, b);return a / c * b;} 例题:

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

【IPV6从入门到起飞】5-1 IPV6+Home Assistant(搭建基本环境)

【IPV6从入门到起飞】5-1 IPV6+Home Assistant #搭建基本环境 1 背景2 docker下载 hass3 创建容器4 浏览器访问 hass5 手机APP远程访问hass6 更多玩法 1 背景 既然电脑可以IPV6入站,手机流量可以访问IPV6网络的服务,为什么不在电脑搭建Home Assistant(hass),来控制你的设备呢?@智能家居 @万物互联

poj 2104 and hdu 2665 划分树模板入门题

题意: 给一个数组n(1e5)个数,给一个范围(fr, to, k),求这个范围中第k大的数。 解析: 划分树入门。 bing神的模板。 坑爹的地方是把-l 看成了-1........ 一直re。 代码: poj 2104: #include <iostream>#include <cstdio>#include <cstdlib>#include <al

MySQL-CRUD入门1

文章目录 认识配置文件client节点mysql节点mysqld节点 数据的添加(Create)添加一行数据添加多行数据两种添加数据的效率对比 数据的查询(Retrieve)全列查询指定列查询查询中带有表达式关于字面量关于as重命名 临时表引入distinct去重order by 排序关于NULL 认识配置文件 在我们的MySQL服务安装好了之后, 会有一个配置文件, 也就

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

C语言指针入门 《C语言非常道》

C语言指针入门 《C语言非常道》 作为一个程序员,我接触 C 语言有十年了。有的朋友让我推荐 C 语言的参考书,我不敢乱推荐,尤其是国内作者写的书,往往七拼八凑,漏洞百出。 但是,李忠老师的《C语言非常道》值得一读。对了,李老师有个官网,网址是: 李忠老师官网 最棒的是,有配套的教学视频,可以试看。 试看点这里 接下来言归正传,讲解指针。以下内容很多都参考了李忠老师的《C语言非

MySQL入门到精通

一、创建数据库 CREATE DATABASE 数据库名称; 如果数据库存在,则会提示报错。 二、选择数据库 USE 数据库名称; 三、创建数据表 CREATE TABLE 数据表名称; 四、MySQL数据类型 MySQL支持多种类型,大致可以分为三类:数值、日期/时间和字符串类型 4.1 数值类型 数值类型 类型大小用途INT4Bytes整数值FLOAT4By

【QT】基础入门学习

文章目录 浅析Qt应用程序的主函数使用qDebug()函数常用快捷键Qt 编码风格信号槽连接模型实现方案 信号和槽的工作机制Qt对象树机制 浅析Qt应用程序的主函数 #include "mywindow.h"#include <QApplication>// 程序的入口int main(int argc, char *argv[]){// argc是命令行参数个数,argv是