遺傳算法入門(連載之五)

   最近在學習有關遺傳算法和神經網絡方面的知識,網上查看了很多這方面的祕笈,只怪小生天生愚鈍、才疏學淺,不能很好的領悟祕笈中的真諦,往往被弄得暈頭轉向、不知所措快哭了委屈。直到有一天無意中看到了博主zzwu寫的有關這方面的文章,初讀之,如溫舊習;漸深入,覺甚好;遂一氣呵成,猶如撥雲見日、茅塞頓開。餘甚怕在茫茫Internet中再無機會拜讀之,遂收藏於此,以便衆人觀之,絕無其他不良用途。在此對博主再次深表感謝。

博文轉自:http://blog.csdn.net/zzwu/article/details/561622


.

.
(連載之五)
.
扎自<遊戲編程中的人工智能技術>第三章

 清華大學出版社

(本章由zzwu譯)

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。這時循環就會自動結束,因爲你已經找到一個解了,可以喊烏拉了!
...再有,不要因爲理解不了這個類的任何一點而操心。我們下面馬上就會開始討論有關的每一件事情的。

-連載5完-

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章