當前位置:編程學習大全網 - 源碼下載 - 找到Rete算法實現代碼。

找到Rete算法實現代碼。

Rete在拉丁語中是“網”,意思是網絡。RETE算法可以分為兩部分:規則編譯和運行時執行。

編譯算法描述了規則如何在生產內存中生成有效的鑒別網絡。用壹句非技術性的話來說,就是用壹個鑒別網絡來過濾數據。該方法是通過數據在網絡中的傳播來過濾數據。頂層節點會有很多匹配的數據。我們順著網絡往下走,匹配的數據會越來越少。網絡的底部是終端節點。在Forgy博士的論文1982中,他描述了四個基本節點:根、1-輸入、2-輸入和終端。下圖顯示了Drools中的RETE節點類型:

圖1。保留節點

根節點是所有對象進入網絡的入口。然後,立即從根節點輸入ObjectTypeNode。ObjectTypeNode的作用是讓引擎只做它需要做的事情。例如,我們有兩個對象集:帳戶和訂單。如果規則引擎需要定期評估每個對象,會浪費很多時間為了提高效率,引擎只會讓匹配對象類型的對象傳遞到節點。這樣,如果應用程序斷言壹個新帳戶,它不會將Order對象傳遞給節點。許多現代的RETE實現都有專門的ObjectTypeNode。在某些情況下,ObjectTypeNode通過哈希進壹步優化。

圖二。對象類型節點

ObjectTypeNode可以傳播到alphanodes、leftinputadapternodes和BetaNodes。

1輸入節點通常稱為AlphaNode。AlphaNodes用於計算文字條件。雖然1982的論文只提到了等式條件(字面意思),但是很多RETE實現都支持其他操作。例如,Account.name = = "Mr Trout "是壹個文字條件。當壹個規則對壹個對象類型有多個文字條件時,這些文字條件將被鏈接在壹起。也就是說,如果壹個應用程序斷言壹個account對象,它必須滿足第壹個文字條件才能到達下壹個AlphaNode。在福吉博士的論文中,他用元素內條件來表達。下圖說明了奶酪的AlphaNode組合(name = = "cheddar ",strength = = "strong "):

圖3。阿爾法節點

Drools通過散列優化了從ObjectTypeNode到AlphaNode的傳播。每次將AlphaNode添加到ObjectTypeNode時,文字值被用作鍵,AlphaNode被用作連接HashMap的值。當壹個新的實例進入ObjectTypeNode時,它可以直接從HashMap中獲得正確的AlphaNode,而無需將其傳遞給每個AlphaNode,從而避免了不必要的文字檢查。

& lt!-【如果!supportEmptyParas]-& gt;

雙輸入節點通常稱為BetaNode。Drools中有兩種beta node:join node和NotNode。BetaNodes用於比較兩個對象。這兩個對象可以是相同的類型,也可以是不同的類型。

我們同意BetaNodes的兩個輸入稱為左和右。BetaNode的左側輸入通常是壹個對象列表。在Drools中,這是壹個數組。右邊的輸入是單個對象。兩個NotNode可以完成“exists”檢查。Drools通過將索引應用於BetaNodes來擴展RETE算法。下圖顯示了JoinNode的用法:

圖4。聯合節點

註意,圖中左邊的輸入使用了LeftInputAdapterNode,這個節點的作用是將單個對象轉換成單個對象元組,並將其傳播到JoinNode節點。因為我們上面提到左邊的輸入通常是壹個對象列表。

& lt!-【如果!supportEmptyParas]-& gt;

終端節點用於指示壹個規則已經匹配了它的所有條件。在這壹點上,我們說這個規則有壹個完全匹配。在某些情況下,帶有OR條件的規則可以有多個終端節點。

Drools通過* * *享受節點來提高規則引擎的性能。因為許多規則可能有壹些相同的模式,所以* * *享受節點允許我們壓縮內存中的節點數量,以提供遍歷節點的過程。以下兩條規則* * *共享壹些節點:

這裏先不討論這兩條規則的意義。從直觀的感覺來說,這兩條規則在他們的LHS中基本相同,但是最後的favouriteCheese,壹條規則等於$cheddar,另壹條規則不等於$cheddar。下面是這兩個規則的節點圖:

圖5。節點共享

從圖中可以看出,在編譯好的RETE網絡中,AlphaNode為* * *所享用,而BetaNode為* * *所不享用。上面說的平等和不平等,體現在BetaNode的區別上。那麽這兩個規則有自己的終端節點。

& lt!-【如果!supportEmptyParas]-& gt;

RETE算法的第二部分是運行時。當應用程序斷言壹個對象時,引擎將數據傳遞給根節點。從那裏,它進入ObjectTypeNode並沿網絡傳播。當數據符合某個節點的條件時,該節點會將其記錄在相應的內存中。原因有幾個:主要原因是可以帶來更快的性能。盡管記住完全或部分匹配的對象需要內存很重要,但它提供了速度和可伸縮性的特征。當壹個規則的所有條件都滿足時,它就是完美匹配。只滿足部分條件,是部分匹配。(我覺得引擎在每個節點都有它對應的內存來存儲滿足那個節點條件的對象,這就造成了如果壹個對象完全匹配,那麽這個對象在每個節點對應的內存裏都會有它的映像。)

2.Leaps算法:

生產系統的Leaps算法使用壹種“懶惰”方法來評估條件。實現了Leaps算法的改進版本。作為Drools v3的壹部分,它試圖結合Leaps和RETE方法的最佳特性來處理工作記憶中的事實。

經典的Leaps方法根據工作存儲器中斷言的FIFO將所有斷言的事實放入主堆棧。它逐個檢查事實,並通過叠代匹配數據類型的事實集來找出每個相關規則的匹配。當找到壹個匹配的數據時,系統記住此時的叠代位置用於下壹次叠代,並激發規則共識。當壹致性執行完成時,系統將繼續處理主堆棧頂部的事實。如此反復。

規則

當...的時候

奶酪($ cheddar:name = = " cheddar ")

$ Person:Person(favorite cheese!= $切達幹酪)

然後

system . out . println($ person . getname()+" does likes cheddar));

結束

規則

當...的時候

奶酪($ cheddar:name = = " cheddar ")

$ Person:Person(favorite cheese = = $ cheddar)

然後

system . out . println($ person . getname()+“喜歡切達”);

結束

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

  • 上一篇:我要最新的qq個性化簽名在2011!想要最新的!拖拉(或悲傷)
  • 下一篇:瑜伽付費課程源代碼
  • copyright 2024編程學習大全網