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

遺傳算法入門
(連載之二)
.
扎自<遊戲編程中的人工智能技術>第三章 
(美)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位就夠了,例如下表所示的那樣:
二進制代碼 十進制譯碼 代表的方向
00 0 向北
01 1 向南
10 2 向東
11 3 向西

 


這樣,如果你得到了一個隨機的二進制字符串,你就能將它譯碼出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

再把這些放進一個表格中,就可以使你相信這是一樣的一些概念: 
        
二進制代碼 十進制譯碼 代表的方向
11 3 West
11 3 West
10 2 East
01 1 South
10 2 East
11 3 West
10 2 East
11 3 West
10 2 East
01 1 South
01 1 South
01 1 South

      到此,你要做的全部就是將Bob置於迷宮的起點,然後告訴他根據這張表所列的方向
一步步地走。如果按某一個方向前進將使Bob碰到牆壁或障礙物,則只需忽略該方向並繼
續按下一個方向去走就行了。這樣不斷下去,直到所有方向用光或Bob到達出口時爲止。
   
    如果你想象有幾百個這樣的隨機的染色體,你就能看到它們中的某些可能爲Bob譯碼
出到達出口的一套方向(問題的一個解),但它們中的大多數將是失敗的。
   
    遺傳算法以隨機的2進制串(染色體)作爲初始羣體,測試它們每一個能讓Bob走到
離開出口有多麼接近,然後讓其中最好的那些來孵化後代,期望它們的子孫中能有比Bob
走得離出口更近一點。這樣繼續下去,直到找出一個解,或直到Bob絕望地在一個角落裏
被粘住不動爲止(你將看到,這種情況是可能發生的)。
     
    因此,我們應定義一種結構,其中包含一個2進制位串(染色體),以及一個與該
染色體相聯繫的適應性分數。我把這個結構稱爲SGenome結構,它的定義如下:    

正如你能見到的那樣,如果你在創建Sgenome對象時把一個整型數作爲參數
傳遞給構造函數,則它就會自動創建一個以此整數爲長度的隨機2進制位串,
並將其適應性分數初始化爲零,這樣就把基因組什麼都準備好了。

   SGenome結構中不具備怎樣爲染色體(vecBits)進行譯碼的知識; 這是需要
由遺傳算法類自己來完成的一項任務。現在讓我們來快速窺視一下這個類的定義。
我已把它稱作CgaBob類
 

由上你可看出,當這個類的一個實例被創建時,構造函數初始化所有的變量,並調用CreateStartPopulation()。

這一短小函數創建了所需數量的基因組羣體。每個基因組一開始包含的是一個由隨機2進制位串組成的染色體,

其適應性分數則被設置爲零。

 


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