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

Drools4:对Sudoku示例的分析

阅读更多
  1. /*  
  2.     Sodu:数独游戏,一个9x9的方格棋盘中,按照每三行三列再细分为9个小棋盘,如下  
  3.             |a|a|a|b|b|b|c|c|c|  
  4.             |a|a|a|b|b|b|c|c|c|  
  5.             |a|a|a|b|b|b|c|c|c|  
  6.             |d|d|d|e|e|e|f|f|f|  
  7.             |d|d|d|e|e|e|f|f|f|  
  8.             |d|d|d|e|e|e|f|f|f|  
  9.             |g|g|g|h|h|h|i|i|i|  
  10.             |g|g|g|h|h|h|i|i|i|  
  11.             |g|g|g|h|h|h|i|i|i|  
  12.           其中a,b...i分别代表大棋盘中的9个小棋盘,规则是:  
  13.           1、使用1-9,九个数字填入字母a-i所在位置  
  14.           2、大棋盘上的每一行,每一列都不能有重复数字  
  15.           3、小棋盘上也不能有重复的数字  
  16.           数独游戏实际上是一个推理游戏,与数字计算无关;首先会随机产生一些数字在棋盘上,然后游戏者完成剩下的填空  
  17.       
  18.     数独游戏通常会在棋盘上事先准备好一些数字,然后由游戏者完成剩下的格子。  
  19.       
  20.     如何使用规则引擎完成这一任务呢?  
  21.       
  22.     --首先我们要对Drools这种正向推理性的引擎有一个认识前提,就是它是基于数据进行规则推导的,  
  23.     也就是说如果需要规则引擎帮你找到结果,那首先必须将所有可能的结果都准备好。  
  24.     这一方法在Golfer球员排序时也使用过,当时是将所有球员组合情况都放到引擎中,由引擎自己找出答案。  
  25.       
  26.     那么现在我们第一步要做的就是在所有未确定数据的空格子位置上准备所有可能的结果,也就是在那里放上从1-9的数字,最后由引擎自己挑选。  
  27.     现在我们在每个空格子里面都准备好了数据,那么下面就是要将格子中无关的数据去掉,如果剩下一个,那显然就是答案了。  
  28.     要如何去掉格子中无效的数据呢?那显然就是要遵循行、列、区域中都不能有重复数字的规则了。  
  29.     设想一下,获得某一行上有数据的格子,那么空格子中与这些格子的数据显然就不能重复,这样就可以排除掉无用的数据。  
  30.     依次类推,在列与区域中也进行这样的检查,那么最终会有空格子的可选数据会只剩一个,此时就将该可选数据转换为正式数据,  
  31.     同时又会引发新的筛选,进一步减少可选值。  
  32.       
  33.     但是这样的规则够了吗?从实际效果上看显然是不够的,因为在很多情况下,这样的规则并不能确定所有格子的值,还需要继续的挖掘潜在的规则。  
  34.     从游戏的原则中我们又可以推导从下面的规则:  
  35.     如果在一个区域/行/列内,某一个空格子上的可选值在这个区域/行/列里是唯一的,并且不会违反行列区域已有数字冲突的原则,那么该可选值就是格子真正的数字。  
  36.     采用了这个规则后,大部分的格子可以完成推导,有时甚至可以完成全部格子推导,但是仍然存在不可以得到结果的情况。  
  37.     或许对于数学非常精通的程序员,可以通过数学定理推导规则是否可以满足所有情况,但是作为大多数人,多测试是唯一的办法。  
  38.       
  39.     这也提醒我们,使用规则引擎解决复杂推理问题时,一定要多想多测试,并尽可能找到显式规则以及所有的潜在规则,  
  40.     宁多勿缺,只要规则正确,最多就是走走弯路,好过没有完成任务!  
  41.       
  42.     最后我们再找到一组潜在的规则  
  43.     如果在区域中有两个格子都只剩两个可选值,并且这两个可选值一样的情况下,显然这两个格子只能是这两个可选值中的一个;  
  44.     这时删除区域中其它空格子中相同的可选值。  
  45. */  

