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

Drools4:Manners示例分析

阅读更多
  1. /*  
  2.     manners示例是一个安排座位的例子,它的要求如下:  
  3.     1、客人应当按照男女性别相邻而坐,围成一圈  
  4.     2、假设客人会有2-3个个人爱好(爱好的可选范围是3种),为了让大家能够更好的交流,  
  5.        要安排每个人都和相邻座位的两个人有共同的爱好,并且与左右两边的共同爱好不要相同  
  6.     3、客人的人数在本例中为64人,男女各一半  
  7.       
  8.     解题思路:  
  9.     1) 按照规则引擎的特性,首先应当将所有可能的数据准备好,从本例来看,客人是主要的数据对象,  
  10.        姓名/性别/兴趣 是三个主要属性,姓名和性别是固定的,可能有多个选择的就是兴趣爱好,  
  11.        那么首先应当将客人的兴趣分别与姓名/性别组合后放入WorkingMemory  
  12.     2) 再考虑一下,本例中规定了每个客人都会有三种爱好里的两种,也就是说任意两个人都必然有相同爱好  
  13.        只要注意不要性别相同以及两边爱好一致就可以;那么只要先安排一个人坐下(这个人应当三种爱好都有),  
  14.        然后找一个性别不同,有一种相同爱好的客人A坐在左边;接下去找一个坐在A旁边的客人B,同样与A性别  
  15.        不同,并且和前一位的共同爱好也不同。这样一直排下去,直到最后一个座位。这里解释一下为什么一开始  
  16.        第一个人要三种爱好齐备,因为这种算法有一个漏洞是没有考虑第一个客人和最后一个客人是相邻而坐的,  
  17.        如果第一个客人和最后一个客人只有一个共同兴趣而这个兴趣又正好是第一和第二个客人的共同兴趣,那么  
  18.        这种算法会得到不正确的结果,但只要第一个坐下来的人三种爱好都有,那么必然和两边的人都有不同爱好,  
  19.        这也弥补了算法的不同。  
  20.        注:从本例中准备的数据和算法来看并没有考虑到这个问题,虽然按照原始数据可以得到正确的结果,但是  
  21.        进行针对性的调整后就会发现结果会有问题  
  22.     3) 因为座位是一个一个找出来的,因此要有合适的流程控制方法。    
  23.       
  24. */  
  25.   
  26.   
  27. package org.drools.benchmark.manners   
  28.   
  29. # 从客人中找出一位放入第一个座位   
  30. # 根据Drools引擎的特性,应当是最后一个加入的Guest   
  31. # 利用Context.state属性控制该规则只执行一次   
  32. rule assignFirstSeat   
  33.     when   
  34.         # Context用于流程控制   
  35.         context : Context( state == Context.START_UP )   
  36.         #   
  37.         #   原例中使用的是  Guest() , 获得最后插入的Fact,但是这样会引起之前提到的Bug   
  38.         #   因此在下面进行了改进,保证找出三个兴趣都有的客人   
  39.         #   
  40.         guest : Guest( $name:name , $hobby : hobby )   
  41.         Guest ( name == $name , hobby != $hobby , $hobby1 : hobby )   
  42.         Guest ( name == $name , hobby != $hobby , hobby != $hobby1 )   
  43.            
  44.         count : Count()   
  45.     then   
  46.         String guestName = guest.getName();   
  47.            
  48.         # Seating用于记录每个座位上的客人,是寻找下一个座位的客人的依据   
  49.         Seating seating =  new Seating( count.getValue(), 1true1, guestName, 1, guestName);   
  50.         insert( seating );   
  51.            
  52.         # Path用来避免已经入座的客人再次被选中   
  53.         Path path = new Path( count.getValue(), 1, guestName );   
  54.         insert( path );   
  55.            
  56.         # 用于计数,并作为Seating的ID   
  57.         count.setValue(  count.getValue() + 1 );           
  58.         update( count );   
  59.   
  60.         System.out.println( "assign first seat :  " + seating + " : " + path );   
  61.   
  62.         # 进入找下一个座位环节   
  63.         context.setState( Context.ASSIGN_SEATS );           
  64.         update( context );   
  65. end   
  66.   
  67. # 寻找相邻的同伴   
  68. rule findSeating   
  69.    when    
  70.        context : Context( state == Context.ASSIGN_SEATS )   
  71.        # 获得最近安排好座位的客人   
  72.        $s:Seating( seatingId:id, seatingPid:pid, pathDone == true, seatingRightSeat:rightSeat, seatingRightGuestName:rightGuestName )   
  73.        # 找到一位有共同兴趣但性别不同的相邻客人   
  74.        Guest( name == seatingRightGuestName, rightGuestSex:sex, rightGuestHobby:hobby )   
  75.        Guest( leftGuestName:name , sex != rightGuestSex, hobby == rightGuestHobby )   
  76.   
  77.        count : Count()   
  78.        # 排除已经入座的客人   
  79.        #   
  80.        # 原例中使用了Path.id作为一个约束条件,而事实上要排除已经入座的客人只要判断guestName就可以了   
  81.        # 因此原例中的makePath规则如果注释掉,然后将下面的语句改为   
  82.        # not ( Path( guestName == leftGuestName) )   
  83.        # 执行后也可以得到完全相同的结果   
  84.        # Manners是作为规则引擎的测试基准发布的,因此这里完全按照标准实现,所以这里虽然
  85.        # 可以进行改进,但是可能因为为了测试规则引擎,因此保留这种算法
  86.        #
  87.        not ( Path( id == seatingId, guestName == leftGuestName) )   
  88.           
  89.        # 排除入座客人已经和使用过的兴趣,保证两边相邻的客人共同兴趣不一样   
  90.        not ( Chosen( id == seatingId, guestName == leftGuestName, hobby == rightGuestHobby) )   
  91.    then   
  92.        int rightSeat = seatingRightSeat;   
  93.        int seatId = seatingId;   
  94.        int countValue = count.getValue();   
  95.           
  96.        # 安排一个新的座位   
  97.        Seating seating = new Seating( countValue, seatId, false, rightSeat, seatingRightGuestName, rightSeat + 1, leftGuestName );   
  98.        insert( seating );        
  99.        # 记录已经入座的客人                       
  100.        Path path = new Path( countValue, rightSeat + 1, leftGuestName  );   
  101.        insert( path );   
  102.        # 记录已经使用的兴趣爱好   
  103.        Chosen chosen = new Chosen( seatId, leftGuestName, rightGuestHobby );   
  104.        insert( chosen  );   
  105.   
  106.        System.err.println( "find seating : " + seating + " : " + path + " : " + chosen);   
  107.        count.setValue(  countValue + 1 );   
  108.        update( count );          
  109.   
  110.        context.setState( Context.MAKE_PATH );   
  111.        update( context );   
  112.           
  113.        retract ( $s );   
  114. end   
  115.   
  116. /*  
  117.   这个规则的执行将为之前所有入座的客人建立一个路径  
  118.   如果使用一个打印语句,部分打印内容如下:  
  119.   makePath :[Path id=1, seat=1, guest=63]  
  120.   makePath :[Path id=2, seat=1, guest=63]  
  121.   makePath :[Path id=2, seat=2, guest=52]  
  122.   makePath :[Path id=3, seat=2, guest=52]  
  123.   makePath :[Path id=3, seat=1, guest=63]  
  124.   makePath :[Path id=3, seat=3, guest=64]  
  125.   makePath :[Path id=4, seat=3, guest=64]  
  126.   makePath :[Path id=4, seat=1, guest=63]  
  127.   makePath :[Path id=4, seat=2, guest=52]  
  128.   makePath :[Path id=4, seat=4, guest=50]  
  129.   makePath :[Path id=5, seat=4, guest=50]  
  130.   makePath :[Path id=5, seat=2, guest=52]  
  131.   makePath :[Path id=5, seat=1, guest=63]  
  132.   makePath :[Path id=5, seat=3, guest=64]  
  133.   makePath :[Path id=5, seat=5, guest=62]  
  134.   ......  
  135.   也就是每个id的数值就对应有多少个Path,而事实上这种数据模型对本例来说并不是太需要  
  136.   在之前的findSeating规则中有说明。  
  137. */  
  138. rule makePath   
  139.     when    
  140.         Context( state == Context.MAKE_PATH )   
  141.         Seating( seatingId:id, seatingPid:pid, pathDone == false )   
  142.         $path : Path( id == seatingPid, pathGuestName:guestName, pathSeat:seat )   
  143.         not Path( id == seatingId, guestName == pathGuestName )   
  144.     then   
  145.         System.out.println ( "makePath :" + $path  );   
  146.         insert( new Path( seatingId, pathSeat, pathGuestName ) );   
  147. end    
  148.   
  149. # 结束座位的路径设置   
  150. rule pathDone   
  151.     when   
  152.         context : Context( state == Context.MAKE_PATH )    
  153.         seating : Seating( pathDone == false )    
  154.     then   
  155.         seating.setPathDone( true );    
  156.         update( seating );   
  157.            
  158.         context.setState( Context.CHECK_DONE );    
  159.         update( context );   
  160. end   
  161.   
  162. # 检查是否安排的客人座位已经到达指定人数,结束规则运算   
  163. rule areWeDone   
  164.     when   
  165.         context : Context( state == Context.CHECK_DONE )    
  166.         LastSeat( lastSeat: seat )   
  167.         Seating( rightSeat == lastSeat )    
  168.     then   
  169.         context.setState(Context.PRINT_RESULTS );    
  170.         update( context );   
  171. end   
  172.   
  173. # 如果之前的areWeDone规则没有允许,则继续座位查找   
  174. rule continue  
  175.     when   
  176.         context : Context( state == Context.CHECK_DONE )    
  177.     then   
  178.         context.setState( Context.ASSIGN_SEATS );    
  179.         update( context );   
  180. end   
  181.   
  182. # 打印完成提示   
  183. rule allDone   
  184.     when   
  185.         context : Context( state == Context.PRINT_RESULTS )    
  186.     then   
  187.         System.out.println( "All Done" );   
  188. end   
  189.   
  190. //query getResults   
  191. //  context : Context( state == Context.PRINT_RESULTS )    
  192. //end    
  193.    
