【java规则引擎】之Drools之Rete算法

简介: 一:规则引擎--->规则引擎的核心是Pattern Matcher(模式匹配器)。不管是正向推理还是反向推理,首先要解决一个模式匹配的问题。--->对于规则的模式匹配,可以定义为: 一个规则是一组模式的集合。

一:规则引擎
--->规则引擎的核心是Pattern Matcher(模式匹配器)。不管是正向推理还是反向推理,首先要解决一个模式匹配的问题。

--->对于规则的模式匹配,可以定义为: 一个规则是一组模式的集合。如果事实/假设的状态符合该规则的所有模式,则称为该规则是可满足的。 模式匹配的任务就是将事实/假设的状态与规则库中的规则一一匹配,找到所有可满足的规则。



二:什么是模式匹配

对于模式匹配我们都应该不陌生,我们经常使用的正则表达式就是一种模式匹配。

正则表达式是一种“模式(pattern)”,
编程语言提供的“正则表达式引擎”就是Pattern Matcher。比如python中的re模块。
首先输入“知识”:re.compile(r'string'),
然后就可以让其匹配(match)事实(字符串)。
最后通过正则表达式引擎可以得到匹配后的结果。
对于规则匹配,通常定义如下:

条件部分,也称为LHS(left-hand side)
事实部分,也称为RHS(right-hand side)
假设系统中有N条规则,平均每个规则的条件部分有P个模式,在某个时点有M个事实需要处理。则规则匹配要做的事情就是: 对每一个规则r,判断当前的事实o是否满足LHS(r)=True,如果满足,则将规则r的实例r(o),即规则+满足该规则的事实,加到冲突集中等待处 理。 通常采取如下过程:

从N条规则中取出一条r;
从M个事实中取出P个事实的一个组合c;
用c测试LHS(r),如果LHS(r(c))=True,将RHS(r(c))加入队列中;
如果M个事实还存在其他的组合c,goto 3;
取出下一条规则r,goto 2;
实际的问题可能更复杂,在规则的执行过程中可能会改变RHS的数据,从而使得已经匹配的规则实例失效或者产生新的满足规则的匹配,形成一种“动态”的匹配链。



三:模式匹配算法

上面的处理由于涉及到组合,过程很复杂。有必要通过特定的算法优化匹配的效率。目前常见的模式匹配算法包括Rete、Treat、Leaps,HAL,Matchbox等。





四:Rete算法

Rete算法是目前使用最广泛的规则匹配算法,由Charles L. Forgy博士在1979年发明。Rete算法是一种快速的Forward-Chaining推理算法,其匹配速度与规则的数量无关。 Rete的高效率主要来自两个重要的假设:

时间冗余性。 facts在推理过程中的变化是缓慢的, 即在每个执行周期中,只有少数的facts发生变化,因此影响到的规则也只占很小的比例。所以可以只考虑每个执行周期中已经匹配的facts.
结构相似性。许多规则常常包含类似的模式和模式组。
Rete算法的基本思想是保存过去匹配过程中留下的全部信息,以空间代价来换取执行效率 。对每一个模式 ,附加一个匹配元素表来记录WorkingMemory中所有能与之匹配的元素。当一个新元素加入到WorkingMemory时, 找出所有能与之匹配的模式, 并将该元素加入到匹配元素表中; 当一个无素从WorkingMemory中删除时,同样找出所有与该元素匹配的模式,并将元素从匹配元素表中删除。 Rete算法接受对工作存储器的修改操作描述 ,产生一个修改冲突集的动作 。

Rete算法的步骤如下:

将初始数据(fact)输入Working Memory。
使用Pattern Matcher比较规则(rule)和数据(fact)。
如果执行规则存在冲突(conflict),即同时激活了多个规则,将冲突的规则放入冲突集合。
解决冲突,将激活的规则按顺序放入Agenda。
使用规则引擎执行Agenda中的规则。重复步骤2至5,直到执行完毕所有Agenda中的规则。
五:Tread算法

