无规则采集器列表算法(入门凑合着看吧的规则引擎需要注意的问题(图))

优采云 发布时间: 2021-11-07 09:12

  无规则采集器列表算法(入门凑合着看吧的规则引擎需要注意的问题(图))

  翻翻旧文,有很多地方比较模糊,可惜现在找不到jess的源码了,不然可以好好看看实现细节,移过去再说,以后会研究,作为介绍,大家看看吧。

  Rete算法最早由Charles Forgy在1979年的论文中提出,针对的是一种基于规则知识性能的模式匹配算法。目前大部分的规则引擎还是基于rete算法,但是已经有所改进,比如drool,jess等,下面介绍rete算法的概念,一些术语,以及需要注意的问题使用规则引擎时要注意。

  我们来看看下面的表达式:

  (此产品的名称

  LHS /* 一个或多个条件 */

  -->

  RHS /* 一个或多个动作 */

  )

  name-of-this-production 是规则,LHS(左手边)一系列条件,RHS(右手边)这是我们满足条件后应该执行的动作。

  

  结合这张图来介绍几个概念:

  生产记忆(PM)由所有生产形成。

  工作记忆(WM)由外部输入根据匹配算法形成。它反映了运行规则引擎的状态,记录了各种数据。WM 中的每一项都称为工作记忆元素(WME),它是由外部输入生成的。

  议程负责匹配、解决冲突和执行操作。

  Rete 的意思是网络(拉丁语),它最终解释(或编译)所有规则,生成一个识别网络,包括 alpha 网络和 beta 网络。alpha 网络是由 LHS 生成的网络。它根据外部输入快速识别条件是否成立,并与其beta网络交互更新整个网络的状态,如下图所示:

  

  最基本的alpha网络如上图所示。与此类似,所有条件都解析为这样的网络。当外界输入wme时,wme就会进入这样的网络进行识别。如果到达底部,则证明条件成立。当然,如图所示的网络是最简单的实现。实际的规则引擎需要提供更快的算法来识别输入的wme,比如将图中颜色的各种值存储在hashtable,或者jumptable,或者是trie树中。整个alpha网络是一个巨大的字符串匹配过滤网络,需要结合各种数据结构来实现海量条件下的快速匹配。各种规则引擎的实现不一致,比如jess,如下图:

  (除费完成

  (测试)

  (号码?号码)

  (测试完成)

  (初始信用5)

  (客户年龄?年龄)

  (有?输入“PP”))

  =>

  (断言(测试完成)))

  

  在此生产说明之后生成的网络。这里我们首先关注红色节点。这些节点是 alpha 网络的节点。该图仅描述了一般过程。以第一列为例。第一个红色节点表示输入是否匹配。TESTING这个字符串,TESTING匹配0后第二个节点是否匹配参数个数(slot),如果我们将TESTING断言到WM中,那么这个事实就可以匹配到done规则的第一个条件,其他的可以在以此类推,值得注意的是最后一个条件,has 是我们自定义的函数,与这个函数类似,jess 并没有生成单独的列,而是将其用作 CUSTOMER AGE 标记列中的最后一个节点。这个条件有一个特点就是需要执行一段代码来判断某个事实是否为真(不仅仅是执行字符串操作)。这段代码不仅是字符串匹配,还具有实时性。像这样的条件的发展需要注意,因为alpha网络在运行时会多次执行条件。这是由匹配算法的特性决定的。因此,我们需要利用缓存或规则语言的特性来避免不必要的代码执行来提高性能。因为 alpha 网络将在运行时多次执行条件。这是由匹配算法的特性决定的。因此,我们需要利用缓存或规则语言的特性来避免不必要的代码执行来提高性能。因为 alpha 网络会在运行时多次执行条件。这是由匹配算法的特性决定的。因此,我们需要利用缓存或规则语言的特性来避免不必要的代码执行来提高性能。

  下面发布了一个更复杂的示例:

  

  

  图片太大,剪不下来。. . . . .

  让我们用两个例子来谈谈 beta 网络。当 alpha 网络过滤后条件成立,WME 传递给 beta 网络后,绿色节点就会发挥作用。这个节点是加入节点。它有两个输入和一个连接。节点,一个 alpha 节点(红色)。join节点由多个WME组成。对于初始连接节点,我们称其为左输入适配器。作为左输入的join节点,这个节点只收录一个WME,下一个join节点收录两个WME,以此类推。图中天蓝色节点上方的join节点正好符合生产执行所需的条件,所以这条规则被激活,等待执行。

  假设我们需要编辑业务逻辑,那么最好的描述载体就是流程图。一个简单的流程图收录以下基本单元:起始节点、逻辑判断、执行动作、结束节点。这些节点可以完成最简单的业务逻辑描述,那么当我们将这些流程解析为规则时,我们会怎么做呢?第一个逻辑判断单元返回真,所以我们执行某个动作,第二个和第三个逻辑判断单元返回真时,我们执行一个动作,相当于解析为两条规则,满足条件1,触发生产1,满足条件 2、3 和触发生产 2。使用beta网络,我们只需要在触发production2时判断condition2, 3是否被触发。是的,对于更复杂的情况,beta 网络可以提高速度并避免重复匹配。

  在开发中使用规则引擎也存在一些问题,总结如下:

  1) 在规则引擎中对特殊条件的处理中,由于条件会在部分产生中重复出现,会造成条件的重复匹配,影响程序的性能。这应该与项目结合以优化解析或规则脚本。使用缓存来提高性能。补充:可以把动态执行的条件放在LHS的最后,保证只在必要的时候才执行。当然,具体情况还要看具体规则引擎的实现。

  2)内存消耗问题,rete算法是空间换时间,所以内存消耗比较大,尤其是在加载规则时(生成网络),运行时内存会增长缓慢,所以gc效率需要注意的同时,单台服务器所能承受的压力(多WM)也与规则引擎密切相关。

  3)测试。对于使用规则来表达业务的系统来说,如何测试是一个必须解决的问题。对于这个问题,只能保证基本的流程分支覆盖测试。在复杂的情况下很难发现缺陷,但有一些原则需要注意。如果要使用规则引擎,就必须完全以规则引擎为核心。对于业务逻辑,我们必须尽可能提取规则引擎来实现。扩展实现的函数粒度一定要小而简单,不要往代码里走。实现业务逻辑。

  4)大部分条件需要保持不变,也就是说基本信息需要保持稳定。比如某客户公司下属集团的信用额度大于100w,这个额度变化的频率不会很高,不需要实时匹配。

  5)remove WME 生产是一个比较复杂的操作。当规则比较复杂时,你应该尽量少做。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线