一個小學題目的解: 採用規則引擎Drools實現

同學幫他侄兒問我一個問題:
資源:
1、小明的錢可以購買50瓶汽水。
2、老闆搞促銷,兩個空汽水瓶子可以換一瓶汽水。

問:小明最多能喝多少瓶汽水?

開始還楞了一下, 現在的小學題目還真不簡單。不過馬上給出答案:
先是50瓶,然後用50個空瓶換來25瓶,喝完後用25個空瓶換12瓶再多個空瓶,
喝完後用13個空瓶換6瓶,然後是7個空瓶換3瓶,然後是4個空瓶換2瓶,
然後是2個空瓶換1瓶,最後問老闆借1個空瓶,再用2個空瓶換1瓶,
剩下來那個空瓶還給老闆。所以喝到50+25+12+6+3+2+1+1=100

不過最近在學習規則引擎, 於是就想到了怎麼用規則引擎來實現。
我的想法是:
1: 假設汽水一元一瓶, 則小明最初有50元。
2: 如果兜裏有超過一元錢, 則買一瓶汽水喝, 此時:
錢減少一元,同時擁有的空瓶增加一個。
3: 如果擁有至少兩個空瓶, 則兩個空瓶賣給老闆, 兜裏的錢加一。
根據如上想法, 有了如下規則引擎的實現的實現(Drool):

java文件SodaWater.java:

package org.drools.examples;

import java.io.InputStreamReader;
import java.io.Reader;

import org.drools.FactHandle;
import org.drools.RuleBase;
import org.drools.RuleBaseFactory;
import org.drools.StatefulSession;
import org.drools.WorkingMemory;
import org.drools.compiler.PackageBuilder;
import org.drools.rule.Package;

public class SodaWater
{
    public static final void main(String[] args) throws Exception {
        final PackageBuilder builder = new PackageBuilder();
        builder.addPackageFromDrl( new InputStreamReader( SodaWater.class.getResourceAsStream( "SodaWater.drl" ) ) );

        final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
        ruleBase.addPackage( builder.getPackage() );

        final StatefulSession session = ruleBase.newStatefulSession();

        Customer customer = new Customer( "XiaoMing", 50);
        session.insert(customer);
        session.fireAllRules();
    }
   
    public static class Customer
    {
        private String name;
       
        private int money;
       
        private int drinkSum;
       
        private int blankCup;
       
        public Customer(String name, int money)
        {
            this.name = name;
            this.money = money;
            this.drinkSum = 0;
            this.blankCup = 0;
        }       

        public int getMoney()
        {
            return money;
        }
       
        public void setMoney(int money)
        {
            this.money = money;
        }
       
        public int getBlankCup()
        {
            return blankCup;
        }

        public void setBlankCup(int blankCup)
        {
            this.blankCup = blankCup;
        }

        public int getDrinkSum()
        {
            return drinkSum;
        }

        public void setDrinkSum(int drinkSum)
        {
            this.drinkSum = drinkSum;
        }

        public String getName()
        {
            return name;
        }

        public void setName(String name)
        {
            this.name = name;
        }      
       
    }
}
 



rule文件:

package org.drools.examples

dialect "mvel"

import org.drools.examples.SodaWater.Customer
 

rule "buy a soda water and drink"
    when
        $c : Customer(money > 0, $m:money, $b:blankCup, $d:drinkSum)
    then
        $c.money = $m - 1;
        $c.blankCup = $b + 1;
        $c.drinkSum = $d + 1;
        System.out.println( "Customer " + $c.name + " now buy a soda water and drink: money=" + $c.money + " and blankCup=" + $c.blankCup);
        update($c);
end

rule "sale blank cup and get money"
    when
        $c : Customer(blankCup > 1, $b:blankCup, $m:money )
    then
        $c.blankCup = $b - 2;
        $c.money = $m + 1;
        System.out.println("Customer " + $c.name + " now sale 2 cups and get money: money=" + $c.money + ", blankCup=" + $c.blankCup);
        update($c);
end

rule "finish drink"           
    no-loop true   
    dialect "java"
    when
        $c : Customer(blankCup < 2, money == 0)
    then
        System.out.println( "Customer " + $c.getName() + " finished drink, and drink number is " + $c.getDrinkSum() + " blankCup=" + $c.getBlankCup());
end
 



運行結果如下:
Customer XiaoMing now buy a soda water and drink: money=49 and blankCup=1
Customer XiaoMing now buy a soda water and drink: money=48 and blankCup=2
Customer XiaoMing now sale 2 cups and get money: money=49, blankCup=0
Customer XiaoMing now buy a soda water and drink: money=48 and blankCup=1
Customer XiaoMing now buy a soda water and drink: money=47 and blankCup=2

...

Customer XiaoMing now buy a soda water and drink: money=1 and blankCup=1
Customer XiaoMing now buy a soda water and drink: money=0 and blankCup=2
Customer XiaoMing now sale 2 cups and get money: money=1, blankCup=0
Customer XiaoMing now buy a soda water and drink: money=0 and blankCup=1
Customer XiaoMing finished drink, and drink number is 99 blankCup=1

不過小明最後手上還有最後一個瓶子, 計算機只能到此了。
向老闆借一個瓶子換一瓶汽水,喝完在還一個空瓶子,估計就是人類智慧來。

 

此程序需要drools的jar包,具體可見:

http://lcllcl987.iteye.com/blog/254381


看看大家還有什麼好的算法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章