當前位置:首頁 » 編程軟體 » drools編譯

drools編譯

發布時間: 2024-12-02 05:41:36

Ⅰ 求Rete演算法實現代碼

Rete 在拉丁語中是 」net」 ,有網路的意思。 RETE 演算法可以分為兩部分:規則編譯( rule compilation )和運行時執行( runtime execution )。
編譯演算法描述了規則如何在 Proction Memory 中產生一個有效的辨別網路。用一個非技術性的詞來說,一個辨別網路就是用來過濾數據。方法是通過數據在網路中的傳播來過濾數據。在頂端節點將會有很多匹配的數據。當我們順著網路向下走,匹配的數據將會越來越少。在網路的最底部是終端節點( terminal nodes )。在 Dr Forgy 的 1982 年的論文中,他描述了 4 種基本節點: root , 1-input, 2-input and terminal 。下圖是 Drools 中的 RETE 節點類型:

Figure 1. Rete Nodes
根節點( RootNode )是所有的對象進入網路的入口。然後,從根節點立即進入到 ObjectTypeNode 。 ObjectTypeNode 的作用是使引擎只做它需要做的事情。例如,我們有兩個對象集: Account 和 Order 。如果規則引擎需要對每個對象都進行一個周期的評估,那會浪費很多的時間。為了提高效率,引擎將只讓匹配 object type 的對象通過到達節點。通過這種方法,如果一個應用 assert 一個新的 account ,它不會將 Order 對象傳遞到節點中。很多現代 RETE 實現都有專門的 ObjectTypeNode 。在一些情況下, ObjectTypeNode 被用散列法進一步優化。

Figure 2 . ObjectTypeNodes
ObjectTypeNode 能夠傳播到 AlphaNodes, LeftInputAdapterNodes 和 BetaNodes 。
1-input 節點通常被稱為 AlphaNode 。 AlphaNodes 被用來評估字面條件( literal conditions )。雖然, 1982 年的論文只提到了相等條件(指的字面上相等),很多 RETE 實現支持其他的操作。例如, Account.name = = 「Mr Trout」 是一個字面條件。當一條規則對於一種 object type 有多條的字面條件,這些字面條件將被鏈接在一起。這是說,如果一個應用 assert 一個 account 對象,在它能到達下一個 AlphaNode 之前,它必須先滿足第一個字面條件。在 Dr. Forgy 的論文中,他用 IntraElement conditions 來表述。下面的圖說明了 Cheese 的 AlphaNode 組合( name = = 「cheddar」 , strength = = 「strong」 ):

Figure 3. AlphaNodes
Drools 通過散列法優化了從 ObjectTypeNode 到 AlphaNode 的傳播。每次一個 AlphaNode 被加到一個 ObjectTypeNode 的時候,就以字面值( literal value )作為 key ,以 AlphaNode 作為 value 加入 HashMap 。當一個新的實例進入 ObjectTypeNode 的時候,不用傳遞到每一個 AlphaNode ,它可以直接從 HashMap 中獲得正確的 AlphaNode ,避免了不必要的字面檢查。
<!--[if !supportEmptyParas]-->

2-input 節點通常被稱為 BetaNode 。 Drools 中有兩種 BetaNode : JoinNode 和 NotNode 。 BetaNodes 被用來對 2 個對象進行對比。這兩個對象可以是同種類型,也可以是不同類型。
我們約定 BetaNodes 的 2 個輸入稱為左邊( left )和右邊( right )。一個 BetaNode 的左邊輸入通常是 a list of objects 。在 Drools 中,這是一個數組。右邊輸入是 a single object 。兩個 NotNode 可以完成『 exists 』檢查。 Drools 通過將索引應用在 BetaNodes 上擴展了 RETE 演算法。下圖展示了一個 JoinNode 的使用:

Figure 4 . JoinNode

注意到圖中的左邊輸入用到了一個 LeftInputAdapterNode ,這個節點的作用是將一個 single Object 轉化為一個單對象數組( single Object Tuple ),傳播到 JoinNode 節點。因為我們上面提到過左邊輸入通常是 a list of objects 。
<!--[if !supportEmptyParas]-->
Terminal nodes 被用來表明一條規則已經匹配了它的所有條件( conditions )。 在這點,我們說這條規則有了一個完全匹配( full match )。在一些情況下,一條帶有「或」條件的規則可以有超過一個的 terminal node 。
Drools 通過節點的共享來提高規則引擎的性能。因為很多的規則可能存在部分相同的模式,節點的共享允許我們對內存中的節點數量進行壓縮,以提供遍歷節點的過程。下面的兩個規則就共享了部分節點:

