drools -Rete演算法

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

Rete演算法是Charles Forgy在1979年的論文中首次提出的,針對基於規則知識表現的模式比對演算法。目前來說,大部分規則引擎還是基於rete演算法作為核心,但都有所改進,比如drool,jess等等,下面介紹rete演算法的概念

1.rete 演算法

Rete演算法是一種高效的模式比對演算法用來實現產生式規則系統
(空間換時間,用記憶體換取匹配速度)

它是高效的演算法,它通過緩衝避免了相同條件多次評估的情況,但是帶來了大量的記憶體使用量

Rete 在拉丁語中是 ”net” ,有網路的意思;Rete演算法通過規則條件產生了一個網路,每個規則條件是網路中的一個節點

rete可以被分為兩部分:規則編譯和運行時執行。規則編譯是指根據規則集產生推理網路的過程,運行時執行指將資料送入推理網路進行篩選的過程。

2.規則編譯

規則編譯就是根據規則檔案推理產生網路的過程。下面展示一下推理後的網路節點圖。(大家只用看一下,心裡有個印象就好,下面我會分析講解)

圖一

2.1 Root Node:

(一的黑色節點) 根節點(RootNode)是所有對象進入網路的入口,然後進入到TypeNode

2.2 Type Node

(有的叫ObjectTypeNode,圖一的紅色節點): type Node 就是我們的fact 也就是我們規則所用到的pojo;每個fact 就是一個 type node。 type Node 就是類型檢查,引擎只讓匹配Object 類型的對象到達節點,它能夠傳播到 AlphaNodes、LeftInputAdapterNodes (作為betaNodes的左端輸入節點)和 BetaNodes

舉例:有兩個fact ,Person 和cheese 。那麼節點圖就如下所示。

2.3 Alpha Node

:(圖一的藍色節點)用來評估字麵條件,例如。person.age>10 這就是一個 alpha node 節點,當一條規則有多條字麵條件,這些字麵條件被連結到一起。

Drools 通過散列法最佳化了從 ObjectTypeNode 到 AlphaNode 的傳播。每次一個 AlphaNode 被加到一個 ObjectTypeNode 的時候,就以字面值( literal value )作為 key ,以 AlphaNode 作為 value 加入 HashMap 。當一個新的執行個體進入 ObjectTypeNode 的時候,不用傳遞到每一個 AlphaNode ,它可以直接從 HashMap 中獲得正確的 AlphaNode ,避免了不必要的字面檢查。

舉例 1:條件 Cheese (name=”cheddar” ,strengh==”strong”)

解釋:name 和 strengh 都是對象Cheese 的屬性,且name 和 strengh兩個條件的關係是且,必須同時滿足拿麼節點圖如下所示:

舉例 2:在舉例1 的條件上添加另外一條規則 Cheese (name=”cheddar” ,age>10)

解釋:name 和 age 都是對象Cheese 的屬性,且name 和 age兩個條件的關係是且,必須同時滿足,拿麼結合舉例1的節點圖,如下所示:

此時我們發現我門共用了(name==“cheddar“) 節點。

2.4 Bate Node:

(一的綠色節點)用來對2個對象進行對比、檢查。約定BetaNode的2個輸入稱為左邊(Join Node)和右邊。左邊通常是一個a list of objects,右邊(NotNode)通常是 a single object。每個Bate節點都有自己的終端節點等組成

BetaNode 具有記憶功能。左邊的輸入被稱為 Beta Memory,會記住所有到達過的語義。右邊的輸入成為 Alpha Memory,會記住所有到達過的對象。

舉例:條件 Cheese (name=”cheddar” ) Person(favouriteiteCheese==”cheese.name”)。

解釋:這個兩個對象Cheese和Person 的關聯操作。Cheese的name=”cheddar” 且cheese.ame ==favouriteiteCheese。那麼節點圖如下所示。

圖中黃色的node 我門稱為LeftInputAdapterNode,這個節點的作用是將一個single Object轉化為一個單對象數組(single Object Tuple),傳播到JoinNode節點。因為我們上面提到過左邊輸入通常是a list of objects。

舉例2:

rulewhen    Cheese( $cheddar : name == "cheddar" )    $person : Person( favouriteCheese == $cheddar )then    System.out.println( $person.getName() + " likes cheddar" );endrulewhen    Cheese( $cheddar : name == "cheddar" )    $person : Person( favouriteCheese != $cheddar )then    System.out.println( $person.getName() + " does not like cheddar" );end

網狀圖如下:

Drools 通過節點的共用來提高規則引擎的效能。因為很多的規則可能存在部分相同的模式,節點的共用允許我們對記憶體中的節點數量進行壓縮,以提供遍曆節點的過程

從圖上可以看到,編譯後的RETE網路中,AlphaNode是共用的,而BetaNode不是共用的。上面說的相等和不相等就體現在BetaNode的不同。然後這兩條規則有各自的Terminal Node。

2.5 建立 rete 網路

Rete 演算法的編譯結果是建立了規則集對應的 Rete 網路 , 它是一個事實可以在其中流動的圖。建立 rete 網路的過程 [1]如下:

1) 建立根節點;
2) 加入一條規則

a. 取出規則中的一個模式 ,(模式就是規則中的最小一個匹配項例如(age>10,age<20)拿麼age>10 就是一個模式,age<20 就是另一個模式。)檢查模式中的參數類型,如果是新類型(也就是新的fact類型),則加入一個類型節點;b. 檢查模式  對應的 Alpha 節點是否已存在,如果存在則記錄下節點位置,如果沒有則將模式  作為一個 Alpha 節點加入到網路中,同時根據 Alpha 節點的模式建立 Alpha 記憶體表;c. 重複 b 直到所有的模式處理完畢;d. 組合 Beta 節點,按照如下方式: Beta 左輸入節點為 Alpha(1),右輸入節點為 Alpha(2) 。Beta(i) 左輸入節點為 Beta(i-1),右輸入節點為 Alpha(i) i>2 並將兩個父節點的記憶體表內聯成為自己的記憶體表; e. 重複 d 直到所有的 Beta 節點處理完畢;f. 將動作(Then 部分)封裝成分葉節點(Action 節點)作為 Beta(n) 的輸出節點;

