规则引擎总结

规则引擎是什么

  • 起源于专家系统, 人工智能领域的商业应用方向 基于产生式规则的推理系统,将领域知识和业务规则集合作为知识库进行存储和管理;
  • 规则引擎根据给定数据及知识库进行推理,执行相应规则,从而作出决策;
  • 使用预定义的规则语言编写业务规则,将业务逻辑从应用程序中分离,业务规则更加可读、可编辑、动态可配置, 从而应对复杂多变的商业规则;
  • 嵌入到应用程序中的可复用计算组件。
  • 适用场景:

    1. 替换复杂嵌套难以维护的条件、分支语句;
    2. 业务规则变化迅速, 且不能经常重新编译和部署应用;
    3. 必须由业务专家动态地维护和管理可变的业务规则和商业机密;
    4. 计费系统、积分系统、知识推理系统等;
  • 规则作为一种知识,其典型运用就是通过实际情况,根据给定的一组规则,得出结论。这个结论可能是某种静态的结果,也可能是需要进行的一组操作。这种 规则的运用过程叫做推理。如果由程序来处理推理过程,那么这个程序就叫做推理机/推理引擎。推理引擎根据知识表示的不同采取的控制策略也是不同的,常见的 类型包括基于神经网络、基于案例和基于规则的推理机。其中,基于规则的推理机易于理解、易于获取、易于管理,被广泛采用。这种推理引擎被称为“规则引擎”。

  • 好的规则引擎一般自带BRMS(Business Rule Management System 业务规则管理系统)例如:Drools的Guvnor,Guvnor提供了规则管理的知识库,通过它可以实现规则的版本控制,及规则的在线修改与编译,使得开发人员和系统管理人员可以在线管理业务规则。

规则引擎的组成

此处输入图片的描述

  • 产生式规则库 (Production Memory): 存放企业规则的可编译形式;
  • 工作内存区(Working Memory):存放事实,对应于企业应用系统中的数据对象;
  • 推理引擎(Inference Engine):决定哪些规则满足事实,并授予规则执行优先级,满足要求的待执行规则被加入议程。推理引擎由模式匹配器、议程和执行引擎组成。
  1. 模式匹配器决定哪些规则满足事实,并授予规则执行优先级,满足要求的待执行规则被加入议程;模式匹配器(Pattern Matcher)是规则引擎的核心,决定着规则引擎实现的效率。一个经典而高效的算法是 ReteOO 算法。
  2. 议程(Agenda)使用指定的冲突消解策略,来决定已匹配的规则集的执行次序;
  3. 执行引擎负责执行规则,输出结果。

规则引擎结构和执行顺序

此处输入图片的描述

此处输入图片的描述

  • [步骤一]: 应用程序启动规则引擎,激活指定的规则/断言集区。激活的规则/断言集被加载入内存,并通过规则/断言编译器,最终构建出规则匹配网络;
  • [步骤二]: 工作内存区从应用程序接收输入数据或对象,将其插入规则匹配网络,经过数据-规则匹配过程,产生完全匹配的<rule, data>集合;
  • [步骤三]:选择器根据元规则集合提供的优先级描述从<rule,data>集合中选择出<rule,data>集合并包装成Activation实例集作为候选执行单位
  • [步骤四]:议程用来管理Activation实例集合的活动,支持添加、删除和更新等操作。它将优先执行的Activation实例集合交给调度器;
  • [步骤五]:调度器会预先从外部获取控制过程子例程集合。当接收到由议程传来的Activation实例集合时,通过一定的调度算法调度一个过程,并根据过程控制程序来选出将要执行的规则动作,交给解释器执行。此外,调度器还负责未能完成的Activation实例执行过程的调度处理。
  • [步骤六]:解释器拥有一个执行栈,用于存放要执行的动作。当解释器执行完一个Activation时,就会从议程中删除已执行的Activation;如果有必要,会产生两种可能的附加结果和操作:
    1. 或者更新工作内存区,并触发新的数据到规则匹配网络中进行匹配;
    2. 或者激活新的规则/断言集合,放入规则/断言编译器,更新规则匹配网络;
  • [步骤七]:解释器依次执行完所有的Activation实例集合并输出结果,或者根据用户指定的执行策略执行Activation实例集合,并在指定时刻输出结果;
  • [步骤八]:用户通过规则引擎提供的API接口取出结果,进一步由应用程序处理。

