21.8. Sudoku 示例决策(complex pattern matching、回调和 GUI 集成)
Sudoku 示例决策基于流行数字 puzzle Sudoku 的示例决策,演示了如何在 Red Hat Process Automation Manager 中使用规则,以根据各种限制在大型潜在解决方案空间中找到解决方案。这个示例还演示了如何将 Red Hat Process Automation Manager 规则集成到图形用户界面(GUI)中,在这种情况下,基于 Swing 的桌面应用程序,以及如何使用回调与正在运行的决策引擎进行交互,以在运行时根据工作内存更改更新 GUI。
以下是 Sudoku 示例的概述:
-
名称 :
sudoku -
主类 :
org.drools.examples.sudoku.SudokuExample(在src/main/java中) -
模块 :
drools-examples - 键入: Java 应用程序
-
规则文件 :
org.drools.examples.sudoku.*.drl(在src/main/resources) - 目标 :演示复杂的模式匹配、问题解决、回调和 GUI 集成
Sudoku 是基于逻辑的数字放置 puzzle。目标是填充 9x9 网格,以便每个列、每个列、每个行以及九个 3x3 区域均包含来自 1 到 9 次的数字。puzzle 设定者提供部分完成的网格,而 puzzle solver 的任务是利用这些限制完成网格。
解决问题的一般策略是,当您插入新数字时,它必须在其特定 3x3 区域、行和列内唯一。这个 Sudoku 示例决策设置使用红帽流程自动化管理器规则来解决 Sudoku puzzles 的问题,并试图解决包含无效条目的缺陷的 puzzles。
Sudoku 示例执行和交互
与其他红帽流程自动化管理器决策示例类似,您可以通过运行 org.drools.examples.sudoku.SudokuExample 类作为 IDE 中的 Java 应用程序来执行 SudokuExample 类。
当您执行 Sudoku 示例时,会出现 Drools Sudoku Example GUI 窗口。此窗口包含空网格,但该程序随附了存储于内部的各种网格,您可以加载和解决。
点 File
图 21.19. 启动时的 Sudoku 示例 GUI
加载 简单示例 时,网格会根据点的初始状态进行填写。
图 21.20. 加载简单示例后的 Sudoku 示例 GUI
从以下选项中选择:
点 Solve 触发 Sudoku 示例中定义的规则,该示例中填充剩余的值,并且使按钮再次不活跃。
图 21.21. 已解决简单示例
点 Step 查看规则集找到的下一个数字。IDE 中的控制台窗口显示从中解决问题的规则的详细信息。
IDE 控制台中的步骤执行输出
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 点击 Dump 查看网格的状态,其中单元显示了既定的值或剩余的可能性。
在 IDE 控制台中转储执行输出
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Sudoku 示例包含一个有意破坏示例文件,示例中定义的规则可以解析。
点 File 5 显示在第一行中不允许的两次。
图 21.22. broken Sudoku 示例初始状态
单击 Solve,将解决规则应用到此无效网格。Sudoku 示例中的关联解决问题检测样本中的问题,并尽可能尝试解决这个问题。这个过程没有完成,并使一些单元留空。
IDE 控制台窗口中会显示 solve 规则活动:
检测到无法正常工作的问题
cell [0,8]: 5 has a duplicate in row 0 cell [0,0]: 5 has a duplicate in row 0 cell [6,0]: 8 has a duplicate in col 0 cell [4,0]: 8 has a duplicate in col 0 Validation complete.
cell [0,8]: 5 has a duplicate in row 0
cell [0,0]: 5 has a duplicate in row 0
cell [6,0]: 8 has a duplicate in col 0
cell [4,0]: 8 has a duplicate in col 0
Validation complete.
图 21.23. 有问题的解决方案示例尝试
名为 Hard 的 Sudoku 示例文件更为复杂,解决规则可能无法解决它们。IDE 控制台窗口中会显示不成功的解决方案:
未解析的硬示例
Validation complete. ... Sorry - can't solve this grid.
Validation complete.
...
Sorry - can't solve this grid.
根据仍是单元的候选值集,用于解决中断示例实施标准解析技术的规则。例如,如果一个集合包含单个值,则这是单元的值。对于九个单元里有一个值出现的一个值,规则插入了某些特定单元的"使用解决方案值"类型 设置 的事实。这一事实导致从该单元所属的任何组中所有其他单元格中消除这个值,且值将被重新处理。
示例中的其他规则会减少某些单元的可分值。规则 "naked pair", "hidden pair in row", "hidden pair in column", 和 "hidden pair in square" 消除了可能性,但没有建立解决方案。规则 "位于 , and 行中的 X-wing in rows", "'X-wing in columns"', "interection removal line""intersection removal 列" 来执行更复杂的清除。
Sudoku 示例类
org.drools.examples.sudoku.swing 包含了为 Sudoku puzzles 实施框架的以下核心组件:
-
SudokuGridModel类定义了一个接口,它将一个接口存储一个 Sudoku puzzle,作为Cell对象的 9x9 网格。 -
SudokuGridView类是一个 Swing 组件,它可以视觉化SudokuGridModel类的任何实现。 -
SudokuGridEvent和SudokuGridListener类在模型和视图之间沟通状态变化。当一个单元值被解析或更改时,将触发事件。 -
SudokuGridSamples类为演示目的提供了部分填充的 Sudoku 模糊。
这个软件包对 Red Hat Process Automation Manager 库没有依赖软件包。
package org.drools.examples.sudoku 包含以下用于实施元素 Cell 对象及其各种聚合的类集:
-
CellFile类,其子类型CellRow、CellCol和CellSqr是CellGroup类。 Cell和CellGroup子类的SetOfNine中的一个属性自由提供带有 typeSet<Integer> 的属性。对于Cell类,该集合代表个人候选集。对于CellGroup类,该集合就是其所有单元集的 union(仍然需要分配的数字集)。在 Sudoku 示例中,81
Cell和 27CellGroup对象和由Cell属性cellRow、cellCol和cellSqr提供的链接,以及CellGroup属性单元单元(Cellll 对象列表)。使用这些组件,您可以编写用于检测特定情况的规则,允许为某个候选项集中的单元或消除值分配值。-
Settingclass 用于触发值分配后的操作。在检测到新情况的所有规则中使用了设置事实,以避免重新操作中间状态。 -
Stepping类用于低优先级规则,当"Step"没有定期终止时,会停止紧急情况。这个行为表示这个程序无法解决。 -
主类
org.drools.examples.sudoku.SudokuExample实施 Java 应用程序,并合并所有这些组件。
Sudoku 验证规则(validate.drl)
Sudoku 示例中的 validate.drl 文件包含在单元组中检测重复数字的验证规则。它们组合成 "验证" 认证组,用户可在用户加载点后明确激活规则。
三个规则 "重复为 cell …" 所有功能的 when 条件如下:
- 规则中的第一个条件会找到一个带有分配值的单元。
- 规则中的第二个条件会拉取单元所属的三个单元组。
- 最终条件找到一个单元(除前一个)的单元(除前一个),其值与第一单元相同,以及同一行、列或方括号,具体取决于规则。
规则 "duicate in cell …"
规则 "terminate group" 是最后触发的最后一个。这个规则会显示信息并停止序列。
规则"确定组"
Sudoku 解决规则(sudoku.drl)
Sudoku 示例中的 sudoku.drl 文件包含三种类型的规则:一个组处理一个到单元的分配,另一个组检测到可行的分配,第三个组会从 candidate 集合中消除值。
规则 "set a value", "iminate a value from Cell 取决于 " 和 "retract settings"Setting 对象的存在。第一个规则处理分配给单元的分配,操作会从单元 的空闲 组中删除值。这个组也会降低一个计数器,在零时将控制权返回到名为 fireUntilHalt() 的 Java 应用程序。
规则 "imininate a value from Cell" 的目的是减少与新分配的单元相关的所有单元的列表。最后,当进行所有的精简时,规则 "retract 设置" 会回收触发 设置 事实。
rules "set a value", "iminate a value from a Cell" and "retract set"
两种解决规则可检测某个情况,在可以分配多个单元时。对于一个包含单个数字的候选集,规则 "single" 触发。当 单个候选者没有单元格时,规则"隐藏 单"触发,但存在包含候选的单元时,这不包括在单元所属的三个组里的其它单元格中。这两个规则都创建并插入 设置 事实。
规则"单一"和"隐藏单一"
来自最大的组的规则(单独或在两组或三组)实施多种解决技术,用于手动解决 Sudoku 议会。
规则 "naked pair" 在组的两个单元中检测相同的候选大小集合。这两个值可以从该组的所有其他候选组中删除。
规则"naked pair"
…"中三个规则" 函数与规则 "naked pair" 类似。这些规则检测一个组只两个单元格中两个数字的子集,且在组的任何其他单元格中都没有发生任何值。这意味着,其他所有候选者都可以从两个单元格中去除以隐藏的隐藏对。
规则"hidden 对在 …"
两条规则处理行和列中的 "Xwing "。当值的每两个可能单元(或列)中都只包括两个可能的单元格时,这些候选人也存在于同一列(或行),那么可以删除列内(或行)的所有其他候选者。当遵循这些规则中的模式序列时,请注意如何以方便的词语表达的条件,如 相同的 或 仅导致 具有合适的限制的模式,或以 not 为前缀。
规则 "X-wings in …"
这两个规则 "intersection removal …" 基于一个方方或单一列内出现某种数量的受限位置。这意味着这个数字必须位于一行或列的两个或者三单元格之一,并可从组所有其他单元的候选单元中删除。这个模式决定了限制发生的情况,然后针对方括号外的每个单元格以及同一单元文件内触发。
rules "interection removal …"
这些规则已足够多,但并非所有 Sudoku 模糊。为了解决非常困难的网格,规则集需要更复杂的规则。(通常,一些不清点可以通过试用和错误解决。)