Fact 插入

  1. StatefulSession session = null;   
  2. try {   
  3.     Collection fields = new ArrayList();   
  4.     // 对于数独阵列中的每一个格子有4个属性:数字,行,列,区域   
  5.     // 下面就是根据这四个属性建立Fact数据,顺便将每一行数据打印出来   
  6.     for ( int i = 0; i < field.length; i++ ) {   
  7.         String row = "{";   
  8.         for ( int j = 0; j < field[i].length; j++ ) {   
  9.             row += field[i][j] + ",";   
  10.             fields.add( new Field( "" + field[i][j],   
  11.                                    j + 1,   
  12.                                    i + 1,   
  13.                                    getZone( i,   
  14.                                             j ) ) );   
  15.         }   
  16.         row += "}";   
  17.         System.out.println( row );   
  18.     }   
  19.     // 启动规则引擎   
  20.     RuleBase ruleBase = readRule();   
  21.     session = ruleBase.newStatefulSession();   
  22.   
  23.     // 将每一个Field实例插入WorkingMemory,同时保存FachHandle   
  24.     Iterator iter = fields.iterator();   
  25.   
  26.     Collection handles = new ArrayList();   
  27.     while ( iter.hasNext() ) {   
  28.         handles.add( session.insert( iter.next() ) );   
  29.     }   
  30.     session.fireAllRules();   
  31.   
  32.     System.out.println( "Size: " + iteratorToList( session.iterateObjects() ).size() );   
  33.   
  34.     // 完成计算以后将数据写回阵列   
  35.     iter = session.iterateObjects();   
  36.     //Copy the values of the fields into the matrix   
  37.     while ( iter.hasNext() ) {   
  38.         Object next = iter.next();   
  39.         if ( next instanceof Field ) {   
  40.             field[((Field) next).getRow() - 1][((Field) next).getColumn() - 1] = Integer.parseInt( ((Field) next).getValue() );   
  41.         }   
  42.     }   
  43.   
  44.     // 打印结果   
  45.     for ( int i = 0; i < field.length; i++ ) {   
  46.         String row = "{";   
  47.         for ( int j = 0; j < field[i].length; j++ ) {   
  48.             row += field[i][j] + ",";   
  49.         }   
  50.         row += "}";   
  51.         System.out.println( row );   
  52.     }   
  53.   
  54. catch ( Throwable t ) {   
  55.     t.printStackTrace();   
  56. finally {   
  57.     if ( session != null ) {   
  58.         session.dispose();   
  59.     }   
  60. }   

规则

  1. # 首先将所有数字为0的格子删除,并对这个格子插入从1-9的所有可能情况   
  2. rule "Rule 1: If a field has the value 0, it is empty: remove it and insert the PossibleValues"  
  3.     salience 100  
  4.     when   
  5.         $field : Field( value == 0, $row : row, $column : column, $zone : zone )   
  6.     then   
  7.         insert( new PossibleValue("1", $field ) );   
  8.         insert( new PossibleValue("2", $field ) );   
  9.         insert( new PossibleValue("3", $field ) );   
  10.         insert( new PossibleValue("4", $field ) );   
  11.         insert( new PossibleValue("5", $field ) );   
  12.         insert( new PossibleValue("6", $field ) );   
  13.         insert( new PossibleValue("7", $field ) );   
  14.         insert( new PossibleValue("8", $field ) );   
  15.         insert( new PossibleValue("9", $field ) );   
  16.         // 插入完毕后删除Field,因为该Field中的数据不是我们所需要的,   
  17.         // 我们需要的只是它的位置信息,而这些是不变的,已经在PossibleValue初始化时保留。   
  18.         retract( $field );   
  19.            
  20.         #System.out.println("Rule 1 fired.");   
  21. end     
  22.   
  23. # 这个规则是当某一个格子上的PossibleValue只剩下一个时,那么这个PossibleValue的值就是要寻找的值   
  24. rule "Rule 2: If there is one PossibleValue left at a certain position, it should be the Fields value"  
  25.     salience 5  
  26.     when   
  27.         $pv : PossibleValue ( $row : row, $zone : zone, $column : column, $value : value )   
  28.         not ( PossibleValue ( row == $row, zone == $zone, column == $column, value != $value ) )   
  29.     then   
  30.         insert( new Field( $value, $column, $row, $zone ) );   
  31.         System.out.println ( "Field be found in row="+$row+";col="+$column+"value="+$value );   
  32.         retract( $pv );   
  33.            
  34.         #System.out.println("Rule 2 fired.");   
  35. end     
  36.   
  37. # 获得行中已确定的数字,将该行上空格子中的相同备选数字删除   
  38. rule "Rule 3: If there is a field with a value in a row, remove all PossibleValues with this value in this row"  
  39.     salience 15  
  40.     when           
  41.         $field2 : Field( $row : row, $value : value != 0 )   
  42.         $possible : PossibleValue( row == $row, value == $value )   
  43.     then   
  44.         retract( $possible );   
  45.         #System.out.println("Rule 3 fired.");   
  46. end   
  47.   
  48. # 获得列中已确定的数字,将该列上空格子中的相同备选数字删除   
  49. rule "Rule 4: If there is a field with a value in a column, remove all PossibleValues with this value in this column"  
  50.     salience 15  
  51.     when           
  52.         $field1 : Field( $column : column, $value : value != 0 )   
  53.         $possible : PossibleValue( column == $column, value == $value )   
  54.     then   
  55.         retract( $possible );   
  56.         #System.out.println("Rule 4 fired.");   
  57. end   
  58.   
  59. # 获得区域中已确定的数字,将该区域上空格子中的相同备选数字删除   
  60. rule "Rule 5: If there is a field with a value in a zone, remove all PossibleValues with this value in this zone"  
  61.     salience 15  
  62.     when           
  63.         $field1 : Field( $zone : zone, $value : value != 0 )   
  64.         $possible : PossibleValue( zone == $zone, value == $value )   
  65.     then   
  66.         retract( $possible );   
  67.         #System.out.println("Rule 5 fired.");   
  68. end   
  69.   
  70. # 一旦产生新的格子数字,则删除在这个格子上的所有可选值   
  71. # Rule 2,3,4,5 不会引起该规则的调用,因为这几个规则是将其它可选值删除后剩余的值设为格子数字。   
  72. # 该规则是由Rule 789激发的   
  73. rule "Rule 6: For fields with a value remove all PossibleValues"  
  74.     salience 250  
  75.     when   
  76.         Field( value != 0, $col : column, $row : row, $zone : zone )   
  77.         $pv : PossibleValue( column == $col, row == $row, zone == $zone )   
  78.     then   
  79.         retract( $pv );   
  80.         #System.out.println("Rule 6 fired.");   
  81. end   
  82.   
  83. # 如果在一个小区域内,某一个空格子上的可选值在这个区域里是唯一的   
  84. # 并且不会违反行列区域数字冲突的原则,那么该可选值就是格子真正的数字   
  85. rule "Rule 7: If there is only one PossibleValue left in a zone, it must have the value of the field"  
  86.     salience 4  
  87.     when           
  88.         $pv : PossibleValue( $zone : zone, $value : value, $col : column, $row : row)   
  89.         not (PossibleValue( zone == $zone, value == $value ))   
  90.         not (Field( value == $value, zone == $zone) )   
  91.         not (Field( value == $value, row == $row) )   
  92.         not (Field( value == $value, column == $col) )   
  93.     then   
  94.         insert( new Field( $value, $col, $row, $zone ) );   
  95.         retract( $pv );   
  96.         #System.out.println("Rule 7 fired.");   
  97. end   
  98.   
  99. # 如果在一列上,某一个空格子上的可选值在这个列上是唯一的   
  100. # 并且不会违反行列区域数字冲突的原则,那么该可选值就是格子真正的数字   
  101. rule "Rule 8: If there is only one PossibleValue left in a column, it must have the value of the field"  
  102.     salience 4  
  103.     when           
  104.         $pv1 : PossibleValue( $zone : zone, $value : value, $col : column, $row : row)   
  105.         not (PossibleValue( column == $col, value == $value ))   
  106.         not (Field( value == $value, zone == $zone) )   
  107.         not (Field( value == $value, row == $row) )   
  108.         not (Field( value == $value, column == $col) )   
  109.     then   
  110.         insert( new Field( $value, $col, $row, $zone ) );   
  111.         retract( $pv1 );   
  112.         #System.out.println("Rule 8 fired.");   
  113. end   
  114.   
  115. # 如果在一行上,某一个空格子上的可选值在这个行上是唯一的   
  116. # 并且不会违反行列区域数字冲突的原则,那么该可选值就是格子真正的数字   
  117. rule "Rule 9: If there is only one PossibleValue left in a row, it must have the value of the field"  
  118.     salience 4  
  119.     when           
  120.         $pv : PossibleValue( $zone : zone, $value : value, $col : column, $row : row)   
  121.         not (PossibleValue( row == $row, value == $value ))   
  122.         not (Field( value == $value, zone == $zone) )   
  123.         not (Field( value == $value, row == $row) )   
  124.         not (Field( value == $value, column == $col) )   
  125.     then   
  126.         insert( new Field( $value, $col, $row, $zone ) );   
  127.         retract( $pv );   
  128.         #System.out.println("Rule 9 fired.");   
  129. end   
  130.   
  131. # 如果在一个区域中的两个空格子只剩两个可选值,则删除该区域中与这两个可选值相同的其它可选值   
  132. rule "Rule 10: If there are two fields with only two possible values, remove the PossibleValues for the same Value in the rest of the zone"  
  133.     salience 1  
  134.     when   
  135.         # 找到一个可选值A   
  136.         PossibleValue( $zone : zone, $val1 : value, $row1 : row, $col1 : column )   
  137.         # 要求在相同区域中,不同列上具有与A数字相同的可选值C   
  138.         PossibleValue( zone == $zone, value == $val1, $row2 : row, $col2 : column != $col1)   
  139.         # 要求与A在同一个格子里有其它可选值B   
  140.         PossibleValue( zone == $zone, row == $row1, column == $col1, $val2 : value )   
  141.         # 要求在C的格子里有与B的数字相同的可选值   
  142.         PossibleValue( zone == $zone, row == $row2, column == $col2, value == $val2 )   
  143.         # 要求在A格子中不存在除A与B的数字以外的可选值,也就是说A格子中的可选值不超过两个   
  144.         not ( PossibleValue( zone == $zone, row == $row1, column == $col1, value != $val1, value != $val2 ) )   
  145.         # 要求在C格子中不存在除A与B的数字以外的可选值,也就是说C格子中的可选值不超过两个   
  146.         # 这两个not条件组合起来要表达的就是区域中有A,C两个格子中的可选值一样,并且只有两个   
  147.         not ( PossibleValue( zone == $zone, row == $row2, column == $col2, value != $val1, value != $val2 ) )   
  148.         # 获得区域中与A数字相同的其它可选值   
  149.         $pv : PossibleValue( zone == $zone, value == $val1)   
  150.     then   
  151.         retract( $pv );   
  152.         #System.out.println("Rule 10 fired.");   
  153. end   
  154.   
  155. # 如果在一个区域中的两个空格子只剩两个可选值,则删除该区域中与这两个可选值相同的其它可选值   
  156. # 本规则与上一规则基本一样区别是寻找C格子时使用不同行而不是不同列   
  157. rule "Rule 11: If there are two fields with only two possible values, remove the PossibleValues for the same Value in the rest of the zone"  
  158.     salience 1  
  159.     when   
  160.         PossibleValue( $zone : zone, $val1 : value, $row1 : row, $col1 : column )   
  161.         # 本行与规则10不同   
  162.         PossibleValue( zone == $zone, value == $val1, $row2 : row != $row1, $col2 : column)   
  163.         PossibleValue( zone == $zone, row == $row1, column == $col1, $val2 : value )   
  164.         PossibleValue( zone == $zone, row == $row2, column == $col2, value == $val2 )   
  165.         not ( PossibleValue( zone == $zone, row == $row1, column == $col1, value != $val1, value != $val2 ) )   
  166.         not ( PossibleValue( zone == $zone, row == $row2, column == $col2, value != $val1, value != $val2 ) )   
  167.         $pv : PossibleValue( zone == $zone, value == $val1)   
  168.     then   
  169.         retract( $pv );   
  170.         #System.out.println("Rule 11 fired.");   
  171. end    
分享到:
评论
8 楼 hrfdotnet 2008-06-20  
哥们,能把这个示例完整的源码发一份给我吗,先谢谢了!hrfsun@yahoo.com.cn
7 楼 czhcc 2007-10-09  
学习中。不过想问一下,为什么 salience值为250的规则不被首先执行?
6 楼 tvjody 2007-09-18  
的确是很不错
楼主写写你的Drools的应用心得以及成功案例
5 楼 chinapr 2007-08-27  
看了楼主的很多帖子都还不错
4 楼 wl1985 2007-08-23  
像是游戏开发中使用的中间件,仔细研究一下,代码注释很规范,值得借鉴
3 楼 宋存义 2007-08-23  
太感谢了 ,正在学习中,
太多的不明白啊,想请教一下,
query是怎么用啊
要做一个从数据库中通过id能显示内容和其他的例子怎么做啊
我现在学的都晕了,谢谢各位知道的回答一下
2 楼 linyajun 2007-08-08  
给分,支持drools4
1 楼 江南白衣 2007-08-06  
给分,兄弟为drools4推广出力良多。

相关推荐

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

    - janino-2.5.16.jar:这是一个轻量级的Java源代码编译器,Drools可能用它作为替代编译器,特别是在对Eclipse JDT Core有特殊需求或者无法使用的情况下。 - droolsjbpm-ide-common.jar:这个文件可能包含了Drools与...

    Drools4Demo 示例 非常不错

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

    drools的使用示例代码

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

    drools5.1 规则流示例

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

    drools5 规则动态加载示例

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

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

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

    drools代码示例包

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

    drools drools drools drools drools

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

    drools6学习例子

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

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

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

    Drools规则引擎实现示例

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

    drools-示例:Drools:规则引擎

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

    Drools4Demo.rar

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

    drools7.5.0和spring 4.3.12集成示例

    在这个集成示例中,"drools7.5.0" 是 Drools 的一个特定版本,它包含了对规则定义、解析和执行的改进。"spring 4.3.12" 是 Spring 框架的一个稳定版本,提供了大量的增强和修复,包括对 Java 8 的全面支持。 集成...

    drools:流量MVN的实现示例

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

    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...

    hellodrools:Drools 示例项目

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

    Drools4.x实例

    7. 性能优化:在Drools4.x中,对性能进行了优化,包括更快的规则匹配和执行,以及更有效的内存管理。这使得Drools能够在处理大规模数据和复杂规则时仍然保持高效。 8. 社区支持:Drools拥有活跃的开发社区,提供了...

    drools7.25中文文档+drools技术指南.zip

    10. **案例研究与示例**:为了更好地理解和应用Drools,文档通常会包含多个实际的案例和示例,让你能够动手实践。 "Drools技术指南"可能会更深入地探讨上述某些主题,或者涵盖更高级的特性,如事件处理、规则流、...

Global site tag (gtag.js) - Google Analytics