在 Rete算法中 ,同一规则连接结点上的寄存器保留了大量的冗余结果。实际上, 寄存器中大部分信息已经体现在冲突集的规则实例中。因此 ,如果在部分匹配过程中直接使用冲突集来限制模式之间的变量约束,不仅可以减少寄存器的数量 ,而且能够加快匹配处理效率 。这一思想称为 冲突集支撑策略 。

考虑增删事实对匹配过程的影响,当向工作存储器增加一个事实时 ,冲突集中已有的规则实例仍然保留,只是将与该事实匹配的规则实例加入到冲突集中; 当从工作存储器删去一个事实时,不可能有新的规则实例产生, 只是将 包含该事实的规则实例从冲突集中删去。

基于冲突集支撑策略和上述观察, Treat算法放弃了Rete算法中利用寄存器保存模式之间变量约束中间结果的思想,对于每一个模式 ,除保留原有 a寄存器的外 ,增加两个新链来记录与该模式匹配的增删事实,一个叫做增链 (addlist),另一个叫做删链 (deletelist)。当修改描述的操作符为 “+”时,临时执行部分连接任务;当修改描述的操作符为 “一”时,直接删去冲突集中包含该事实的规则实例。

Treat算法的步骤如下:

行动 :根据点火规则的 RHS,生成修改描述表 CHANGES;
模式匹配:置每一模式的删链和增链为空,对 CHANGES的每一个修改描述 ,执行模式匹配。对于与修改描述中的事实匹配成功的模式,若修改描述的操作符为 “+”, 将该事实加入这一模式的增链;若修改描述的操作符为 “一”,将该事实加入这一模式的 删链。
删去事实的处理:对于任一模式链中的每一个事实,找到冲突集中所有包含该事实 的规则实例,并将这一规则实例从冲突集中删去。相应地修改该模式的 a寄存器 。
新增事实的处理:对 于 每 一 模 式 ,若 其 增 链 非 空 ,则 将 增 链 中 的 所 有 事 实 加 入 该 模 式的a寄存器 ,并对与新增事实相关的每一条规则临时执行部分匹配,寻找该规则新的实 例。具体做法为:首先将第一个模式增链中的事实集合与后一模式的 a寄存器进行连接 , 再将部分连接结果与第三个模式的a寄存器进行连接 ,一直到所有模式均连接完成为止。 其中 ,a寄存器 的内容包括新增 事实。若连接结果非空 ,则将找到 的规则 实例插入到冲突 集中。
六:Leaps 算法

前向推理引擎,包括LEAPS,都包括了匹配-选择-执行(match-select-action)循环。即,确定可以匹配的规则,选择某个匹配 的元 组,此元组相应的规则动作被执行。重复这一过程,直到某一状态(如没有更多的规则动作)。RETE和TREAT匹配算法速度慢的原因是,它们把满足规则条 件的元组都实例化。Leaps算法的最大的改进就是使用一种"lazy"的方法来评估条件(conditions),即仅当必要时才进行元组的实例化。这 一改进极大的减少了前向推理引擎的时空复杂度,极大提高了规则执行速度。

Leaps算法将所有的 asserted 的 facts ,按照其被 asserted 在 Working Memory 中的顺序( FIFO ),放在主堆栈中。它一个个的检查 facts ,通过迭代匹配 data type 的 facts 集合来找出每一个相关规则的匹配。当一个匹配的数据被发现时,系统记住此时的迭代位置以备待会的继续迭代,并且激发规则结果( consequence )。当结果( consequence )执行完成以后,系统就会继续处理处于主堆栈顶部的 fact 。如此反复。

Leaps算法的效率可以比Rete算法和Tread算法高几个数量级。

七:其他算法

对于HAL算法和Matchbox算法,使用的范围不是很广,这里不做过多的介绍。