一般应用调用方式

  1. ruleEngine.put(传入对象);
  2. ruleEngine.excute(“规则包调用名”);
  3. 传出对象 = ruleEngine.get(“传出对象名”);

RETE 算法

基本概念

Rete 在拉丁语中是 “net” ,有网络的意思。 RETE 算法可以分为两部分:规则编译( rule compilation )和运行时执行( runtime execution )。

  • 用一个非技术性的词来说,一个辨别网络就是用来过滤数据
  • 方法是通过数据在网络中的传播来过滤数据。在顶端节点将会有很多匹配的数据。当我们顺着网络向下走,匹配的数据将会越来越少。

基本构件

  • 规则:亦称 [产生式],指一条由IF-THEN表述的语句,包括规则条件和规则动作;(产生式是由条件和动作组成的指令,即所谓的条件—活动规则,(condition—action 简称C-A规则)—— 百度百科)
  • [规则条件]:通常称为LHS,是规则的IF部分的表达,其中含有待匹配的“模式”元素
  • [规则动作]:通常称为RHS,是规则的THEN部分的表达,含有当规则被激活和调度时要执行的操作;
  • [对象(fact事实)]: 用来匹配规则的事实或数据,在面向对象的语境中统称对象;
  • [工作内存]:全局数据区,包含运行时将会插入、删除或更新的对象;当工作内存区插入、删除或更新对象时,都将引发事实在规则集合中的匹配过程。
  • [冲突集]:冲突集是一个集合,其中的每一个元素都是一条规则及与之完全匹配的对象集合。
1
2
3
4
5
6
7

when //LHS
emp: Employ(awardPunish=="award")
then //RHS
System.out.println("exec rule Award ... ");
emp.setPercent(1.10);
end

七种基本节点

  • 【RETE Node】 RETE网络的根节点, 默认入口点,任何插入的token都要经过此节点进入RETE匹配网络
  • 【EntryPointNode 】 RETE根节点的后继节点,它将进入的token创建多个副本并分发到其所有的后继节点
  • 【ObjectTypeNode】 对象类型检测节点,即判断分发的事实副本是否属于某个类的对象,不满足的直接被丢弃
  • 【AlphaNode 】第一级匹配节点,用于匹配单个对象的单个属性
  • 【LeftInputAdapterNode 】适配器节点,用于为匹配AlphaNode类型的对象创建元组并将其加入BetaNode节点的左工作区,是通向BetaNode类型的入口点。
  • 【BetaNode】第二级匹配节点,用于匹配多个对象之间的属性约束联系, BetaNode通常有两个工作区,分别称为左工作区和右工作区。左工作区用于存放匹配前驱AlphaNode类型或BetaNode类型的元组,右工作区用于存放匹配AlphaNode类型的对象。
  • 【TerminalNode】叶节点类型。当元组和对象集合完全匹配某个规则中的模式时,就会到达该节点,并创建包含该规则及匹配对象集的元组。这些元组将在适当的时候加入到议程中获得调度和执行。

三种匹配网络

此处输入图片的描述

此处输入图片的描述

此处输入图片的描述

匹配例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(1)规则内容

IF:

年级是三年级以上,

性别是男的,

年龄小于10岁,

身体健壮,

身高170cm以上,


THEN:

这个男孩是一个篮球苗子,需要培养

image

四种匹配子例程/四种结构

  • 【Alpha匹配网络】 负责单对象单属性的模式元素匹配,由大量AlphaNode类型的节点集合组成;
  • 【Alpha内存区】 负责存储Alpha匹配网络中匹配AlphaNode模式元素的对象集合;
  • 【Beta匹配网络】 负责多对象多属性的模式元素组合匹配,由大量BetaNode类型的节点集合组成;
  • 【 Beta内存区】负责存储从Alpha内存区或Beta内存区中进入的仅匹配BetaNode模式类型中的部分模式元素的对象集合