這里我們先不探討這兩條 rule 到的是什麼意思,單從一個直觀的感覺,這兩條 rule 在它們的 LHS 中基本都是一樣的,只是最後的 favouriteCheese ,一條規則是等於 $cheddar ,而另一條規則是不等於 $cheddar 。下面是這兩條規則的節點圖:

Figure 5 . Node Sharing
從圖上可以看到,編譯後的 RETE 網路中, AlphaNode 是共享的,而 BetaNode 不是共享的。上面說的相等和不相等就體現在 BetaNode 的不同。然後這兩條規則有各自的 Terminal Node 。
<!--[if !supportEmptyParas]-->
RETE 演算法的第二個部分是運行時( runtime )。當一個應用 assert 一個對象,引擎將數據傳遞到 root node 。從那裡,它進入 ObjectTypeNode 並 沿著網路向下傳播。當數據匹配一個節點的條件,節點就將它記錄到相應的內存中。這樣做的原因有以下幾點:主要的原因是可以帶來更快的性能。雖然記住完全或 部分匹配的對象需要內存,它提供了速度和可伸縮性的特點。當一條規則的所有條件都滿足,這就是完全匹配。而只有部分條件滿足,就是部分匹配。(我覺得引擎 在每個節點都有其對應的內存來儲存滿足該節點條件的對象,這就造成了如果一個對象是完全匹配,那這個對象就會在每個節點的對應內存中都存有其映象。)
2. Leaps 演算法:
Proction systems 的 Leaps 演算法使用了一種「 lazy 」方法來評估條件( conditions )。一種 Leaps 演算法的修改版本的實現,作為 Drools v3 的一部分,嘗試結合 Leaps 和 RETE 方法的最好的特點來處理 Working Memory 中的 facts 。
古典的 Leaps 方法將所有的 asserted 的 facts ,按照其被 asserted 在 Working Memory 中的順序( FIFO ),放在主堆棧中。它一個個的檢查 facts ,通過迭代匹配 data type 的 facts 集合來找出每一個相關規則的匹配。當一個匹配的數據被發現時,系統記住此時的迭代位置以備待會的繼續迭代,並且激發規則結果( consequence )。當結果( consequence )執行完成以後,系統就會繼續處理處於主堆棧頂部的 fact 。如此反復。

rule
when
Cheese( $chedddar : name == " cheddar " )
$person : Person( favouriteCheese != $cheddar )
then
System.out.println( $person.getName() + " does likes cheddar " );
end

rule
when
Cheese( $chedddar : name == " cheddar " )
$person : Person( favouriteCheese == $cheddar )
then
System.out.println( $person.getName() + " likes cheddar " );
end

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/icefishchwd/archive/2007/01/22/1489668.aspx

Ⅱ Google Aviator——輕量級 Java 表達式引擎實戰

本文將探討Google Aviator——一款輕量級Java表達式引擎,其在實戰中的表現和與其他常用表達式引擎如Drools、IKExpression和Groovy的對比。Drools以其高性能和Java實現聞名,但主要關注復雜對象的規則匹配,而Aviator則定位在輕量級和高性能之間,編譯執行模式提供更好的性能。IKExpression作為解釋執行的引擎,雖然簡潔,但在性能上不如Aviator和Groovy。Groovy憑借動態執行和JIT編譯,適用於頻繁執行的場景。

在實際場景中,比如監控告警規則配置,Aviator能快速將規則轉化為表達式並執行,如示例所示:

通過自定義函數實現,只需繼承AbstractAlertFunction,如源碼所示,並在初始化時注冊。對於性能問題,推薦使用編譯緩存模式,以減少每次執行時的編譯成本。

Aviator的性能優化和管理可以通過其提供的緩存管理方法來實現。對於更深入的技術探討和參考,可以參考作者的個人博客和相關文檔。

熱點內容
漫播下載的廣播劇存儲路徑 發布:2024-12-04 15:41:21 瀏覽:837
rc2在線加密 發布:2024-12-04 15:32:58 瀏覽:86
紅米4怎麼鎖屏密碼忘了怎麼辦 發布:2024-12-04 15:24:12 瀏覽:944
編程語言推薦 發布:2024-12-04 15:11:23 瀏覽:819
安卓機怎麼下載酷狗音樂 發布:2024-12-04 15:10:32 瀏覽:189
整數劃分編程 發布:2024-12-04 15:02:44 瀏覽:356
編程兩個變數 發布:2024-12-04 14:59:27 瀏覽:502
伺服器搭建信息化系統 發布:2024-12-04 14:59:26 瀏覽:974
斯柯達明銳哪個配置比較劃算 發布:2024-12-04 14:50:28 瀏覽:12
恆星壓縮槍 發布:2024-12-04 14:34:36 瀏覽:270