相关文章
|
2月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
92 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
4月前
|
搜索推荐 算法 Java
手写快排:教你用Java写出高效排序算法!
快速排序(QuickSort)是经典的排序算法之一,基于分治思想,平均时间复杂度为O(n log n),广泛应用于各种场合。在这篇文章中,我们将手写一个Java版本的快速排序,从基础实现到优化策略,并逐步解析代码背后的逻辑。
188 1
|
2月前
|
算法 搜索推荐 Java
java 后端 使用 Graphics2D 制作海报,画echarts图,带工具类,各种细节:如头像切割成圆形,文字换行算法(完美实验success),解决画上文字、图片后不清晰问题
这篇文章介绍了如何使用Java后端技术,结合Graphics2D和Echarts等工具,生成包含个性化信息和图表的海报,并提供了详细的代码实现和GitHub项目链接。
152 0
java 后端 使用 Graphics2D 制作海报,画echarts图,带工具类,各种细节:如头像切割成圆形,文字换行算法(完美实验success),解决画上文字、图片后不清晰问题
|
2月前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
93 2
|
2月前
|
算法 Java Linux
java制作海报一:java使用Graphics2D 在图片上写字,文字换行算法详解
这篇文章介绍了如何在Java中使用Graphics2D在图片上绘制文字,并实现自动换行的功能。
152 0
|
2月前
|
数据可视化 算法 Java
JAVA规则引擎工具
本文介绍了六款常用的Java规则引擎:Drools、IBM ODM、Easy Rules、jBPM、OpenL Tablets 和 Apache Camel。每款引擎都有其独特的特点和适用场景,如Drools的高效规则匹配、IBM ODM的Web界面管理、Easy Rules的轻量级特性、jBPM的流程管理、OpenL Tablets的Excel规则定义以及Apache Camel的路由和规则结合。选择合适的规则引擎可以显著提高系统的灵活性和可维护性。
132 0
|
2月前
|
算法 Java 测试技术
数据结构 —— Java自定义代码实现顺序表,包含测试用例以及ArrayList的使用以及相关算法题
文章详细介绍了如何用Java自定义实现一个顺序表类,包括插入、删除、获取数据元素、求数据个数等功能,并对顺序表进行了测试,最后还提及了Java中自带的顺序表实现类ArrayList。
35 0
|
4月前
|
设计模式 缓存 算法
揭秘策略模式:如何用Java设计模式轻松切换算法?
【8月更文挑战第30天】设计模式是解决软件开发中特定问题的可重用方案。其中,策略模式是一种常用的行为型模式,允许在运行时选择算法行为。它通过定义一系列可互换的算法来封装具体的实现,使算法的变化与客户端分离。例如,在电商系统中,可以通过定义 `DiscountStrategy` 接口和多种折扣策略类(如 `FidelityDiscount`、`BulkDiscount` 和 `NoDiscount`),在运行时动态切换不同的折扣逻辑。这样,`ShoppingCart` 类无需关心具体折扣计算细节,只需设置不同的策略即可实现灵活的价格计算,符合开闭原则并提高代码的可维护性和扩展性。
70 2
|
4月前
|
安全 算法 Java
java系列之~~网络通信安全 非对称加密算法的介绍说明
这篇文章介绍了非对称加密算法,包括其定义、加密解密过程、数字签名功能,以及与对称加密算法的比较,并解释了非对称加密在网络安全中的应用,特别是在公钥基础设施和信任网络中的重要性。
|
4月前
|
数据采集 搜索推荐 算法
【高手进阶】Java排序算法:从零到精通——揭秘冒泡、快速、归并排序的原理与实战应用,让你的代码效率飙升!
【8月更文挑战第21天】Java排序算法是编程基础的重要部分,在算法设计与分析及实际开发中不可或缺。本文介绍内部排序算法,包括简单的冒泡排序及其逐步优化至高效的快速排序和稳定的归并排序,并提供了每种算法的Java实现示例。此外,还探讨了排序算法在电子商务、搜索引擎和数据分析等领域的广泛应用,帮助读者更好地理解和应用这些算法。
48 0