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

drools4: Conway示例分析

阅读更多
  1. /*  
  2.     Conway: 元细胞自动机模型,俗称生命游戏  
  3.     它有些类似于一张围棋棋盘,但是可以更大。每个棋盘上的格子(元细胞)只能是生/死两种状态之一。  
  4.     游戏遵循下面的规则  
  5.     1)格子的状态只能是生/死两种状态之一  
  6.     2)格子以其上下左右及斜角方向的8个格子为邻居  
  7.     3)一个格子的生死由其在该时刻本身的生死状态和周围八个邻居的状态 (确切讲是状态的和)决定:  
  8.         a、在当前时刻,如果一个格子状态为"生",且八个相邻格子中有两个或三个的状态为"生",  
  9.            则在下--时刻该格子继续保持为"生",否则"死"去;  
  10.         b、在当前时刻。如果一个格子状态为"死"。且八个相邻格子中正好有三个为"生"。  
  11.            则该格子在下一时刻 "复活"。否则保持为"死"。  
  12.  
  13.     元细胞自动机模型已在多方面得到应用。它的演化规则近似地描述了生物群体的生存繁殖规律:  
  14.     在生命密度过小(相邻元胞数<2) 时,由于孤单、缺乏配种繁殖机会、缺乏互助也会出现生命危机,元胞状态值由1变为0;  
  15.     在生命密度过大 (相邻元胞数>3)时,由于环境恶化、资源短缺以及相互竞争而出现生存危机,元胞状态值由1变为0;  
  16.     只有处于个体适中(相邻元胞数为2或3)位置的生物才能生存(保持元胞的状态值为1)和繁衍后代(元胞状态值由0变为1)。  
  17.     正由于它能够模拟生命活动中的生存、灭绝、竞争等等复杂现象,因而得名"生命游戏"。  
  18.     J·H·Conway还证明,这个元胞自动机具有通用图灵机的计算能力(谢惠民,1994;李才伟,1997),  
  19.     与图灵机等价,也就是说给定适当的初始条件,生命游戏模型能够模拟任何一种计算机。  
  20.  
  21.       
  22.     本示例设计到界面显示,用到的类比较多,这里简单说明一下每个类的用途,不再详细列举代码  
  23.     AbstractRunConway.java              建立GUI界面  
  24.     ConwayGUI.java                      在这里定义好了界面,以及按钮相关事件  
  25.     CellGridCanvas.java                 绘制界面  
  26.     ConwayRuleFlowGroupRun.java         继承AbstractRunConway,使用规则流模式启动程序  
  27.     ConwayAgendaGroupRun.java           继承AbstractRunConway,使用Agenda组模式启动程序,之前版本不推荐  
  28.     ConwayApplicationProperties.java    用于从conway.properties中读取预定义的属性  
  29.     ConwayRuleDelegate.java             作为Agenda和规则流两种模式的统一接口  
  30.     *RuleFlowDelegate.java              规则流模式行为响应代理,界面按钮的动作由该类转发给规则引擎,引起WorkingMemory中的变化  
  31.                                         使用规则流控制规则执行时,针对应用的不同操作共使用了4组规则流如下:  
  32.                                         初始化init - 规则流"register neighbor"  
  33.                                         产生下一步的变化nextGeneration - 规则流"generation",连续变化通过重复调用该步骤进行  
  34.                                         清除killAll - 规则流"kill all"  
  35.                                         模式设置setPattern - 规则流"calculate"  
  36.     AgendaGroupDelegate.java            Agenda模式行为响应代理,作用同上  
  37.     Cell.java                           代表一个格子,有行列属性和状态属性  
  38.     CellGrid.java                       控制表格的抽象接口  
  39.     *CellGridImpl.java                  表格接口的实现,用于向规则引擎中插入数据,以及调用响应代理  
  40.                                         数据的插入分为两种情况  
  41.                                         1、初始化棋盘  
  42.                                             将代表棋盘的CellGrid实例插入  
  43.                                             将棋盘上的每一个格子产生一个Cell对象插入  
  44.                                         2、设置初始模式  
  45.                                             根据提供的模式数组长宽向棋盘中间对齐,对于True的数组数据  
  46.                                             修改对应格子的Cell状态为Live  
  47.     CellState.java                      格子状态(生/死)  
  48.     Phase.java                          在规则中用于控制格子处理的阶段,间接影响格子的状态  
  49.     Neighbor.java                       用于保存两个格子之间的邻居关系  
  50.       
  51.     ConwayPattern.java                  模型初始化数据读取接口  
  52.     Border.java                         一种模型初始格式,实现ConwayPattern接口  
  53.     Hi.java                             同上  
  54.     Pentadecathalon.java                同上  
  55.     Pulsar.java                         同上  
  56.     SimpleGlider.java                   同上    
  57.       
  58.     思路:  
  59.         从元细胞自动机模型的规则中我们可以发现几个关键要点,  
  60.         1、一个格子的状态由相邻格子的状态决定;因此在规则处理中我们要能够方便的确定每个格子的相邻格子情况  
  61.         2、格子的状态变化是一次性完成计算的,格子状态的改变不会对本次变化产生影响;因此在规则处理时要注意  
  62.           解决fact变化激活新的规则的问题  
  63.       
  64.         作者将所有规则按照规则流分组的方式分为下面几个组  
  65.         "register north east"   -   建立格子间的邻居关系(再次提醒,规则引擎推理基于数据,应当将所有需要的数据事先准备好  
  66.                                     数据模型的好坏直接影响规则的效率和质量)  
  67.                                       
  68.         "evaluate"              -   根据格子邻居的情况判定格子下一步的状态,并预设一个值;这里之所以没有直接改变格子  
  69.                                     状态就是因为上面提到的一次性计算问题,如果直接改变状态会影响对其它邻居格子的判断  
  70.                                     Phase:只对Phase==EVALUATE的格子执行  
  71.                                       
  72.         "calculate"             -   遍历每一个格子,根据该格子的生存/死亡状态更新邻居格子的‘邻居’生存个数  
  73.                                     这里留意的是,按照正常的编程思路,应当是找到格子后获得所有邻居状态,然后计算有多少  
  74.                                     个邻居格子是生存状态的,然后更新本格子中的LiveNeighbors计数;但是要采用这样的  
  75.                                     思路,必然涉及到对集合的处理以及一些循环语句,这样增加了规则的复杂度以及引入了过程  
  76.                                     代码,这都是在规则中应当避免的问题;而换一个角度思考我们就会得到更为简单的规则。  
  77.                                     Phase:规则完成后将格子的Phase设为EVALUATE  
  78.                                     注:使用规则引擎不只是掌握一门新技术,而是要求在编程思维上的改变。  
  79.                                       
  80.         "reset calculate"       -   取消"calculate"组激活的规则,因为每次格子重新设置pattern时,盘面上还有生存的格子  
  81.                                     这时如果使用kill all规则来将格子设为死亡,如果之前的calcuate规则还起作用,那么就会  
  82.                                     引起calcuate规则执行,建立新的生存格子,反过来又会引起kill all规则执行,造成无限循环  
  83.           
  84.         "kill"                  -   将Phase为KILL的格子状态设为死亡  
  85.           
  86.         "birth"                 -   将Phase为BIRTH的格子状态设为生存  
  87.           
  88.         "kill all"              -   将所有格子的状态设为死亡,是用在初始化棋盘时  
  89. */  
  90.   
  91. package org.drools.examples   
  92.     
  93. import org.drools.examples.conway.Cell;   
  94. import org.drools.examples.conway.CellGrid;   
  95. import org.drools.examples.conway.Neighbor;   
  96. import org.drools.examples.conway.Phase;   
  97. import org.drools.examples.conway.CellState;   
  98.   
  99. import org.drools.WorkingMemory;   
  100. import org.drools.common.InternalWorkingMemoryActions;   
  101. import org.drools.RuleBase;   
  102.   
  103. /*  
  104.     下面的四条规则都属于ruleflow-group:"register neighbor"  
  105.     它们的作用是建立格子之间彼此的邻居关系。  
  106.     我们知道每个格子会有8个相邻的格子,而规则建立关系时都是成对建立的,  
  107.     因此只用四条规则即可完成所有邻居关系建立  
  108. */  
  109. # 建立格子与其右上角格子的邻居关系   
  110. rule "register north east"  
  111.     ruleflow-group "register neighbor"  
  112. when   
  113.     # 获得棋盘列数   
  114.     CellGrid( $numberOfColumns : numberOfColumns )   
  115.     # 获得棋盘内的每个格子,最右边除外,因为最右边没有右上角   
  116.     $cell: Cell( $row : row > 0, $col : col < ( $numberOfColumns - 1 ) )       
  117.     # 获得上面格子的东北角格子         
  118.     $northEast : Cell( row  == ($row - 1), col == ( $col + 1 ) )       
  119. then                       
  120.     # 为这两个格子建立邻居关系   
  121.     insert( new Neighbor( $cell, $northEast ) );   
  122.     insert( new Neighbor( $northEast, $cell ) );           
  123. end   
  124.   
  125. # 建立格子与其正上方格子的邻居关系   
  126. rule "register north"  
  127.     ruleflow-group "register neighbor"     
  128. when   
  129.     $cell: Cell( $row : row > 0, $col : col )      
  130.     $north : Cell( row  == ($row - 1), col == $col )       
  131. then           
  132.     insert( new Neighbor( $cell, $north ) );   
  133.     insert( new Neighbor( $north, $cell ) );           
  134. end   
  135.   
  136. # 建立格子与其左上角格子的邻居关系   
  137. rule "register north west"  
  138.     ruleflow-group "register neighbor"  
  139. when   
  140.     $cell: Cell( $row : row > 0, $col : col > 0 )              
  141.     $northWest : Cell( row  == ($row - 1), col == ( $col - 1 ) )                           
  142. then           
  143.     insert( new Neighbor( $cell, $northWest ) );   
  144.     insert( new Neighbor( $northWest, $cell ) );           
  145. end   
  146.   
  147. # 建立格子与其左边格子的邻居关系   
  148. rule "register west"  
  149.     ruleflow-group "register neighbor"  
  150. when   
  151.     $cell: Cell( $row : row >= 0, $col : col > 0 )             
  152.     $west : Cell( row  == $row, col == ( $col - 1 ) )                          
  153. then           
  154.     insert( new Neighbor( $cell, $west ) );   
  155.     insert( new Neighbor( $west, $cell ) );            
  156. end   
  157.   
  158. /*  
  159.     下面的三条规则都属于ruleflow-group:"evaluate"  
  160.     它们是用在进行下一步的变化评估中的,这3个规则中并没有直接改变Cell.CellState,  
  161.     因为CellState是用来进行评估用的,随意改变会造成无限的循环调用,因此规则使用了Phase字段来控制格子状态变化  
  162.     在评估中只是改变Phase,最后根据Phase的状态完成所有格子CellState的设置,并将Phase设回EVALUATE状态  
  163. */  
  164.   
  165. # 将格子的邻居中少于两个是生存状态的格子的状态设为死   
  166. rule "Kill The Lonely"  
  167.     ruleflow-group "evaluate"  
  168.     no-loop   
  169. when   
  170. #   A live cell has fewer than 2 live neighbors   
  171.     theCell: Cell(liveNeighbors < 2, cellState == CellState.LIVE, phase == Phase.EVALUATE)   
  172. then   
  173.     theCell.setPhase(Phase.KILL);   
  174.     update( theCell );   
  175. end   
  176.   
  177. # 将格子的邻居中超过3个状态是生存的格子状态设为死   
  178. rule "Kill The Overcrowded"  
  179.     ruleflow-group "evaluate"  
  180.     no-loop   
  181. when   
  182. #   A live cell has more than 3 live neighbors   
  183.     theCell: Cell(liveNeighbors > 3, cellState == CellState.LIVE, phase == Phase.EVALUATE)   
  184. then   
  185.     theCell.setPhase(Phase.KILL);   
  186.     update( theCell );   
  187. end   
  188.   
  189. # 将格子的邻居中正好有3个是生存状态的死亡格子变为生   
  190. rule "Give Birth"  
  191.     ruleflow-group "evaluate"  
  192.     no-loop   
  193. when   
  194. #   A dead cell has 3 live neighbors   
  195.     theCell: Cell(liveNeighbors == 3, cellState == CellState.DEAD, phase == Phase.EVALUATE)   
  196. then   
  197.     theCell.setPhase(Phase.BIRTH);   
  198.     update( theCell );   
  199. end   
  200.   
  201. # 取消ruleflow-group为"calculate"的所有激活规则   
  202. # clearRuleFlowGroup    -   Clears the RuleFlow group, cancelling all its Activations   
  203. # 因为在"generation"后,"calculate"组的规则还留在引擎中,如果不事先取消,就会引起无限循环   
  204. rule "reset calculate"  
  205.     ruleflow-group "reset calculate"  
  206. when   
  207. then   
  208.     WorkingMemory wm = drools.getWorkingMemory();   
  209.     wm.clearRuleFlowGroup( "calculate" );   
  210. end   
  211.   
  212. # 将所有格子的Phase为Kill的格子状态设置为死,并将处理阶段Phase设置为DONE   
  213. rule "kill"  
  214.     ruleflow-group "kill"  
  215.     no-loop   
  216. when   
  217.     theCell: Cell(phase == Phase.KILL)   
  218. then   
  219.     theCell.setCellState(CellState.DEAD);   
  220.     theCell.setPhase(Phase.DONE);      
  221.     update( theCell );   
  222. end    
  223.   
  224. # 将所有格子的Phase为Birth的格子状态设置为生,并将处理阶段Phase设置为完成   
  225. rule "birth"  
  226.     ruleflow-group "birth"  
  227.     no-loop   
  228. when   
  229.     theCell: Cell(phase == Phase.BIRTH)   
  230. then   
  231.     theCell.setCellState(CellState.LIVE);   
  232.     theCell.setPhase(Phase.DONE);   
  233.     update( theCell );     
  234. end    
  235.   
  236. # 根据格子的生存状态改变邻居格子中LiveNeighbors属性的计数   
  237. rule "Calculate Live"  
  238.     ruleflow-group "calculate"  
  239.     lock-on-active  # 本规则更新的数据在规则流处理完成前不激活新的规则   
  240. when   
  241.     # 获得状态为生存的格子   
  242.     theCell: Cell(cellState == CellState.LIVE)   
  243.     # 找到该格子的每一个邻居   
  244.     Neighbor(cell == theCell, $neighbor : neighbor)    
  245. then   
  246.     # 为这个格子的每一个邻居的LiveNeighbors属性加1  
  247.     $neighbor.setLiveNeighbors( $neighbor.getLiveNeighbors() + 1 );   
  248.     # 将邻居格子的处理阶段Phase设置为EVALUATE   
  249.     $neighbor.setPhase( Phase.EVALUATE );      
  250.     update( $neighbor );   
  251.     System.out.println( "--live--" );   
  252.     System.out.println( "theCell: row"+theCell.getRow()+"col"+theCell.getCol());   
  253.     System.out.println ( "Neighbor: row:"+$neighbor.getRow()+"col"+$neighbor.getCol()+";LiveNeighbors:"+ $neighbor.getLiveNeighbors()) ;   
  254. end    
  255.   
  256. # 类似上一规则,只是进行递减操作   
  257. # 对于这个规则,不太熟悉规则引擎的程序员可能会有所迷惑,所有的格子初始化状态都是DEAD   
  258. # 那这样的话很多格子的LiveNeighbors就会变成负数了,有这样的想法是因为忽略了规则引擎不是从数据里找到规则合适的地方   
  259. # 而是在数据插入或发生变化时找到规则,一开始初始化所有格子为DEAD时确实激活了"Calculate Dead"的很多实例,但是在   
  260. # setPattern时首先执行了"reset calculate",这取消了之前的所有"Calculate Dead"的激活实例   
  261. # 然后运行"kill all"规则,如果是第一次,该规则不改变任何数据也不会激发新的规则   
  262. # 然后是根据数据设置格子的生存状态,此时上面的"Calculate Live"规则被激活   
  263. # 在后面的规则运算中每次执行"evalaute"规则组都要运行"reset calculate"也是这个原因   
  264. # 然后在运行了"birth""kill"规则后才执行"Calculate Live""Calculate Dead"规则   
  265. rule "Calculate Dead"  
  266.     ruleflow-group "calculate"  
  267.     lock-on-active # 本规则更新的数据在规则流处理完成前不激活新的规则   
  268. when   
  269.     theCell: Cell(cellState == CellState.DEAD)   
  270.     Neighbor(cell == theCell, $neighbor : neighbor )   
  271. then   
  272.     $neighbor.setLiveNeighbors( $neighbor.getLiveNeighbors() - 1 );   
  273.     $neighbor.setPhase( Phase.EVALUATE );   
  274.     update( $neighbor );       
  275.     System.out.println( "--dead--" );   
  276.     System.out.println( "theCell: row"+theCell.getRow()+"col"+theCell.getCol());   
  277.     System.out.println ( "Neighbor: row:"+$neighbor.getRow()+"col"+$neighbor.getCol()+";LiveNeighbors:"+ $neighbor.getLiveNeighbors()) ;   
  278. end    
  279.   
  280. # 将所有生存状态的格子设为死亡   
  281. rule "Kill All"  
  282.     ruleflow-group "kill all"      
  283.     no-loop   
  284. when   
  285.     theCell: Cell(cellState == CellState.LIVE)   
  286. then   
  287.     theCell.setCellState(CellState.DEAD);   
  288.     update( theCell );   
  289. end  
分享到:
评论
1 楼 ganchun-ling 2007-08-14  
简直是场及时雨啊!

相关推荐

    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