分享到:
评论
1 楼 hxpwork 2007-08-15  
另外补充一点,Manners是作为对规则引擎的基准测试发布的,这里的例子是完全按照论文中要求的实现,所以MakePath规则虽然可能有更好的实现方式,但是它存在的目的是为了测验规则引擎的性能,因此被保留下来。

相关推荐

    Drools报错:The Eclipse JDT Core jar is not in the classpath

    标题 "Drools报错: The Eclipse JDT Core jar is not in the classpath" 提示了一个常见的编程问题,即在使用Drools规则引擎时,由于缺少Eclipse JDT(Java Development Tools)核心库,导致运行错误。这个问题涉及...

    drools5.1 规则流示例

    本示例旨在演示如何在Drools 5.1中使用规则流(Rule Flow)进行复杂的业务流程管理。规则流是Drools提供的一种工具,它允许用户通过图形化方式定义规则执行的顺序和条件,从而更好地控制业务逻辑的执行流程。 首先...

    Drools4Demo 示例 非常不错

    通过研究和理解Drools4Demo中的各个示例,开发者可以快速掌握Drools的用法,并将其应用于自己的业务场景,实现高效、灵活的业务规则管理。此外,Drools4Demo还提供了详细的文档和注释,帮助开发者更好地理解和学习...

    Drools规则引擎实现示例

    4. **插入事实**:在示例中,可能会创建一个或多个`Customer`对象并将其插入到工作内存中,例如: ```java KieSession ksession = ...; // 初始化KieSession Customer customer = new Customer(); customer.set...

    drools的使用示例代码

    Drools是一款强大的规则引擎,它...通过分析和实践这个项目,开发者不仅可以掌握Drools的基本用法,还能了解如何在实际项目中灵活运用Drools,实现业务规则的动态管理。这将对提升企业的业务敏捷性和决策效率大有裨益。

    hellodrools:Drools 示例项目

    【标题】"hellodrools:Drools 示例项目"是一个基于Drools规则引擎的实践教程,旨在帮助开发者了解和掌握如何在Java应用程序中使用Drools进行业务规则的管理和执行。 【描述】"你好,Drools 示例项目"表明这是一个...

    drools代码示例包

    这个“drools代码示例包”提供了与CSDN博客文章《Drools实战:一个详尽的指南》相关的示例代码,帮助读者深入理解Drools的工作原理和使用方法。 在Drools中,主要涉及以下几个核心概念: 1. **规则**:规则是...

    Drools规则引擎实现原理及示例

    Drools规则引擎是一种嵌套在应用程序中的组件, 是用Java语言编写的开放源码规则引擎,使用Rete算法对所编写的规则求值。 它实现了将业务规则从程序代码忠分离出来,规则引擎使用特定的语法编写业务规则,规则引擎...

    drools-示例:Drools:规则引擎

    ** drools-examples-master 文件夹内容分析 ** `drools-examples-master` 压缩包很可能包含了 Drools 的示例项目,这些示例通常会演示如何创建、加载和执行规则,以及如何处理事实和规则结果。项目可能包括以下内容...

    drools drools drools drools drools

    4. drools-examples:这可能是一个包含drools使用示例的目录,帮助开发者理解如何在实际项目中应用drools,涵盖了各种规则的创建、加载和执行。 drools 使用DRL(Drools Rule Language)作为规则定义的语言,它支持...

    Drools入门-环境搭建,分析及示例.docx

    4. **Drools Fusion**:专为事件处理和时间推理而设计,它能够实时分析和响应来自不同源的事件,适用于实时决策系统。 5. **Drools Planner**:这是一个自动规划引擎,用于解决复杂的优化问题,如车辆路线规划、...

    Drools4Demo.rar

    在"压缩包子文件的文件名称列表"中,只提到了"Drools4Demo",这可能是整个示例项目的根目录。通常,这样的目录结构会包含以下部分: 1. **bin** 目录:可能包含可执行的Java程序或JAR文件,用于运行Drools示例。 2....

    drools6学习例子

    这部分可能包括各种Drools规则的语法示例,如条件语句(IF-THEN)、逻辑运算符、函数调用、事实模式、积累函数、约束条件等。通过这些例子,你可以了解到如何编写规则来匹配特定的事实对象,并在满足条件时执行相应...

    drools使用的jar包

    drools使用的jar包,运行官方drools-distribution-7.7.0.Final drools使用的jar包,运行官方drools-distribution-7.7.0.Final drools使用的jar包,运行官方drools-distribution-7.7.0.Final drools使用的jar包,运行...

    Drools4 insurance例子

    【Drools4保险例子详解】 Drools4保险例子是一个基于Drools规则引擎的实战项目,展示了如何在J2EE环境下,特别是在使用JBoss应用服务器时,利用Drools进行业务规则管理。这个例子旨在帮助开发者理解如何将Drools...

    drools:流量MVN的实现示例

    标题 "drools:流量MVN的实现示例" 指涉的是使用 Drools 这一规则引擎来处理流量管理的场景,而该场景是通过 Maven(MVN)构建工具来实现的。Drools 是一个强大的业务规则管理系统,它允许开发者通过声明式的方式定义...

    drools5 规则动态加载示例

    在这个"drools5 规则动态加载示例"中,我们将探讨如何在不重启服务的情况下,实现规则的热更新,即动态加载修改后的规则文件,使得业务逻辑能够实时适应变化。 在传统的软件开发中,一旦应用部署,若需更改业务规则...

    drools7.5.0和spring 4.3.12集成示例

    4. **易于维护**:由于 drools 的规则独立于业务代码,更改规则无需重新编译整个项目,降低了维护成本。 总的来说,这个 drools7.5.0 和 spring 4.3.12 的集成示例提供了一个实用的方法,让开发者可以在 Spring ...

    Drools4.x实例

    Drools4.x实例 Drools是一款强大的规则引擎,属于Java开源社区JBOSS的一部分。它基于Business Rule Management System (BRMS)的概念,帮助企业快速实施业务规则,从而提高业务决策的灵活性和效率。在Drools4.x版本...

    Learning-Drools:学习Drools规则引擎

    《深入学习Drools:构建智能业务规则引擎》 Drools是一款强大的开源规则引擎,由Jboss(现为Red Hat)...在"Learning-Drools-master"这个项目中,你可以找到相关的示例代码和教程,进一步加深对Drools的理解和应用。

Global site tag (gtag.js) - Google Analytics