`
hxpwork
  • 浏览: 110890 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

技巧:使用规则寻找最大值

阅读更多
 

使用规则寻找最大值<o:p></o:p>

<o:p> </o:p>

<o:p> </o:p>

原文网址:http://wiki.jboss.org/wiki/Wiki.jsp?page=RulesFindMax<o:p></o:p>


有时你可能想查找fact的最大值。你可以通过使用not实现这个目的,如下例所示(如果你喜欢也可以将它放在一个Query中):<o:p></o:p>

<o:p> </o:p>

rule "Highest Temperature for a Day"<o:p></o:p>

       when<o:p></o:p>

               Day(highest : temp)<o:p></o:p>

               not Day(temp > highest)<o:p></o:p>

       then...<o:p></o:p>

<o:p> </o:p>

感谢Mitch Christensen 提供建议. <o:p></o:p>

[译者注:<o:p></o:p>

   这里为一些初学者解释一下上面规则的执行思路,在说明之前我们先回顾Drools中对于Fact匹配有一个原则:在没有限制条件的情况下,引擎寻找最大限度的组合<o:p></o:p>

   回到规则分析,假设在Working Memory中设置了三个Day对象,temp分别是102030;那么考虑一下规则引擎如何执行。<o:p></o:p>

   首先规则的第一个条件是Day(highest : temp)没有对Day有过滤限制,则上面三个Day对象都会尝试激发"Highest…"规则。假设Day(10)先进入,则对第二个条件,因为highest是上一个条件传过来的变量,所以引擎会为highesttemp建立3种组合:[ Day(10) , Day(10) ] [ Day(10) , Day(20) ] [ Day(10) , Day(30) ],显然后两种组合对于not Day(temp > highest)是不成立的。由此类推只有当Day30)尝试激发规则时才能满足两个条件。<o:p></o:p>

]<o:p></o:p>


Fact的排序过程<o:p></o:p>

类似的方法通常用来对一组关联的fact进行排序处理。例如,要按照timestamp(时间戳)的顺序处理一组Alert Fact,你可以如下进行:<o:p></o:p>

rule "Process Alerts by time received"<o:p></o:p>

    when<o:p></o:p>

        $alert : Alert($oldest : timestamp)<o:p></o:p>

        not Alert(timestamp < $oldest)<o:p></o:p>

    then<o:p></o:p>

        // process the Alert in some application specific way<o:p></o:p>

        $alert.process()<o:p></o:p>

<o:p> </o:p>

        // 必须将处理过的AlertWorking Memory中删除<o:p></o:p>

        // 否则引擎不会对Working Memory中的Fact重新评估<o:p></o:p>

        retract($alert);<o:p></o:p>

end<o:p></o:p>

该规则将按照Alert中的timestamp属性的早晚来依次进行处理,完成处理的Alertworking memory中删除,接着进行下一个的处理。<o:p></o:p>

-Mitch Christensen <o:p></o:p>


Mitch 提供的这种模式是最简单的但不是最有效率的。简单来说,如果有1000Day对象在Working Memory中,则引擎要对 (1+2+…+1000)种组合进行判断(考虑到Drools引擎在碰到第一个不满足条件的组合时就会抛弃Fact)。显然在Day对象数量过于庞大时,这种判断方法会成为性能瓶颈。因此下面是改进后的判断最大值规则:<o:p></o:p>

<o:p> </o:p>

rule "Try day"<o:p></o:p>

   when<o:p></o:p>

       $d : Day($temp : temp)<o:p></o:p>

   then<o:p></o:p>

       assert(new TryDay($d));<o:p></o:p>

end<o:p></o:p>

<o:p> </o:p>

rule "Highest unknown"<o:p></o:p>

   when<o:p></o:p>

       $attempt : TryDay($d : day)<o:p></o:p>

       not (Highest())<o:p></o:p>

   then<o:p></o:p>

       assert (new Highest($d));<o:p></o:p>

end<o:p></o:p>

<o:p> </o:p>

rule "Highest lower"<o:p></o:p>

   when<o:p></o:p>

       $highest: Highest($highDay : day)<o:p></o:p>

       $attempt : TryDay($day : day -> ($day.getTemp() > $highDay.getTemp()))<o:p></o:p>

   then<o:p></o:p>

       $highest.setDay($day);<o:p></o:p>

       modify($highest);<o:p></o:p>

end<o:p></o:p>

<o:p> </o:p>

rule "Highest higher"<o:p></o:p>

   when<o:p></o:p>

       Highest($highest: day)<o:p></o:p>

       $attempt : TryDay($day : day -> ($day.getTemp() <= $highest.getTemp()))<o:p></o:p>

   then<o:p></o:p>

       retract($attempt);<o:p></o:p>

end<o:p></o:p>

rule "Print highest"<o:p></o:p>

   salience -10<o:p></o:p>

   when<o:p></o:p>

       Highest($day : day)<o:p></o:p>

   then<o:p></o:p>

       System.out.println("Highest day is " + $day);<o:p></o:p>

end<o:p></o:p>

Steven Williams <o:p></o:p>

经过测试,当Day的数量为1000时,Mitch的规则执行时间约2000毫秒,而Steven的规则为223毫秒;当Day的数量为2000时,Mitch的规则执行时间约8000毫秒,而Steven的规则为345毫秒<o:p></o:p>


更多关于查找最大值<o:p></o:p>

查找最大值的问题通常并不限制于对单个属性或字段进行比较。<o:p></o:p>

<o:p> </o:p>

当面对这个问题时,让我们概括它为“发现最好”或“发现最佳”的模式,这在现实中是非常有可能碰到的。如最好的投资机会,最好的网络节点,最好的保险策略等等。

这些问题有两个特点使得采用基于规则的方法具有吸引力。第一,当最好的标准经常发生变更时,规则允许我们在代码外对此进行调整(例如:对于有小孩的家庭最好的新家不一定就是没有小孩家庭的最佳选择). 第二, 最好的可能是复杂的事务, 常常难以用语言捕捉,更不用说在程序开发语言中了。

Steven Williams
在上面提供的方案,一旦在碰到更多的判断属性时,当保持性能时,规则的规模将会增加的很快。<o:p></o:p>

假设我们的任务不是仅仅发现最高的温度,而是有一个组合的温度——最高的温度与最高的dewPoint

<o:p></o:p>

public class HeatRecord<o:p></o:p>

{<o:p></o:p>

    int temp;<o:p></o:p>

    int dewPoint;<o:p></o:p>

    .<o:p></o:p>

    .<o:p></o:p>

}<o:p></o:p>

一个简单的解决方案可能是: <o:p></o:p>

rule "Filter" // 测试每一个,如果被另一个超越则删除<o:p></o:p>

        salience 100<o:p></o:p>

        when<o:p></o:p>

               HR1 : HeatRecord($t1:temp, $d1:dewPoint )<o:p></o:p>

               HeatRecord( temp > $t1 ) || HeatRecord( temp == $t1, dewPoint > $d1  )<o:p></o:p>

        then <o:p></o:p>

               retract( HR1 );<o:p></o:p>

end<o:p></o:p>

<o:p> </o:p>

rule "Report" // 报告留下了什么<o:p></o:p>

        salience 50<o:p></o:p>

        when<o:p></o:p>

               HR1 : HeatRecord( )<o:p></o:p>

        then<o:p></o:p>

               System.out.println("The Most Sweltering Conditions were: " + HR1.getTemp() +" "+ HR1.getDewPoint() ); <o:p></o:p>

end<o:p></o:p>

<o:p> </o:p>

如果我们试图使用Steven Williams 提到的方法,它将会是多大?怎样维护? <o:p></o:p>

想一想?
Mike Panihill <o:p></o:p>

<o:p> </o:p>

分享到:
评论

相关推荐

    动态规划求表达式最大值

    在这个场景中,“动态规划求表达式最大值”指的是利用动态规划策略来寻找一种在给定表达式中添加括号的方式,以最大化表达式的计算结果。 首先,我们需要理解表达式。表达式通常由数字、运算符(如加号"+"、减号"-...

    matlab-(含教程)基于PSO粒子群优化的三维曲面最大值搜索matlab仿真

    在本资源中,我们主要探讨的是使用MATLAB进行三维曲面的最大值搜索,具体方法是应用粒子群优化(PSO)算法。MATLAB是一种强大的编程环境,尤其在数学建模和数值计算方面,而PSO则是一种全局优化算法,常用于解决复杂...

    找出一个序列中前M个大值对应的索引(堆排序实现)

    通过分析这个C语言实现,你可以更深入地了解如何将堆排序算法应用于寻找序列中前M个最大值的索引。这个过程涉及到了数据结构、算法设计以及C语言的编程技巧,对于提升编程能力非常有帮助。 总结起来,解决这个问题...

    C语言考试系统试题(库)~5~数组.doc

    上述题目涉及到了数组在处理各种计算和操作时的应用,包括计算平均值、寻找最大值及其下标、逆序输出数组元素、交换最小值和最大值的位置、选择法排序、计算字符串长度、统计大写辅音字母的数量、查找特定字符以及...

    c语言.pdf

    3. **最大值乘积**:找出最大值,然后与最小值相乘,可能需要两次遍历数组。 4. **数值保留小数位**:涉及浮点数处理和四舍五入规则。 5. **分段函数**:根据输入值选择不同计算方式,需要if-else或switch-case结构...

    Engineering Math - Matlab Programming

    - 寻找最大值:max函数。 - 寻找最小值:min函数。 - 多个值的最大/最小:使用维度参数。 - **求和和乘积** - 累加:sum函数。 - 累乘:prod函数。 - 条件求和:使用逻辑索引。 - **统计分析** - 平均值、...

    "C语言程序设计大赛”模拟题库

    30. 最大值移到链表尾部:遍历链表,找到最大值,将其移动至尾部。 31. 删除指定范围链表元素:理解链表结构,修改指针关系。 32. 报数游戏:循环遍历链表,实现淘汰逻辑。 33. 链表节点移动:修改节点指针,实现...

    源代码使用说明[归纳].pdf

    - **ArraySample3**:介绍寻找数组最大值和最小值的技巧。 - **InputAndOutputAC-String**:解释 C 风格字符串的输入输出操作。 - **GetC-String**:说明函数 get() 和 getline() 的使用方法。 - **CinAndGet**...

    C语言编程练习60题.pdf

    4. 求7的倍数之和:使用循环结构,检查每个数是否是7的倍数,如果是,则累加到总和中。 5. 方阵右下三角元素之和:理解矩阵的结构,从第一个非零元素开始,逐行累加到总和。 6. 判断水仙花数:对于三位数,分解每...

    数据分析相关的教程、技巧、案例、代码、工具使用.docx

    或者通过聚合函数(如均值、最大值等)生成新的统计特征。 5. **模型选择**: - **考量因素**:根据问题类型(如预测、分类、聚类等)、数据特性及业务需求来决定使用哪种类型的模型。 - **常见算法**:对于分类...

    C语言编程题库.pdf

    4. 条件判断:寻找最大值或最小值需要使用条件语句,如`if`或`switch`,并与当前最大或最小值比较。 5. 函数使用:题目7要求根据给定公式计算s,可以定义一个函数接收n作为参数,返回计算结果。 6. 数的反转:题目...

    线性规划建模的疑问处理及技巧

    其中,决策变量是指模型中的未知数,目标函数则是需要最大化或最小化的线性表达式,而约束条件则规定了决策变量之间的关系及其范围。 #### 二、线性规划模型的性质 1. **比例性**:每个决策变量对目标函数和约束...

    图论- 网络流- 基本概念与建模技巧.rar

    - **最大流最小割定理**:寻找网络的最大流等价于找到最小割,即最小容量的边集合,使得源点与汇点被分隔。 3. **算法** - **Ford-Fulkerson方法**:通过寻找增广路径来逐步增加流量,直到无法找到增广路径为止。...

    优化算法的MATLAB实现技巧(单).docx

    根据提供的文档信息,本文将重点讨论优化算法在MATLAB中的实现技巧,特别是针对旅行商问题(Traveling Salesman Problem, TSP)的禁忌搜索算法(Tabu Search Algorithm)。以下是基于文档内容提炼的关键知识点: ##...

    CCF CSP 2016.09 第8次题目答案代码.docx

    - **问题描述:** 给定一系列整数,求解相邻整数之间的最大波动值(即相邻两数差的绝对值的最大值)。 - **解决方案:** 遍历数组,计算相邻元素间的差值,并更新最大波动值。 - **代码实现:** - **变量声明:** 定义 ...

    zuidaliu.rar_matlab最大流_最大流 MATLAB

    这个流量是所有可行流中的最大值,同时满足两个关键条件:流量守恒和容量约束。流量守恒意味着每个中间节点的流入流量等于流出流量;容量约束则规定每条边的流量不能超过其自身的容量。 MATLAB中的最大流算法通常...

    c语言程序设计复习题库 (2).pdf

    10. **累加和超过特定值**:使用循环累加,检测累加和何时超过目标值。 11. **百钱买百鸡问题**:经典的线性代数问题,找到满足条件的整数解。 12. **素数寻找**:遍历指定范围,使用质数判定算法(如埃拉托斯特尼...

    双指针算法,算法练习代码练习

    4. **滑动窗口最大值/最小值**:在处理动态窗口的最大值或最小值问题时,可以使用两个指针,一个指向当前窗口的起始位置,一个指向下一个可能的窗口起始位置,通过更新最大值或最小值来维护窗口的状态。 5. **解题...

Global site tag (gtag.js) - Google Analytics