3) 重複 2) 直到所有規則處理完畢; 執行完上述步驟,建立的 rete 網狀圖

3. 運行時執行

WME :儲存區儲存的最小單位是工作儲存區元素(Working Memory Element,簡稱WME),WME是為事實建立的元素,是用於和非根結點代表的模式進行匹配的元素。

Token:是WME的列表,包含有多個WME,(在Forgy的論文中,把Token看成是WME的列表或者單個WME,為了闡述方便,本文將把Token只看成WME的列表)

(1)如果WME的類型和根節點的後繼結點TypeNode(alpha結點的一種)所指定的類型相同,則會將該事實儲存在該TypeNode結點對應的alpha儲存區中,該WME被傳到後繼結點繼續匹配,否則會放棄該WME的後續匹配;

TypeNode儲存: 每次一個AlphaNode被加到一個 ObjectTypeNode的時候,就以字面值(literal value)也就是file 作為key,以AlphaNode作為value加入HashMap。當一個新的執行個體進入ObjectTypeNode的時候,不用傳遞到每 一個AlphaNode,它可以直接從HashMap中獲得正確的AlphaNode,避免了不必要的字面檢查。

(2)如果WME被傳遞到alpha結點,則會檢測WME是否和該結點對應的模式相匹配,若匹配,則會將該事實儲存在該alpha結點對應的儲存區中,該WME被傳遞到後繼結點繼續匹配,否則會放棄該WME的後續匹配;

alpha 儲存:檢測WME是否和該結點對應的模式相匹配,若匹配,則會將該事實儲存在該alpha結點對應的儲存區中,該WME被傳遞到後繼結點繼續匹配

(3)如果WME被傳遞到beta結點的右端,則會加入到該beta結點的right儲存區,並和left儲存區中的Token進行匹配(匹配動作根據beta結點的類型進行,例如:join,projection,selection),匹配成功,則會將該WME加入到Token中,然後將Token傳遞到下一個結點,否則會放棄該WME的後續匹配;

bate儲存區:每個非根結點都有一個儲存區。其中1-input(alpha)結點有alpha儲存區和一個輸入口;2-input(bate)結點有left儲存區和right儲存區和左右兩個輸入口,其中left儲存區是beta儲存區,right儲存區是alpha儲存區。儲存區儲存的最小單位是工作儲存區元素(Working Memory Element,簡稱WME),WME是為事實建立的元素,是用於和非根結點代表的模式進行匹配的元素。

(4)如果Token被傳遞到beta結點的左端,則會加入到該beta結點的left儲存區,並和right儲存區中的WME進行匹配(匹配動作根據beta結點的類型進行,例如:join,projection,selection),匹配成功,則該Token會封裝匹配到的WME形成新的Token,傳遞到下一個結點,否則會放棄該Token的後續匹配;

(5)如果WME被傳遞到beta結點的左端,將WME封裝成僅有一個WME元素的WME列表做為Token,然後按照(4)所示的方法進行匹配;

(6)如果Token傳遞到終結點,則和該根結點對應的規則被啟用,建立相應的Activation,並儲存到Agenda當中,等待激發。

(7)如果WME被傳遞到終結點,將WME封裝成僅有一個WME元素的WME列表做為Token,然後按照(6)所示的方法進行匹配;

以上是RETE演算法對於不同的結點,來進行WME或者token和結點對應模式的匹配的過程。

4. Rete 演算法的特點:

a. Rete 演算法是一種啟發學習法演算法,不同規則之間往往含有相同的模式,因此在 beta-network 中可以共用 BetaMemory 和 betanode。如果某個 betanode 被 N 條規則共用,則演算法在此節點上效率會提高 N 倍。

b. Rete 演算法由於採用 AlphaMemory 和 BetaMemory 來儲存事實,當事實集合變化不大時,儲存在 alpha 和 beta 節點中的狀態不需要太多變化,避免了大量的重複計算,提高了匹配效率。

c. 從 Rete 網路可以看出,Rete 匹配速度與規則數目無關,這是因為事實只有滿足本節點才會繼續向下沿網路傳遞。

5. Rete 演算法的不足:

a. 事實的刪除與事實的添加順序相同, 除了要執行與事實添加相同的計算外, 還需要執行尋找, 開銷很高 [3]。

b. RETE 演算法使用了β儲存區儲存已計算的中間結果, 以犧牲空間換取時間, 從而加快系統的速度。然而β儲存區根據規則的條件與事實的數目而成指數級增長, 所以當規則與事實很多時, 會耗盡系統資源 [3]。
針對 Rete 演算法的特點和不足,在應用或者開發基於 Rete 演算法的規則引擎時,提出如下建議:

    a. 容易變化的規則盡量置後匹配,可以減少規則的變化帶來規則庫的變化。    b. 約束性較為通用或較強的模式盡量置前匹配,可以避免不必要的匹配。    c. 針對 Rete 演算法記憶體開銷大和事實增加刪除影響效率的問題,技術上應該在 alpha 記憶體和 beata 記憶體中,只儲存指向記憶體的指標,並對指標建裡索引(可用 hash 表或者非平衡二叉樹)。    d. Rete 演算法 JoinNode 可以擴充為 AndJoinNode 和 OrJoinNode,兩種節點可以再進行組合 [5]。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.