1.1.2 rete 算法相关概念node
Rete 算法规则相关的概念有以下几个:算法
Fact:已经存在的事实,它是指对象之间及对象属性之间的多元关系,为简单起见,事实用一个三元组来表示:(标识符 ^ 属性 值)[1],例如以下事实:数据库
w1:(B1 ^ on B2) w6:(B2 ^color blue) w2:(B1 ^ on B3) w7:(B3 ^left-of B4) w3:(B1 ^ color red) w8:(B3 ^on table) w4:(B2 ^on table) w9:(B3 ^color red) w5:(B2 ^left-of B3)
Rule:规则,包含条件和行为两部分,条件部分又叫左手元(LHS),行为部分又叫右手元(RHS)。条件部分能够有多条条件,而且能够用 and 或 or 链接 [1]。其通常形式以下:数组
(name-of-this-production LHS /*one or more conditions*/ --> RHS /*one or more actions*/ ) 例如,下面的例子: (find-stack-of-two-blocks-to-the-left-of-a-red-block (^on) (^left-of) (^color red) --> ...RHS... ) Patten:模式,也就是规则的条件部分,是已知事实的泛化形式,是未实例化的多元关系 [1]。好比,前面的那条规则的条件部分: (^on) (^left-of) (^color red) Rete 网络的概念 [1][9][10]以下:
RootNode:Rete 网络的根节点,全部对象经过 Root 节点进入网络。缓存
ObjectTypeNode:对象类型节点,保证所传入的对象只会进入本身类型所在的网络,提升了工做效率。安全
AlphaNode:Alpha 节点是规则的条件部分的一个模式,一个对象只有和本节点匹配成功后,才能继续向下传播。网络
JoinNode:用做链接(jion)操做的节点,至关于 and,至关于数据库的表链接操做,属于 betaNode 类型的节点。BetaNode 节点用于比较两个对象和它们的字段。两个对象多是相同或不一样的类型。咱们将这两个输入称为左和右。BetaNode 的左输入一般是一组对象的数组。BetaNode 具备记忆功能。左边的输入被称为 Beta Memory,会记住全部到达过的语义。右边的输入成为 Alpha Memory,会记住全部到达过的对象。性能
NotNode:根据右边输入对左边输入的对象数组进行过滤,两个 NotNode 能够完成‘ exists ’检查。优化
LeftInputAdapterNodes:将单个对象转化成对象数组。this
Terminal Nodes 被用来代表一条规则已经匹配了它的全部条件(conditions)。
图 1 展现的是一个简单的 rete 网络:
1.1.3 建立 rete 网络
Rete 算法的编译结果是建立了规则集对应的 Rete 网络 , 它是一个事实能够在其中流动的图。建立 rete 网络的过程 [1]以下: 1) 建立根节点; 2) 加入一条规则 1 (Alpha 节点从 1 开始,Beta 节点从 2 开始 ); a. 取出规则中的一个模式 1,检查模式中的参数类型,若是是新类型,则加入一个类型节点; b. 检查模式 1 对应的 Alpha 节点是否已存在,若是存在则记录下节点位置,若是没有则将模式 1 做为一个 Alpha 节点加入到网络中,同时根据 Alpha 节点的模式创建 Alpha 内存表; c. 重复 b 直到全部的模式处理完毕; d. 组合 Beta 节点,按照以下方式: Beta(2) 左输入节点为 Alpha(1),右输入节点为 Alpha(2) Beta(i) 左输入节点为 Beta(i-1),右输入节点为 Alpha(i) i>2 并将两个父节点的内存表内联成为本身的内存表; e. 重复 d 直到全部的 Beta 节点处理完毕; f. 将动做(Then 部分)封装成叶节点(Action 节点)做为 Beta(n) 的输出节点; 3) 重复 2) 直到全部规则处理完毕; 执行完上述步骤,创建的 rete 网络以下图 2 (a 图为含有 3 个规则的 rete 网络,b 图为含有一个规则的 rete 网络 ):
图 2. beta-network and alpha-network
上图(a 图和 b 图),他们的左边的部分都是 beta-network, 右边都是 alpha-network, 圆圈是 join-node。右边的 alpha-network 是根据事实库和规则条件构建的,其中除 alpha-network 节点的节点都是根据每一条规则条件的模式 , 从事实库中 match 过来的,即在编译构建网络的过程当中静态创建的。只要事实库是稳定的,RETE 算法的执行效率应该是很是高的,其缘由就是已经经过静态的编译,构建了 alpha-network。左边的 beta-network 表现出了 rules 的内容,其中 p1,p2,p3 共享了许多 BetaMemory 和 join-node, 这样能加快匹配速度。
1.1.4 Rete 算法的匹配过程
匹配过程以下: 1) 对于每一个事实,经过 select 操做进行过滤,使事实沿着 rete 网达到合适的 alpha 节点。2) 对于收到的每个事实的 alpha 节点,用 Project( 投影操做 ) 将那些适当的变量绑定分离出来。使各个新的变量绑定集沿 rete 网到达适当的 bete 节点。3) 对于收到新的变量绑定的 beta 节点,使用 Project 操做产生新的绑定集,使这些新的变量绑定沿 rete 网络至下一个 beta 节点以致最后的 Project。4) 对于每条规则,用 project 操做将结论实例化所需的绑定分离出来。
若是把 rete 算法类比到关系型数据库操做,则事实集合就是一个关系,每条规则就是一个查询,再将每一个事实绑定到每一个模式上的操做看做一个 Select 操做,记一条规则为 P,规则中的模式为 c1,c2,…,ci, Select 操做的结果记为 r(ci), 则规则 P 的匹配即为 r(c1)◇r(c2)◇…◇(rci)。其中◇表示关系的链接(Join)操做。
Rete 网络的链接(Join)和投影 (Project) 和对数据库的操做形象对好比图 3 所示:
图 3. join and project
1.1.5 Rete 算法的特色、不足和建议 Rete 算法有以下特色:
a. Rete 算法是一种启发式算法,不一样规则之间每每含有相同的模式,所以在 beta-network 中能够共享 BetaMemory 和 betanode。若是某个 betanode 被 N 条规则共享,则算法在此节点上效率会提升 N 倍。
b. Rete 算法因为采用 AlphaMemory 和 BetaMemory 来存储事实,当事实集合变化不大时,保存在 alpha 和 beta 节点中的状态不须要太多变化,避免了大量的重复计算,提升了匹配效率。
c. 从 Rete 网络能够看出,Rete 匹配速度与规则数目无关,这是由于事实只有知足本节点才会继续向下沿网络传递。
Rete 算法的不足:
a. 事实的删除与事实的添加顺序相同, 除了要执行与事实添加相同的计算外, 还须要执行查找, 开销很高 [3]。
b. RETE 算法使用了β存储区存储已计算的中间结果, 以牺牲空间换取时间, 从而加快系统的速度。然而β存储区根据规则的条件与事实的数目而成指数级增加, 因此当规则与事实不少时, 会耗尽系统资源 [3]。
针对 Rete 算法的特色和不足,在应用或者开发基于 Rete 算法的规则引擎时,提出以下建议:
a. 容易变化的规则尽可能置后匹配,能够减小规则的变化带来规则库的变化。
b. 约束性较为通用或较强的模式尽可能置前匹配,能够避免没必要要的匹配。
c. 针对 Rete 算法内存开销大和事实增长删除影响效率的问题,技术上应该在 alpha 内存和 beata 内存中,只存储指向内存的指针,并对指针建里索引(可用 hash 表或者非平衡二叉树)。
d. Rete 算法 JoinNode 能够扩展为 AndJoinNode 和 OrJoinNode,两种节点能够再进行组合 [5]。
优化:
1. 模式尽可能完整和独立,便于规则之间的模式重复利用;
2. 因为规则之间的模式匹配结果会缓存和重复利用,为了尽可能保持规则库稳定不变,规则生效时间放在规则外面,同时,在Action里,禁止修改Facts属性;
3. 在规则里面,约束性较为通用或较强的模式尽可能置前匹配,能够避免没必要要的匹配;
4. 规则包加载后加入缓存,运行期禁止动态加载规则,为了性能和安全;
5. 将数据准备和规则执行拆分,也是为了保持Facts的稳定,利于规则之间的模式复用