Rete算法

一、简介

  • Rete算法:是一种高效的模式匹配算法用来实现产生式规则系统

    空间换时间,用内存换取匹配速度

  • Rete算法通过规则条件生成了一个网络,每个规则条件是网络中的一个节点
  • rete 分为:
    • 规则编译:指根据规则集生成推理网络的过程
    • 运行时执行: 指将数据送入推理网络进行筛选的过程

二、规则编译

规则编译:根据规则文件推理生成网络的过程

在这里插入图片描述

1. 根节点(RootNode)

  • 是所有对象进入网络的入口,然后进入到 TypeNode

2. TypeNode

  • 是 fact,即规则所用到的 pojo
    • 每个 fact 是一个 TypeNode
    • TypeNode 就是类型检查,引擎只让匹配 Object 类型的对象到达节点,

    能够传播到 AlphaNodes、LeftInputAdapterNodes (作为betaNodes的左端输入节点)和 BetaNodes

举例:有两个fact ,Person 和cheese,则节点图如下所示
在这里插入图片描述

3. AlphaNode

首图的蓝色节点

  • 用来评估字面条件

    例如: person.age>10 就是一个 alpha node 节点
    当一条规则有多条字面条件,这些字面条件被链接到一起

Drools 通过散列法优化了从 ObjectTypeNode 到 AlphaNode 的传播:

  • 每次一个 AlphaNode 被加到一个 ObjectTypeNode 时,就以字面值作为 key ,以 AlphaNode 作为 value 加入 HashMap
  • 当一个新的实例进入 ObjectTypeNode 时,不用传递到每一个 AlphaNode ,直接从 HashMap 中获得正确的 AlphaNode ,避免不必要的字面检查

4. Bate Node

  • 用来对两个对象进行对比、检查

约定 BetaNode 的两个输入称为左边(Join Node)和右边(NotNode):

  • 左边通常是一个 a list of objects

    左边的输入被称为 Beta Memory,会记住所有到达过的语义

  • 右边通常是 a single object

    右边的输入成为 Alpha Memory,会记住所有到达过的对象

5. 构建 rete 网络

  • 创建根节点

  • 加入一条规则
    a. 取出规则中的一个模式 ,检查模式中的参数类型,如果是新类型(即新 fact 类型),则加入一个类型节点

    模式就是规则中的最小一个匹配项例如(如: age>10;age<20)

    b. 检查模式对应的 Alpha 节点是否已存在:

    • 若已存在,则记录下节点位置
    • 若未存在,则将模式作为一个 Alpha 节点加入到网络中,同时根据 Alpha 节点的模式建立 Alpha 内存表

    c. 重复 b 直到所有的模式处理完毕
    d. 组合 Beta 节点: Beta 左输入节点为 Alpha(1),右输入节点为 Alpha(2)

    Beta(i) 左输入节点为 Beta(i-1),右输入节点为 Alpha(i)

    e. 重复 d 直到所有的 Beta 节点处理完毕
    f. 将动作(Then 部分)封装成叶节点(Action 节点)作为 Beta(n) 的输出节点

  • 重复 2) 直到所有规则处理完毕

案例
  • 案例一

    举例:条件 Cheese (name=”cheddar”), Person(favouriteiteCheese==”cheese.name”)
    关联操作: Cheese.name == Person.favouriteiteCheese
    节点图如下所示:
    在这里插入图片描述

    • 黄色 node 称为 LeftInputAdapterNode,作用是将一个 single Object 转化为一个单对象数组,传播到 JoinNode 节点
  • 案例二:drools

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

    在这里插入图片描述

    • Drools 通过节点的共享来提高规则引擎的性能

三、运行时执行

  • WME:工作存储区元素(Working Memory Element,存储区的最小单位),WME 是为事实建立的元素,是用于和非根结点代表的模式进行匹配的元素
  • Token:WME 列表,包含多个 WME

RETE 算法对于不同结点,进行 WME 或 token 和结点对应模式的匹配过程:

  • 若 WME 的类型和根节点的后继结点 TypeNode 所指定的类型相同,则将该事实保存在该TypeNode 结点对应的 alpha 存储区,该 WME 被传到后继结点继续匹配或放弃后续匹配

    TypeNode 存储: 每次一个 AlphaNode 被加到一个 ObjectTypeNode 时,就以字面值作为 key,以 AlphaNode 作为 value 加入 HashMap

    • 当一个新的实例进入 ObjectTypeNode 时,可以直接从 HashMap 中获得正确的 AlphaNode,避免了不必要的字面检查
  • 若 WME 被传递到 alpha 结点,则会检测 WME 是否和该结点对应的模式相匹配:

    • 若匹配,则会将该事实保存在该 alpha 结点对应的存储区中,该 WME 被传递到后继结点继续匹配
    • 否则会放弃该 WME 的后续匹配

    alpha 存储:检测 WME 是否和该结点对应的模式相匹配

    • 若匹配,则将该事实保存在该 alpha 结点对应的存储区中,该 WME 被传递到后继结点继续匹配
  • 若 WME 被传递到 beta 结点的右端,则会加入到该 beta 结点的 right 存储区,并和 left 存储区中的 Token 进行匹配:

    • 匹配成功,则会将该 WME 加入到 Token 中,然后将 Token 传递到下一个结点
    • 否则会放弃该 WME 的后续匹配

    bate 存储区:每个非根结点都有一个存储区

    • 1-input(alpha) 结点有 alpha 存储区和一个输入口
    • 2-input(bate) 结点有 left 存储区和 right 存储区和左右两个输入口
      其中 left 存储区是 beta 存储区,right 存储区是 alpha 存储区

    WME 是为事实建立的元素,是用于和非根结点代表的模式进行匹配的元素

  • 若 Token 被传递到 beta 结点的左端,则会加入到该 beta 结点的 left 存储区,并和 right 存储区中的WME进行匹配:

    • 匹配成功,则该 Token 会封装匹配到的 WME 形成新的 Token,传递到下一个结点
    • 否则会放弃该 Token 的后续匹配
  • 若 WME 被传递到 beta 结点的左端,将 WME 封装成仅有一个 WME 元素的 WME 列表做为 Token,然后按照上述所示的方法进行匹配

  • 若 Token 传递到终结点,则和该根结点对应的规则被激活,建立相应的 Activation,并存储到Agenda 当中,等待激发

  • 若 WME 被传递到终结点,将 WME 封装成仅有一个 WME 元素的 WME 列表做为 Token,然后按照上述所示的方法进行匹配

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值