Java Votary

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  48 随笔 :: 1 文章 :: 80 评论 :: 0 Trackbacks

题记

世界是事实的总体,而不是事物的总体。
世界为诸事实所规定,为它们既是全部事实所规定。
——路德维希·维特根斯坦,《逻辑哲学论》



The answer, please?
"请回答我..."
The stern voice startles you.
一个严厉的声音把你吓个半死.
You were dozing in Mrs. Rosencrantz's high school math class again. You realize at once that she's been talking to you.
你又在Mrs. Rosencrantz的数学课堂上和周公聊天了. 你立刻意识到, 她是在和你说话.
Well? You look at the blackboard. It's one of those word puzzles, the logic kind. Mrs.
什么? 你看看黑板, 原来是那些无聊的逻辑类填字题目.
Rosencrantz is waiting for you to solve it. You quickly scan what she's scrawled on the board with her crone's hand:
Rosencrantz女士正等着你的答案. 你飞快的扫描了一遍她用她那又老又丑的手在黑板上的涂鸦:

1. A foursome of golfers is standing at a tee, in a line from left to right. Each
golfer wears different colored pants; one is wearing red pants. The golfer to
Fred's immediate right is wearing blue pants.
1. 四个高尔夫选手从右向左排成一排, 站在树下. 每个选手穿着不通颜色的裤子.其中一个穿黑色. 在Fred右边的一个选手穿蓝色.

2.Joe is second in line.
2.Joe在队列中排第二.

3.Bob is wearing plaid pants.
3.Bob穿着彩色格呢的裤子.

4.Tom isn't in position one or four, and he isn't wearing the hideous orange
pants.
4.Tom不在第一或者第四, 他没有穿那种让人恶心的桔黄色裤子.

In what order will the four golfers tee off, and what color are each golfer's
pants?

那么, 问题是, 这四个人在队列中的顺序是什么? 他们各自穿什么颜色的裤子?



问题出来, 可能你唯一能想到的就是拿出一张纸, 一支笔, 坐下来, 仔仔细细的把逻辑理清楚.
你会说: "这种问题简直是小case....".
OK, 那你听说过爱因斯坦的难题吧(Deep同志贴出来过)?

这下, 除非你有超强的推理能力以外, 你还能做出来(你肯定知道,Google可以回答)?

仔细看看题目.
我们知道, 总共有四个人, 这是Facts
除了这些事实, 我们还有一堆的"if then" 样式的规则(Rule), 这一系列的规则成为我们的知识库(KB).
当然我们自己不会把这些东西在脑子里做推理的. 我们还需要一个推理机.
这就是Drools可以做的事情.
简单回顾一下:

首先有一个应用的规则集,包含很多规则。
推理引擎用规则左边的模式去匹配facts列表中的fact
如果有匹配成功的话,这条规则就被激活,放到议程(已激活的规则集合)中去。
最后所有的规则都匹配完成后,规则引擎就开始触发这些规则
规则引擎根据规则左边的匹配执行右边的动作,这些动作执行的过程中规则引擎会根据优先级
和一定的算法根绝左边匹配的事实放入到右边的上下文中。
也就是指针对匹配的事实执行右部的动作。

OK. 我们来让Drools干活.
有一点比较绕的是, 按照OO的思想, 我们可能搞出来不少的对象(人, 裤子, 颜色....). 这里我们只需要简化一下.
先来个颜色的类...

public class PantsColor {
public String of = null; // A person's name
public String is = null; // A pants color.

public PantsColor(String of, String is) {
this.of = of;
this.is = is;
}
}

我们还需要一个表示顺序的Position类:

public class Position {
public String of = null; // A person's name
public int is = 0; // A position (from left to right: 1, 2, 3, 4)

public Position(String of, int is) {
this.of = of;
this.is = is;
}
}

现在看看, 是不是比抽象出来N个对象更加简便了? 其实这两个才是我们真正想要得到的东西.

我们需要把手上一堆的规则描述出来, 让Drools认识这些东西.

这是一个规则描述文件, 我会用不正确的注释格式在里面作出说明.

xml version="1.0"?>

<rule-set name="golfer"
xmlns
="http://drools.org/rules"
xmlns:java
="http://drools.org/semantics/java"
xmlns:xs
="http://www.w3.org/2001/XMLSchema-instance"
xs:schemaLocation
="http://drools.org/rules rules.xsd
http://drools.org/semantics/java java.xsd"
>

<java:import>com.zyyang.golfer.PantsColorjava:import>   //让引擎知道这两个类的位置.
<java:import>com.zyyang.golfer.Positionjava:import>

<rule name="find-solution">   //规则名, 唯一的ID
        //根据题目中描述的, 我们一口气声明出5对...(P和C是他们中的任意两个)                
Unknown golfer's position and pants color -->
<parameter identifier="p"><class>Positionclass>parameter>
<parameter identifier="c"><class>PantsColorclass>parameter>

