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

遗传算法入门
(连载之二)
.
扎自<游戏编程中的人工智能技术>第三章 
(美)Mat Buckland 著
吴祖增 沙 鹰 译
清华大学出版社出版

 

 

 

3.4 帮助 Bob 回家( Helping Bob Home )

由于寻找路径问题被看成是游戏人工智能的一块神圣基石,我们下面就来创建一个遗传算法,用在一个非常简单的场景中解决寻找路径问题。为此,我们将创建一个迷宫,它的左边有一入口,右边有一出口,并有一些障碍物散布在其中。然后在出发点放置一个虚拟的人,我们叫他鲍勃(Bob),然后要为他解决如何寻找路径的问题,使他能找到出口,并避免与所有障碍物相碰撞。下面我将说明怎样来产生Bob的染色体的编码,但首先需要解释怎样来表示迷宫...

迷宫是一个2D整数型数组;用0来表示开放的空间,1代表墙壁或障碍物,5是起始点,8是出口。因此,整数数组:

.{ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.
. 1,0,1,0,0,0,0,0,1,1,1,0,0,0,1,
..5,0,0,0,0,0,0,0,1,1,1,0,0,0,1,
..1,0,0,0,1,1,1,0,0,1,0,0,0,0,1,
..1,0,0,0,1,1,1,0,0,0,0,0,1,0,1,
. 1,1,0,0,1,1,1,0,0,0,0,0,1,0,1,
..1,0,0,0,0,1,0,0,0,0,1,1,1,0,1,
..1,0,1,1,0,0,0,1,0,0,0,0,0,0,8,
..1,0,1,1,0,0,0,1,0,0,0,0,0,0,1,
.. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }

在屏幕上看起来将会有下面图3.5的样子:


图 3.5 Bob的迷宫,用红色标出了入口和出口

  作者已把这种地图设计方法封装在一个被称作CBobsMap的类中,它定义为:

...。
.
      由上可以看出,我们只需要以常量的形式来保存地图数组以及起点和终点的坐标就行了。这些数据是在文件 CBobsMap.cpp 中定义的,在光盘上你能找到它的相关的文件夹。除了存储迷宫的数据外,这个Map类也用来记录Bob在迷宫中所走过的路程: memory[][] 。这对遗传算法本身而言不是本质的,但为了显示目的,使你能看到 Bob 怎样在迷宫中漫游,设置一个记录是必需的。这里重要的是成员函数TestRoute(),它需要利用一系列的行进方向来检测 Bob 走了多远。这里我不准备花费时间来列出TestRoute 函数的清单,因为这是十分简单的那种函数,但要列出来却可能需要长长的2页。我们只需要说明一下就行了。给出一个方向向量,它的每个分量能代表向北(North)、向南(South)、向东(East)、向西(West)四个方向之一,让 Bob 按照它在地图中行走, TestRoute 计算 Bob 能到达的最远点的位置,然后返回一个适应性分数,它正比于 Bob 最终位置离出口的距离。他所到达的位置离开出口愈近,奖励给他的适应性分数也愈高。如果他实际已到达了出口,则我们就要向他表示祝贺了,他将得到满分1。这时循环就会自动结束,因为你已经找到一个解了,可以喊乌拉了!
....再有,不要因为理解不了这个类的任何一点而操心。我们下面马上就会开始讨论有关的每一件事情的。

3.4.1为染色体编码
(Ecoding the Chromosome)

          
个染色体必须把小人Bob 的每一个行动编入代码中。Bob的行动仅限为4个方向:
    
             向东(East),向南(South),向西(West),向北(North)
    
故编码后的染色体应该就是代表这4个方向信息的一个字符串。传统的编码方法就是把方
向变换成二进制的代码。四个方向只要2位就够了,例如下表所示的那样:
二进制代码十进制译码代表的方向
000向北
011向南
102向东
113向西

 


这样,如果你得到了一个随机的二进制字符串,你就能将它译码出Bob行动时所遵循的
一系列方向。例如染色体:

                    111110011011101110010101

代表的基因就是:
            11,11,10,01,10,11,10,11,10,01,01,01
			  
当把二进制代码译成十进制时,就成为
            3,3,2,1,2,3,2,3,2,1,1,1

再把这些放进一个表格中,就可以使你相信这是一样的一些概念: 
        
二进制代码十进制译码代表的方向
113West
113West
102East
011South
102East
113West
102East
113West
102East
011South
011South
011South

      到此,你要做的全部就是将Bob置于迷宫的起点,然后告诉他根据这张表所列的方向
一步步地走。如果按某一个方向前进将使Bob碰到墙壁或障碍物,则只需忽略该方向并继
续按下一个方向去走就行了。这样不断下去,直到所有方向用光或Bob到达出口时为止。
   
    如果你想象有几百个这样的随机的染色体,你就能看到它们中的某些可能为Bob译码
出到达出口的一套方向(问题的一个解),但它们中的大多数将是失败的。
   
    遗传算法以随机的2进制串(染色体)作为初始群体,测试它们每一个能让Bob走到
离开出口有多么接近,然后让其中最好的那些来孵化后代,期望它们的子孙中能有比Bob
走得离出口更近一点。这样继续下去,直到找出一个解,或直到Bob绝望地在一个角落里
被粘住不动为止(你将看到,这种情况是可能发生的)。
     
    因此,我们应定义一种结构,其中包含一个2进制位串(染色体),以及一个与该
染色体相联系的适应性分数。我把这个结构称为SGenome结构,它的定义如下:    

正如你能见到的那样,如果你在创建Sgenome对象时把一个整型数作为参数
传递给构造函数,则它就会自动创建一个以此整数为长度的随机2进制位串,
并将其适应性分数初始化为零,这样就把基因组什么都准备好了。

   SGenome结构中不具备怎样为染色体(vecBits)进行译码的知识; 这是需要
由遗传算法类自己来完成的一项任务。现在让我们来快速窥视一下这个类的定义。
我已把它称作CgaBob类
  

由上你可看出,当这个类的一个实例被创建时,构造函数初始化所有的变量,并调用CreateStartPopulation()。

这一短小函数创建了所需数量的基因组群体。每个基因组一开始包含的是一个由随机2进制位串组成的染色体,

其适应性分数则被设置为零。

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值