RETE网络的匹配过程由一个总控制程序进行调度,当对象token副本到达Alpha匹配网络,或者Alpha内存区或者Beta匹配网络,或Beta内存区,均会激发相应的子例程,从而实现对象在RETE网络中的匹配过程。可以采用观察者模式实现。


Alpha 匹配网络子例程

对进入的对象进行类型测试和单属性测试,并将匹配的对象传入对应的Alpha内存区,接着,调用相应的Alpha内存子例程。

Alpha 内存区子例程

当有满足单对象单属性的对象进入Alpha内存区时,首先将其加入到所匹配模式元素的对象集合中,然后调用与之相连的每一个BetaNode的右激发子例程。Alpha内存区可以通过对所有的类型检测模式、单属性模式建立全局索引表,从而提高匹配效率,通常可以达到O(1)的效率。因此,规则引擎的匹配效率主要取决于Beta网络的匹配效率。

BetaNode 子例程

BetaNode 具有两个子例程:左激发子例程和右激发子例程。
当匹配BetaNode部分模式元素的元组进入与之相连的父Beta内存区时,就会调用左激发子例程,查找是否有对象满足给定模式;
当匹配BetaNode部分模式元素的对象进入与之相连的Alpha内存区时,就会调用其右激发子例程,查找是否有元组满足给定模式。
若找到,则将相应的元组和对象包装成更大的元组,传入与之相连的子Beta内存区,并激发相应的Beta内存区子例程。

Beta 内存子例程

当有元组进入Beta内存区时,就会激发Beta内存子例程。
Beta内存区首先将元组加入到所匹配模式元素的对象集合中,然后将其传入与之相连的每一个BetaNode,调用其左激发子例程。Beta内存区同样可建立一个全局索引表来提高匹配效率。

规则引擎的优势

  • 逻辑表达与执行的分离。业务逻辑的实现可以细分为业务逻辑的表达和执行。 在传统代码中,表达与执行是混在一起的,均是由代码来表达和执行;而在基于规则和规则引擎的系统中,规则用于逻辑表达,引擎进行执行。逻辑表达与执行分离了;

  • 基于规则的系统中, 系统的正确性取决于规则的正确性。规则就像一系列表达“KNOW-HOW”的小片, 通过将规则片合理的组合起来(规则流的作用),从而表达完整的计算逻辑。规则、规则流和规则引擎是核心概念;

  • 动态可配置的计算逻辑,具备固有的可扩展性。由于计算逻辑通过规则来表达和实现,而规则是动态可配置的,这就使得计算逻辑是动态可配置的。 这对于复杂多变、要求快速部署的现代商业应用是非常具有潜力和优势的;

  • 规则比代码更具可读性。如果将规则生成和管理系统做到更人性化,就可以让用户(通常是业务人员和业务专家)通过编写规则和规则流来创建应用逻辑了。

  • 规则具备自解释性。可以跟踪规则的执行, 清晰地看到最终计算结果的产生过程。而在传统代码中,虽然能够打印出一些语句,但是受程序结构限制, 通常仅限于程序员来调试。

  • 计算组件的复用性。 规则用于表达, 引擎用于执行。 业务逻辑的多变性通常体现在表达上,而不是执行上。 因此, 表达部分是多变的,而执行部分是相对稳定的。规则引擎是计算组件中的可复用部分。

  • 策略与机制的分离。在软件设计的角度来说,这也体现了策略与机制的分离。 规则表达是策略, 引擎是机制。 策略可变,机制稳定。

人类专家(业务专家)、基于规则引擎的解决方案和传统计算方案(硬编码写死规则)的对比

此处输入图片的描述

  • 人类专家在计算智能和自适应性上具有很大的优势,其不足之处在于计算效率慢,难以胜任大量的计算工作;

  • 基于规则引擎的计算方案汲取了人类专家的“经验和智慧”,具备一定的智能性,同时计算效率要远高于人类专家;

  • 传统方案: 仅在计算效率方面略高于前者,而在其它方面都有难以比拟的劣势。

坚持技术分享,您的支持将鼓励我更好的创作!