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

来源:互联网 发布:四物汤 知乎 编辑:程序博客网 时间:2024/04/29 04:55
 

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的类中,它定义为:

 
class CBobsMap
{          
      
private:
               
   //保存地图用的存储器 (一个2维整型数组)
    static const int map[MAP_HEIGHT][MAP_WIDTH]; 
    static const int m_iMapWidth;   //地图的宽度  
    static const int m_iMapHeight;  //地图的高度
   
   //起始点在数组中的下标       
    static const int m_iStartX;   
    static const int m_iStartY;             
      
   //终点的数组下标      
    static const int m_iEndX;             
    static const int m_iEndY;          

public:             
   //你可以利用这一数组作为 Bob 存储器,如果需要的话
    int memory[MAP_HEIGHT][MAP_WIDTH];  
  
    CBobsMap()
    {
      ResetMemory();
    }
            
   //利用一个字符串来记录Bob行进的方向,其中每一个字符代表
   //Bob所走的一步;检查Bob离开出口还有多远;
   //返回一个与到达出口距离成正比的适应性分数
    double TestRoute(const vector &vecPath,
                     CBobsMap     &memory);            
                            
   //Render函数利用Windows GDI在一个给定的surface上显示地图
    void Render(const int    cxClient,
                const int    cyClient,
                HDC          surface);

   //画出能够存放于存储器中的不管什么样的路径
    void MemoryRender(const int cxClient,
                      const int cyClient.
                      HDC       surface);
    void ResetMemory();
       
};
  

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

再有,不要因为理解不了这个类的任何一点而操心。我们下面马上就会开始讨论有关的每一件事情的。

原创粉丝点击