Fred's position and pants color -->
<parameter identifier="p1"><class>Positionclass>parameter>
<parameter identifier="c1"><class>PantsColorclass>parameter>

Joe's position and pants color -->
<parameter identifier="p2"><class>Positionclass>parameter>
<parameter identifier="c2"><class>PantsColorclass>parameter>

Bob's position and pants color -->
<parameter identifier="p3"><class>Positionclass>parameter>
<parameter identifier="c3"><class>PantsColorclass>parameter>

Tom's position and pants color -->
<parameter identifier="p4"><class>Positionclass>parameter>
<parameter identifier="c4"><class>PantsColorclass>parameter>

Ensure each position is unique -->
<java:condition>p1.is != p2.isjava:condition>
<java:condition>p1.is != p3.isjava:condition>
<java:condition>p1.is != p4.isjava:condition>
<java:condition>p2.is != p3.isjava:condition>
<java:condition>p2.is != p4.isjava:condition>
<java:condition>p3.is != p4.isjava:condition>


Ensure each pants color is unique -->
<java:condition>!c1.is.equals(c2.is)java:condition>
<java:condition>!c1.is.equals(c3.is)java:condition>
<java:condition>!c1.is.equals(c4.is)java:condition>
<java:condition>!c2.is.equals(c3.is)java:condition>
<java:condition>!c2.is.equals(c4.is)java:condition>
<java:condition>!c3.is.equals(c4.is)java:condition>


Ensure the unknown golfer's position and pants color
matches one of the known golfers
-->
<java:condition>
((p == p1) || (p == p2) || (p == p3) || (p == p4))
java:condition>
<java:condition>
((c == c1) || (c == c2) || (c == c3) || (c == c4))
java:condition>

Unknown golfer -->
<java:condition>p.of.equals(c.of)java:condition>

The golfer to Fred's immediate right is wearing blue pants. -->
<java:condition>"Fred".equals(p1.of)java:condition>
<java:condition>"Fred".equals(c1.of)java:condition>
<java:condition>p1.is + 1 == p.isjava:condition>
<java:condition>"blue".equals(c.is)java:condition>

Joe is second in line. -->
<java:condition>"Joe".equals(p2.of)java:condition>
<java:condition>"Joe".equals(c2.of)java:condition>
<java:condition>2 == p2.isjava:condition>

Bob is wearing plaid pants. -->
<java:condition>"Bob".equals(p3.of)java:condition>
<java:condition>"Bob".equals(c3.of)java:condition>
<java:condition>"plaid".equals(c3.is)java:condition>

Tom isn't in positions one or four,
and he isn't wearing the orange pants.
-->
<java:condition>"Tom".equals(p4.of)java:condition>
<java:condition>"Tom".equals(c4.of)java:condition>
<java:condition>1 != p4.isjava:condition>
<java:condition>4 != p4.isjava:condition>
<java:condition>!"orange".equals(c4.is)java:condition>

Print out the solution. -->
<java:consequence>   //打印出来咯.
System.out.println("Fred " + p1.is + " " + c1.is);
System.out.println("Joe " + p2.is + " " + c2.is);
System.out.println("Bob " + p3.is + " " + c3.is);
System.out.println("Tom " + p4.is + " " + c4.is);
java:consequence>
rule>
rule-set>

好, 规则也描述出来了, 下面让Drools干活.

/**
* @param args
* @throws IOException
* @throws SAXException
* @throws IntegrationException
* @throws FactException
*/
public static void main(String[] args) throws IntegrationException, SAXException, IOException, FactException {
URL url
= GolfersExample.class.getResource("golf.drl");   //规则文件的URL
RuleBase ruleBase
= RuleBaseLoader.loadFromUrl(url);   //把规则读出.
WorkingMemory workingMemory
= ruleBase.newWorkingMemory();   //这就是一个推理的地方.
String[] names
= new String[] { "Fred", "Joe", "Bob", "Tom" }; //四个人...
String[] pantsColors
= new String[] { "red", "blue", "plaid", "orange" };   //四种颜色.
int[] positions = new int[] { 1, 2, 3, 4 };   //位置的代号.
//一个一个的assert到workingmemoruy中.
for (int i = 0; i < names.length; i++) {
for (int j = 0; j < pantsColors.length; j++){
workingMemory.assertObject(
new PantsColor(names[i], pantsColors[j]));
}
for (int j = 0; j < positions.length; j++) {
workingMemory.assertObject(
new Position(names[i], positions[j]));
}
}
workingMemory.fireAllRules();   //激活.
}

由于Drools是Forword方式的, 它以事件向外部提供结果.

结果为:

Fred 1 orange
Joe 2 blue
Bob 4 plaid
Tom 3 red


现在你应该知道怎么去解决爱因斯坦的题目了.
无非就是多几个对象, 多几个规则而已嘛.


posted on 2006-03-11 10:02 Dion 阅读(2098) 评论(0)  编辑  收藏 所属分类: Rule Engine

只有注册用户登录后才能发表评论。


网站导航: