1. 程式人生 > >行為樹的原理及實現

行為樹的原理及實現

查閱了一些行為樹資料,目前最主要是參考了這篇文章,看完後感覺行為樹實乃強大,絕對是替代狀態機的不二之選。但從理論看起來很簡單的行為樹,真正著手起來卻發現很多細節無從下手。

總結起來,就是:

1、行為樹只是單純的一棵決策樹,還是決策+控制樹。為了防止不必要的麻煩,我目前設計成單純的決策樹。

2、什麼時候執行行為樹的問題,也就是行為樹的Tick問題,是在條件變化的時候執行一次,還是隻要物件啟用,就在Update裡面一直Tick。前者明顯很節省開銷,但那樣設計的最終結果可能是最後陷入事件傳送的泥潭中。那麼一直Tick可能是最簡單的辦法,於是就引下面出新的問題。目前採用了一直Tick的辦法。

3、基本上可以明顯節點有Composite Node、Decorator Node、Condition Node、Action Node,但具體細節就很頭疼。比如組合節點裡的Sequence Node。這個節點是不是在每個Tick週期都從頭迭代一次子節點,還是記錄正在執行的子節點。每次都迭代子節點,就感覺開銷有點大。記錄執行節點就會出現條件冗餘問題,具體後面再討論。目前採用儲存當前執行節點的辦法。

4、條件節點(Condition Node)的位置問題。看到很多設計都是條件節點在最後才進行判斷,而實際上,如果把條件放在組合節點處,就可以有效短路判斷,不再往下迭代。於是我就採用了這種方法。

設計開始

在Google Code上看到的某個行為樹框架,用的是抽象類做節點。考慮到C#不能多繼承,抽象類可能會導致某些時候會很棘手,所以還是用介面。雖然目前還未發現介面的好處。

在進行抽象設計的時候,介面的純粹性雖然看起來更加清晰,不過有時候遇到需要重複使用某些類函式的時候就挺麻煩,讓人感覺有點不利於複用。
  1. publicenum RunStatus  
  2. {  
  3.     Completed,  
  4.     Failure,  
  5.     Running,  
  6. }  
  7. publicinterface IBehaviourTreeNode  
  8. {  
  9.     RunStatus status { getset; }  
  10.     string nodeName { getset; }  
  11.     bool Enter(object input);  
  12.     bool Leave(object input);  
  13.     bool Tick(object input, object output);  
  14.     RenderableNode renderNode { getset; }  
  15.     IBehaviourTreeNode parent { getset; }  
  16.     IBehaviourTreeNode Clone();  
  17. }  
  18. /************************************************************************/
  19. /* 組合結點                                                             */
  20. /************************************************************************/
  21. publicinterface ICompositeNode : IBehaviourTreeNode  
  22. {  
  23.     void AddNode(IBehaviourTreeNode node);  
  24.     void RemoveNode(IBehaviourTreeNode node);  
  25.     bool HasNode(IBehaviourTreeNode node);  
  26.     void AddCondition(IConditionNode node);  
  27.     void RemoveCondition(IConditionNode node);  
  28.     bool HasCondition(IConditionNode node);  
  29.     ArrayList nodeList { get; }  
  30.     ArrayList conditionList { get; }  
  31. }  
  32. /************************************************************************/
  33. /* 選擇節點                                                             */
  34. /************************************************************************/
  35. publicinterface ISelectorNode : ICompositeNode  
  36. {  
  37. }  
  38. /************************************************************************/
  39. /*順序節點                                                              */
  40. /************************************************************************/
  41. publicinterface ISequenceNode : ICompositeNode  
  42. {  
  43. }  
  44. /************************************************************************/
  45. /* 平行(並列)節點                                                             */
  46. /************************************************************************/
  47. publicinterface IParallelNode : ICompositeNode  
  48. {  
  49. }  
  50. //////////////////////////////////////////////////////////////////////////
  51. /************************************************************************/
  52. /* 裝飾結點                                                             */
  53. /************************************************************************/
  54. publicinterface IDecoratorNode : IBehaviourTreeNode  
  55. {  
  56. }  
  57. /************************************************************************/
  58. /* 條件節點                                                             */
  59. /************************************************************************/
  60. publicinterface IConditionNode  
  61. {  
  62.     string nodeName { getset; }  
  63.     bool ExternalCondition();  
  64. }  
  65. /************************************************************************/
  66. /* 行為節點                                                             */
  67. /************************************************************************/
  68. publicinterface IActionNode : IBehaviourTreeNode  
  69. {  
  70. }  
  71. publicinterface IBehaviourTree  
  72. {  
  73. }  

很多節點的介面都是空的,目前唯一的作用就是用於型別判斷,很可能在最後也沒有什麼實際的作用,搞不好就是所謂的過度設計。如果最終確定沒有用再刪掉吧。

接口裡出現了一個渲染節點,目的是為了能夠更方便的把這個節點和負責渲染的節點聯絡到一起,方便節點的視覺化。

如果只有介面,每次實現介面都要重複做很多工作,為了利用面向物件的複用特性,就來實現一些父類


  1. publicclass BaseNode  
  2. {  
  3.     public BaseNode() { nodeName_ = this.GetType().Name + "\n"; }  
  4.     protected RunStatus status_ = RunStatus.Completed;  
  5.     protectedstring nodeName_;  
  6.     protected RenderableNode renderNode_;  
  7.     protected IBehaviourTreeNode parent_;  
  8.     publicvirtual RunStatus status { get { return status_; } set { status_ = value; } }  
  9.     publicvirtualstring nodeName { get { return nodeName_; } set { nodeName_ = value; } }  
  10.     publicvirtual RenderableNode renderNode { get { return renderNode_; } set { renderNode_ = value; } }  
  11.     publicvirtual IBehaviourTreeNode parent { get { return parent_; } set { parent_ = value; } }  
  12.     publicvirtual IBehaviourTreeNode Clone() {  
  13.         var clone = new BaseNode();  
  14.         clone.status_ = status_;  
  15.         clone.nodeName_ = nodeName_;  
  16.         clone.renderNode_ = renderNode_;  
  17.         clone.parent_ = parent_;  
  18.         return clone as IBehaviourTreeNode;  
  19.     }  
  20. }  
  21. publicclass BaseActionNode : IActionNode  
  22. {  
  23.     

    相關推薦

    決策原理實現

    方式 -1 變化 log nbsp 導致 結點 以及 重要 1、決策樹原理 1.1、定義 分類決策樹模型是一種描述對實例進行分類的樹形結構。決策樹由結點和有向邊組成。結點有兩種類型:內部節點和葉節點,內部節點表示一個特征或屬性,葉節點表示一個類。

    kd原理實現

    優化 根節點 一半 索引 表示 建立索引 一次 所有 隨機 常用來作空間劃分及近鄰搜索,是二叉空間劃分樹的一個特例。通常,對於維度為k,數據點數為N的數據集,kd樹適用於N?2的k次方的情形。 1維數據的查詢 假設在數據庫的表格T中存儲了學生的語文成績chinese、

    AVL原理實現(C語言實現以及Java語言實現

    歡迎探討,如有錯誤敬請指正 如需轉載,請註明出處http://www.cnblogs.com/nullzx/ 1. AVL定義 AVL樹是一種改進版的搜尋二叉樹。對於一般的搜尋二叉樹而言,如果資料恰好是按照從小到大的順序或者從大到小的順序插入的,那麼搜尋二叉樹就對退化成連結串列,這個時候查詢,插入和刪除的

    淺談線段原理實現

    pri 二叉搜索樹 進行 span 但是 build += std 葉子 大家好,給大家介紹完了樹狀數組(有興趣的讀者可以在我的博客文章中閱讀),現在來給大家介紹另一種數據結構——線段樹。它們結構都有共同點,但是線段樹更為復雜,功能也更為強大,接下來

    行為原理實現

    查閱了一些行為樹資料,目前最主要是參考了這篇文章,看完後感覺行為樹實乃強大,絕對是替代狀態機的不二之選。但從理論看起來很簡單的行為樹,真正著手起來卻發現很多細節無從下手。 總結起來,就是: 1、行為樹只是單純的一棵決策樹,還是決策+控制樹。為了防止不必

    狀陣列的原理實現

    對於樹狀陣列,它的查詢和修改的時間複雜度都是log(n),空間複雜度則為O(n),這是因為樹狀陣列通過將線性結構轉化成樹狀結構,從而進行跳躍式掃描。通常使用在高效的計算數列的字首和,區間和。 附上一張圖便於理解 其中a陣列就是原陣列,c陣列則是樹狀陣列,可以發現

    線段原理實現

    前言 有時我們需要對陣列中[i, j]區間中的所有值進行操作,這樣的操作對於普通的樹來說是十分麻煩的,所以我們引入了新的一種樹——線段樹。 線段樹 線段樹(segment tree),顧名思義, 是用來存放給定區間(segment, or interval)內對應資訊的

    二叉的順序儲存原理實現過程

    二叉樹的順序儲存,實際上就是使用陣列儲存二叉樹。 使用陣列儲存二叉樹的實現思想是將二叉樹從根節點按照層次順序依次儲存在陣列中,但需要注意的是,此方式只適用於完全二叉樹,如果要使用陣列儲存普通二叉樹,需要提前將該二叉樹轉化為完全二叉樹。 完全二叉樹,即二叉樹除了最後一層節點外,其餘各節點都既有左節點和右節點

    【演算法學習】AVL平衡二叉搜尋原理各項操作程式設計實現(C++)

    AVLTree即(Adelson-Velskii-Landis Tree),是加了額外條件的二叉搜尋樹。其平衡條件的建立是為了確保整棵樹的深度為O(nLogn)。平衡條件是任何節點的左右子樹的高度相差不超過1. 在下面的程式碼中,程式設計實現了AVL樹的建立、查詢、插入、

    決策演算法原理實現

    歡迎大家檢視實現的完整程式碼。。。 決策樹模型 分類決策樹模型是一種描述對例項進行分類的樹形結構。決策樹由結點和有向邊組成。結點有兩種型別:內部節點和葉節點,內部節點表示一個特徵或屬性,葉節點表示一個分類類別。 分類的時候,從根節點開始,按照某種策略對

    寫程式學ML:決策演算法原理實現(四)

    [題外話]近期申請了一個微信公眾號:平凡程式人生。有興趣的朋友可以關注,那裡將會涉及更多更新機器學習、OpenCL+OpenCV以及影象處理方面的文章。 2.3   決策樹的測試 書中使用隱形眼鏡資料集對決策樹進行了測試。 建立測試檔案contactLenses4Deci

    快速匹配字串演算法BK 原理python實現

    BK樹或者稱為Burkhard-Keller樹,是一種基於樹的資料結構。用於快速查詢近似字串匹配,比方說拼寫糾錯,或模糊查詢,當搜尋”aeek”時能返回與其最相似的字串”seek”和”peek”。 在構建BK樹之前,我們需要定義一種用於比較字串相似度的度量方法。通常都是採用

    關於base64編碼的原理實現

    一個 replace 編碼範圍 func nco 都是 style bit 如果 我們的圖片大部分都是可以轉換成base64編碼的data:image。 這個在將canvas保存為img的時候尤其有用。雖然除ie外,大部分現代瀏覽器都已經支持原生的基於base64的enco

    使用行為(Behavior Tree)實現遊戲AI

    方便 不同 sequence 理解 and while 記錄 策略 積累 談到遊戲AI,很明顯智能體擁有的知識條目越多,便顯得更智能,但維護龐大數量的知識條目是個噩夢:使用有限狀態機(FSM),分層有限狀態機(HFSM),決策樹(Decision Tree)來實現遊戲AI總

    java設計模式singleton原理實現

    最新 不必要 -- 不同 適合 所有 引用 ati cnblogs 題外話:我要變強,要變強,變強,強。 1、 Singleton的應用場景以及為什麽要使用singleSingleton是一生只能有一個實例的對象。只能由singleton自身創建一個實例。外人是無法創建實例

    RPC原理實現

    .get 版本 pcs 連接方式 正常 zookeepe list 接口 分布式計算 1 簡介 RPC 的主要功能目標是讓構建分布式計算(應用)更容易,在提供強大的遠程調用能力時不損失本地調用的語義簡潔性。為實現該目標,RPC 框架需提供一種透明調用機制讓使用者不必顯式的

    SSO單點登錄原理實現

    response dem nbsp boolean 配置文件 實現 有效 ucc ons 1.SSO分類   根據實現的域不同,可以把SSO分為同域SSO、同父域SSO、跨域SSO三種類型。 2.SSO實現原理 a.打開統一的登錄界面 b.登錄,同時向服務器寫入Cookie

    線程池的原理實現

    execute inter void date() 超過 緩沖 線程池大小 exceptio 調整 1、線程池簡介: 多線程技術主要解決處理器單元內多個線程執行的問題,它可以顯著減少處理器單元的閑置時間,增加處理器單元的吞吐能力。 假設一個服務器完成一項任務所需時間為:T1

    線程池原理實現

    任務隊列 批量 not alt con 成了 代碼 pla extends 1、線程池簡介: 多線程技術主要解決處理器單元內多個線程執行的問題,它可以顯著減少處理器單元的閑置時間,增加處理器單元的吞吐能力。 假設一個服務器完成一項任務所需時間為:T1

    四.HashSet原理實現學習總結

    throw map 所有 cti con name 保持 nts equal 在上一篇博文(HashMap原理及實現學習總結)詳細總結了HashMap的實現過程,對於HashSet而言,它是基於HashMap來實現的,底層采用HashMap來保存元素。所以如果對HashMa