01、背景
技术产生的背景:
概念拆解:规则的引擎
规则,在怎样的情况(条件)下做什么事情(结论),转化为伪代码: IF ... THEN ...
引擎,可以翻译为“加速器”,将复杂问题简单化,笨拙问题灵活化,低效问题高效化,
如大家知道的:搜索引擎、推荐引擎、工作流引擎、 实时规则引擎,都是“专业加速器”。
和 工作流引擎的区别?以贷款处理为例:分风控和放贷审批;其中风控评估就是采用规则引擎进行灵活匹配;而放贷过程则是通过工作流来让多方人员参与审批流转。
技术产生的背景:
规则引擎起源于基于规则的专家系统(CLIPS:源于1984年NASA的人工智能项目),规则引擎通过模拟人类的思考方式,使用试探性推理方法得到结果,并使用人类能够理解的方式证明其结论。
规则引擎把复杂、冗余的业务规则与程序分离,做到架构的可复用移植。通过约定好的规范,接受用户的输入,解析用户的业务规则,最后执行解析好的业务规则作出决策。
一般情况下,所有的业务规则都可以表达成类似IF … THEN的条件语句,但由于企业的快速发展,业务规则会迅速增加,维护和管理这些业务规则会变得越来越困难,而规则引擎将至少具有三个作用:
(1)管理复杂的规则
(2)使用过程不再需要二次编程
(3)知识的管理和发现
以上三方面可以使得业务人员把注意力放到真正有意义的领域,减少重复性工作。从业务的角度上说,重要的是知识的获取和复用,由于规则引擎将规则逻辑从代码中分离,使得业务人员可以着重考虑规则中蕴含的知识,而规则引擎的推理和运行机制又解放了维护人员浪费大量的时间在逻辑判断代码上,在实际应用中起到了巨大的作用。
规则引擎自80年代至今,已经产生了多种商业及开源的产品,基本上都是基于Java开发, 既有商业产品,也有开源项目,其中最出名的是Drools(KIE Knowledge Is Everything 中的一个子项目),KIE解析图:
02、原理
参考:
git库: https://github.com/kiegroup/drools
文档: https://docs.jboss.org/drools/release/7.36.0.Final/drools-docs/html_single/index.html#_welcome
Drools 是一种特定类型的规则引擎:生产规则系统(PRS)。
将Facts( 新事物或现有事实 )和Rules(生产规则)进行模式匹配,由推理引擎执行 。匹配成功时,对应的规则会在Agenda(议程)中被激活并注册;具有大量规则和事实的系统可能导致 许多规则同时匹配相同的事实(术语:断言是正确的); 这些规则会存在冲突,这时议程使用冲突解决策略(Conflict Resolution)管理这些冲突规则的执行顺序。
相关概念
事实,Facts/WME (Element of Working Memory),对象之间及对象属性之间的关系
规则,Rules/PME( Element of Production Memory ),是由条件和结论构成的推理语句,一般表示为if…Then。一个规则的if部分称为LHS(left-hand-side),then部分称为RHS(right hand side)。
Drools核心
Drools基于Rete算法(推理网络)的扩展: ReteOO(加强了面向对象的实现)——>PHREAK( 新懒惰算法)
Rete算法
Rete是拉丁文,对应英文是net,即网络。
其核心思想是用分离的匹配项构造匹配网络,同时缓存中间结果。以空间换时间。规则编译(rule compilation)和运行时执行(runtime execution)。
Part 1、规则编译:根据规则集 生成 推理网络
把规则文件中多个条件作为alpha节点串联起来,如果多个规则文件有相同的条件时就共用一个节点。beta节点用于表示条件的组合,beta节点左边输入多个节点,右边输入单个节点。通过beta节点可以找到命中的规则文件。当传入一个fact时,fact会沿着节点传递,所有节点都有存储功能,可以保留到搭过的fact和语义,使用空间换时间的方式,提升下次匹配规则的速度。
以购车优惠为例(分地区、会员类型、车系 折扣策略不同):
规则1: 北京地区 的 普通会员 购买 哈弗-车系1 ,享受1000元折扣。
规则2: 成都地区 的 普通会员 购买 哈弗-车系1,享受2000元折扣。
规则3: 成都地区 的 普通会员 购买 哈弗-车系2,享受3000元折扣。
规则4: 成都地区 的 Plus会员 购买 哈弗-车系2 ,享受5000元折扣。
// 规则1: 北京地区 的 普通会员 购买 哈弗-车系1 ,享受1000元折扣。
rule "北京地区-普通会员-哈弗-车系1 优惠政策":
when
Area(city == "北京")
Account(type ==“普通会员”)
Product(brand ==“哈弗”,serial == “车系1”)
then
"享受1000元折扣";
规则1,推理网络构建过程:
可以把rete算法类比到关系型数据库操作。把事实集合看作一个关系,每条规则看作一个查询,将每个事实绑定到每个模式上的操作看作一个Select操作,记一条规则为P,规则中的模式为c1,c2,…,ci, Select操作的结果记为r(ci),则规则P的匹配即为r(c1)◇r(c2)◇…◇(rci)。其中◇表示关系的内连接(Join)操作。
AM(Alpha Memory);
wx(Working Memory Element),工作内存元;
Cx(Codition),条件;
Px(Pattern),匹配模式,一个模式对应一个条件组合;
Part 2、运行时执行:将数据送入推理网络进行筛选的过程。
(编译后)推理网络节点图
推理引擎在进行模式匹配时,先对事实进行断言,为每一个事实建立WME(Working Memory Element),然后将WME从RETE鉴别网络的根结点开始匹配,因为WME传递到的结点类型不同采取的算法也不同,所以需要对alpha结点和beta结点处理WME的不同情况而分开讨论。
1)如果Fact/WME (Working Memory Element)的类型和根节点的后继结点TypeNode(alpha结点的一种)所指定的类型相同,则会将该事实保存在该TypeNode结点对应的alpha存储区中,该WME被传到后继结点继续匹配,否则会放弃该WME的后续匹配;
2)如果WME被传递到alpha结点,则会检测WME是否和该结点对应的模式相匹配,若匹配,则会将该事实保存在该alpha结点对应的存储区中,该WME被传递到后继结点继续匹配,否则会放弃该WME的后续匹配:
3)如果WME被传递到beta结点的右端,则会加入到该beta结点的right存储区,并和left存储区中的Token进行匹配(匹配动作根据beta结点的类型进行,例如:selection过滤, join连接,projection投影),匹配成功,则会将该WME加入到Token中,然后将Token传递到下一个结点,否则会放弃该WME的后续匹配:
4)如果Token被传递到beta结点的左端,则会加入到该beta结点的left存储区,并和right存储区中的WME进行匹配(匹配动作根据beta结点的类型进行,例如:join,projection,selection),匹配成功,则该Token会封装匹配到的WME形成新的Token,传递到下一个结点,否则会放弃该Token的后续匹配;
5)如果WME被传递到beta结点的左端,将WME封装成仅有一个WME元素的WME列表做为Token,然后按照 4) 所示的方法进行匹配:
6)如果Token传递到终结点,则和该根结点对应的规则被激活,建立相应的Activation,并存储到Agenda当中,等待激发。
7)如果WME被传递到终结点,将WME封装成仅有一个WME元素的WME列表做为Token,然后按照 6) 所示的方法进行匹配;
03、使用方法
注:本当章节下所有内容的撰写思路与方式:
Springboot整合,通过规则管理中心进行规则管理配置。对应的规则文件drl , Drools Rule Language 的缩写。
1、规则有哪些维护方式?
通过库表 及文件:XML、JSON、Excel文件 都可以。
2、如何通过库表维护?
将规则以字符串方式维护进库表中;
然后读取出来,加载进临时drl文件中;
以KieBuilder方式编译所有规则,返回编译结果;
将编译后的规则 + 事实 都放入决策引擎中——》触发。
3、如何解决高频问题?
Kie sessions
无状态会话,应用场景(确认有效性、计算应用、路由及过滤),个人理解:一次性的,无需状态保持传递就能实现的,通过java 提供的modify 来设置字段,返回相应结果。
有状态会话,应用场景(监控、诊断、物流、合规性),个人理解:存在推理逻辑,需要保持状态并传递。
操作事实Facts的几种方式:
// 添加事实,方式一:
kSession.insert(account);
kSession.insert(area);
kSession.insert(product);
// 添加事实,方式二:
kSession.execute(ks.getCommands().newInsertElements(Arrays.asList(new Object[] {account, area, product})));
// 添加事实,方式三:
KieCommands kieCommands = ks.getCommands();
List<Command> cmds = new ArrayList<>();
cmds.add(kieCommands.newInsert(account));
cmds.add(kieCommands.newInsert(area));
cmds.add(kieCommands.newInsert(product));
kSession.execute(kieCommands.newBatchExecution(cmds));
// 添加事实,方式四:
FactHandle accountHandle = kSession.insert(account);
FactHandle areaHandle = kSession.insert(area);
FactHandle productHandle = kSession.insert(product);
// 之后可以删除、修改
kSession.delete(areaHandle);
解决高频的sessions操作:sessions pools(会话池)
// 初始会话数 10个
pool = kContainer.newKieSessionsPool(10);
KieSession kSession = pool.newKieSession();
04、应用场景
介绍如何应用场景:
CRM系统
风控模型配置,风控是规则引擎,参考 有赞风控规则引擎
用户积分等配置
简单的离线计算,各类数据量比较小的统计等
05、延展
关联技术的延展介绍
1、知识表示和推理 (KRR,Knowledge Representation and Reasoning),人工智能的核心。
2、推理技术:
正向链接 被动和数据驱动(data driven)的推理技术。从已知数据开始展开推理。每一次只执行顶端的一条规则。当有规则被触发时,就有新事实加入数据库。这个新的事实的改变又触发了另外一条规则(任何规则只能触发一次)当没有规则可触发时,循环终止。
后向链接 目标驱动的推理技术(被动查询)。在后向链接中,假设一个既定的结果,从所有规则中的THEN部分有这个结果的,并且数据符合要求。就触发这一条规则。如果不符合就继续以这个IF作为一个下一个规则的THEN部分继续往前推导,看是否符合数据,循环往复,直到所有规则,数据都不可以满足IF的设定。
3、Drools, PRS(生产规则系统)——> 采用混合推理系统(HRS)
正向链接是“数据驱动的”,因此是反动的,事实被置于工作记忆中,这导致一个 或多个规则同时成立并安排由议程执行。简而言之,我们从一个事实开始,它通 过规则传播,我们最终得出结论。
向后链接是“目标驱动的”,这意味着我们从引擎试图满足的结论开始。如果不能, 那么它会搜索它可以满足的结论。这些被称为子目标,将有助于满足当前目标的 一些未知部分。它继续这个过程,直到初步结论得到证实或没有更多的子目标。 Drools 也可以进行反向链接, 我们将其称为派生 查询:
4、专家系统
用于特定领域的系统