行爲樹(Behavior Tree)實踐(1)– 基本概念

原文:http://www.aisharing.com/archives/90

行爲樹(Behavior Tree)實踐(1)– 基本概念

自從開博以來,每天都會關心一下博客的訪問情況,看到一些朋友的訂閱或者訪問,不勝欣喜,也促使我去寫一些更好的博文,來和大家分享和交流,從訪問統計來看,有相當一部分是來自於搜索引擎的流量,關鍵字以“行爲樹”,或者“Behavior Tree”居首位,我想大家對此可能有些興趣,加上,這幾年反反覆覆一直在AI中研究和運用行爲樹,所以這次就來談談關於行爲樹(Behavior Tree)的一些東西,以前也寫過一些文章(123)來討論行爲樹,不過已經是一兩年前的事情了,較之以前,這次會更爲系統,也會添加一些我新的思考和感悟。所謂行爲樹實踐,其實在我腦海裏就是Practice in Behavior Tree,沒法子,受英文教材影響太多了:)

我想通過一個例子來介紹一下行爲樹的基本概念,會比較容易理解,看下圖:

bv-tree-1

這是我們爲一個士兵定義的一顆行爲樹(可以先不管這些綠圈和紅圈是幹嗎的),首先,可以看到這是一個樹形結構的圖,有根節點,有分支,而且子節點個數可以任意,然後有三個分支,分別是巡邏(Patrol),攻擊(Attack),逃跑(Retreat),這個三個分支可以看成是我們爲這個士兵定義的三個大的行爲(Behavior),當然,如果有更多的行爲,我們可以繼續在根節點中添加新的分支。當我們要決策當前這個士兵要做什麼樣的行爲的時候,我們就會自頂向下的,通過一些條件來搜索這顆樹,最終確定需要做的行爲(葉節點),並且執行它,這就是行爲樹的基本原理。

值得注意的是,我們標識的三大行爲其實並不是真正的決策的結果,它只是一個類型,來幫助我們瞭解這個分支的一些行爲是屬於這類的,真正的行爲樹的行爲都是在葉節點上,一般稱之爲行爲節點(Action Node),如下圖紅圈表示的

bv-tree-action-node

這些葉節點纔是我們真正通過行爲樹決策出來的結果,如果用我以前提到的那個層次化的AI結構來描述的話,這些行爲結果,相當於就是一個個定義好的“請求”(Request),比如移動(Move),無所事事(Idle),射擊(Shoot)等等。所以行爲樹是一種決策樹,來幫助我們搜尋到我們想要的某個行爲。

行爲節點是遊戲相關的,因不同的遊戲,我們需要定義不同的行爲節點,但對於某個遊戲來說,在行爲樹上行爲節點是可以複用的,比如移動,在巡邏的分支上,需要用到,在逃跑分支上,也會用到,這種情況下,我們就可以複用這個節點。行爲節點一般分爲兩種運行狀態:

  1. 運行中(Executing):該行爲還在處理中
  2. 完成(Completed):該行爲處理完成,成功或者失敗

除了行爲節點,其餘一般稱之爲控制節點(Control Node),用樹的“學名”的話,就是那些父節點,如下圖綠圈表示

bv-tree-control-node

控制節點其實是行爲樹的精髓所在,我們要搜索一個行爲,如何搜索?其實就是通過這些控制節點來定義的,從控制節點上,我們就可以看出整個行爲樹的邏輯走向,所以,行爲樹的特點之一就是其邏輯的可見性。

我們可以爲行爲樹定義各種各樣的控制節點(這也是行爲樹有意思的地方之一),一般來說,常用的控制節點有以下三種

  1. 選擇(Selector):選擇其子節點的某一個執行
  2. 序列(Sequence):將其所有子節點依次執行,也就是說當前一個返回“完成”狀態後,再運行先一個子節點
  3. 並行(Parallel):將其所有子節點都運行一遍

用圖來表示的話,就是這樣,依次爲選擇,序列和並行

bv-tree-sel

bv-tree-seq

bv-tree-pal

可以看到,控制節點其實就是“控制”其子節點(子節點可以是葉節點,也可以是控制節點,所謂“執行控制節點”,就是執行其定義的控制邏輯)如何被執行,所以,我們可以擴展出很多其他的控制節點,比如循環(Loop)等,與行爲節點不同的是,控制節點是與遊戲無關的,因爲他只負責行爲樹邏輯的控制,而不牽涉到任何的遊戲代碼。如果是作爲一個行爲樹的庫的話,其中就一定會包含定義好的控制節點庫。

如果我們繼續考察選擇節點,會產生一個問題,如何從子節點中選擇呢?選擇的依據是什麼呢?這裏就要引入另一個概念,一般稱之爲前提(Precondition),每一個節點,不管是行爲節點還是控制節點,都會包含一個前提的部分,如下圖

bv-tree-precondition

前提就提供了“選擇”的依據,它包含了進入,或者說選擇這個節點的條件,當我們用到選擇節點的時候,它就是去依次測試每一個子節點的前提,如果滿足,則選擇此節點。由於我們最終返回的是某個行爲節點(葉節點),所以,當前行爲的“總”前提就可以看成是:

當前行爲節點的前提 And 父節點的前提 And 父節點的父節點的前提 And….And 根節點的前提(一般是不設,直接返回True)

行爲樹就是通過行爲節點,控制節點,以及每個節點上的前提,把整個AI的決策邏輯描述了出來,對於每次的Tick,可以用如下的流程來描述:

action = root.FindNextAction(input);
if action is not empty then
action.Execute(request,  input)  //request是輸出的請求
else
print “no action is available”

從概念上來說,行爲樹還是比較簡單的,但對AI程序員來說,卻是充滿了吸引力,它的一些特性,比如可視化的決策邏輯,可複用的控制節點,邏輯和實現的低耦合等,較之傳統的狀態機,都是可以大大幫助我們迅速而便捷的組織我們的行爲決策。希望這次簡單的介紹,對大家有所幫助,能力有限,不一定能表述的很清楚,有問題,或者有指教的,都請和我多多交流,最後,我對這個士兵的巡邏分支畫了一個示意圖,供大家參考:

S — 選擇節點   Se — 序列節點

bv-tree-patrol-example

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