使用规则引擎Drools计算圆周率PI

实际上是使用规则引擎能够更新工作内存区重新匹配规则实现迭代功能。 使用了策略模式实现。

《规则引擎与RETE算法介绍》 PPT :

http://files.cnblogs.com/lovesqcc/%E8%A7%84%E5%88%99%E5%BC%95%E6%93%8E%E4%B8%8ERETE%E7%AE%97%E6%B3%95.pptx

1.  CalcPI.java

package sample;

import java.util.ArrayList;
import java.util.List;

import org.drools.KnowledgeBase;
import org.drools.builder.ResourceType;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.StatefulKnowledgeSession;

import sample.helper.KnowledgeBaseHelper;
import sample.model.PI;
import sample.model.RuleResource;

public class CalcPI {

public static void main(String[] args) {

        try {
            // load up the knowledge base
            KnowledgeBase kbase = readKnowledgeBase();
            StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
            KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
            // go !
            PI pi = new PI();
            pi.setIterStrategy(PI.IterStrategySetting.ballardMethod.getStrategy());
            ksession.insert(pi);
            ksession.fireAllRules();
            System.out.println("PI: " + pi.getPi());
            logger.close();
        } catch (Throwable t) {
            t.printStackTrace();
        }            

    }

    private static KnowledgeBase readKnowledgeBase() throws Exception {
        List<RuleResource> resources = new ArrayList<RuleResource>();
        resources.add(new RuleResource("rules/CalcPI.drl", ResourceType.DRL));
        return KnowledgeBaseHelper.readKnowledgeBase(resources);
    }
}

2. PI.java

package sample.model;

import java.math.BigDecimal;

/**
 * @author qin.shuq
 * @see http://zh.wikipedia.org/wiki/%E5%9C%93%E5%91%A8%E7%8E%87
 */
public class PI {

    private BigDecimal pi;    // PI 值

    private int   iterValue;   // 迭代值

    private IterStrategy iterStrategy ;   // 迭代策略

    public PI() {
        iterStrategy = IterStrategySetting.WallisMethod.getStrategy();
        this.pi = BigDecimal.valueOf(IterStrategySetting.WallisMethod.getInitPi());
        this.iterValue = IterStrategySetting.WallisMethod.getInitIterValue();
    }

    public PI(IterStrategy strategy) {
        this.iterStrategy = strategy;
        this.pi = BigDecimal.valueOf(IterStrategySetting.toEnum(this.iterStrategy).getInitPi());
        this.iterValue = IterStrategySetting.toEnum(this.iterStrategy).getInitIterValue();
    }

    private static final IterStrategy leibnizStrategy = new LeibnizIterStrategy();
    private static final IterStrategy wallisStrategy = new WallisIterStrategy();
    private static final IterStrategy arctanStrategy = new ArctanIterStrategy();
    private static final IterStrategy ballardStrategy = new BallardIterStrategy();

    /**
     * 迭代一次的计算
     */
    public void iterOne() {
        iterStrategy.iterCalcOne(this);
    }

    public BigDecimal getPi() {
        return pi;
    }

    public void setPi(BigDecimal pi) {
        this.pi = pi;
    }

    public int getIterValue() {
        return iterValue;
    }

    public void setIterValue(int iterValue) {
        this.iterValue = iterValue;
    }

    public void setIterStrategy(IterStrategy iterStrategy) {
        this.iterStrategy = iterStrategy;
        this.pi = BigDecimal.valueOf(IterStrategySetting.toEnum(this.iterStrategy).getInitPi());
        this.iterValue = IterStrategySetting.toEnum(this.iterStrategy).getInitIterValue();
    }

    public enum IterStrategySetting {
        LeibnizMethod(leibnizStrategy, 4, 1),   //  PI: 3.141590653589692    iterValue: 1000000
        WallisMethod(wallisStrategy, 2, 1),     //  PI: 3.141591082795387    iterValue: 1000000

        // PI: 3.141592653589793057092897568389359
        //       021087492184878678890301622544682
        //       870922262624376585084262078791652
        //       664665170934387960240111985365743
        //       816329749380749612568341860137676
        //       992899578827196104523046458933737
        //       232212198503616995641765457187290
        //       803101355648406923221343642309071
        //       354773081438421905649763339659738
        //       095339778728962929492812141689849872323987745
        // iterValue: 183
        ArctanMethod(arctanStrategy, 4*((double)44/57+(double)7/239-(double)12/682+(double)24/12943), 1),

        ballardMethod(ballardStrategy, 0.015625*(-32-(double)1/3+256-(double)64/3-0.8-(double)4/7+(double)1/9), 0);

        private IterStrategy strategy;
        private double initPi;
        private int    initIterValue;

        private IterStrategySetting(IterStrategy strategy, double initPi, int initIterValue) {
            this.strategy = strategy;
            this.initPi = initPi;
            this.initIterValue = initIterValue;
        }

        public double getInitPi() {
            return initPi;
        }
        public int getInitIterValue() {
            return initIterValue;
        }
        public void setStrategy(IterStrategy strategy) {
            this.strategy = strategy;
        }

        public IterStrategy getStrategy() {
            return strategy;
        }

        public static IterStrategySetting toEnum(IterStrategy strategy) {
            for (IterStrategySetting s: IterStrategySetting.values()) {
                if (strategy.equals(s.getStrategy())) {
                    return s;
                }
            }
            return null;
        }

    }

}

interface IterStrategy {
    void iterCalcOne(PI pi);
}

class LeibnizIterStrategy implements IterStrategy {

    public void iterCalcOne(PI pi) {
        /**
         * according to formula :
         * PI/4 = (1-1/3+1/5-1/7+1/9-...)
         */
        int iterValue = pi.getIterValue()+2;
        pi.setIterValue(iterValue);
        int sign = (iterValue % 4 == 3) ? -1 : 1;
        pi.setPi(BigDecimal.valueOf(pi.getPi().doubleValue() + (double) 4 * sign / iterValue));
    }

}

class WallisIterStrategy implements IterStrategy {

    public void iterCalcOne(PI pi) {
        /**
         * according to formula :
         * PI/2 = (2/1 * 2/3) * (4/3 * 4/5) * (6/5 * 6/7) ...
         */
        long iterValue = pi.getIterValue();
        double newpi = pi.getPi().doubleValue() * (1 + (double)1/(iterValue*(iterValue+2)));
        pi.setPi(BigDecimal.valueOf(newpi));
        pi.setIterValue((int)(iterValue+2));
    }

}

/**
 * PI: 3.141592653589793    iterValue: 183
 */
class ArctanIterStrategy implements IterStrategy {

    public void iterCalcOne(PI pi) {
        /**
         * according to formula :
         *  PI/4 = 44arctan(1/57) + 7arctan(1/239) - 12arctan(1/682) + 24arctan(1/12943)
         *  arctan(x) = x - 1/3*x^3 + 1/5*x^5 - 1/7*x^7
         */
        long iterValue = pi.getIterValue() + 2;
        int sign = (iterValue % 4 == 3) ? -1 : 1;
        BigDecimal part1 = BigDecimal.valueOf((double)44*Math.pow((double)1/57, iterValue));
        BigDecimal part2 = BigDecimal.valueOf((double)7*Math.pow((double)1/239, iterValue));
        BigDecimal part3 = BigDecimal.valueOf((double)12*Math.pow((double)1/682, iterValue));
        BigDecimal part4 = BigDecimal.valueOf((double)24*Math.pow((double)1/12943, iterValue));
        BigDecimal incre = BigDecimal.valueOf(4*sign*((double)1/iterValue)).multiply(
                           part1.add(part2).subtract(part3).add(part4));
        pi.setPi(pi.getPi().add(incre));
        pi.setIterValue((int)iterValue);
    }

}

class BallardIterStrategy implements IterStrategy {

    /**
     * PI = 0.015625* SUM(0-n) {(-1)^n/2^(10*n)*(-32/(4n+1)-1/(4n+3)+256/(10n+1)-64/(10n+3)-4/(10n+5)-4/(10n+7)+1/(10n+9)))}
     */
    public void iterCalcOne(PI pi) {
        int iterValue = pi.getIterValue()+1;
        int sign = (iterValue % 2 == 0) ? 1: -1;
        BigDecimal part1 = BigDecimal.valueOf(-32/(double)(4*iterValue+1));
        BigDecimal part2 = BigDecimal.valueOf(-1/(double)(4*iterValue+3));
        BigDecimal part3 = BigDecimal.valueOf(256/(double)(10*iterValue+1));
        BigDecimal part4 = BigDecimal.valueOf(-64/(double)(10*iterValue+3));
        BigDecimal part5 = BigDecimal.valueOf(-4/(double)(10*iterValue+5));
        BigDecimal part6 = BigDecimal.valueOf(-4/(double)(10*iterValue+7));
        BigDecimal part7 = BigDecimal.valueOf(1/(double)(10*iterValue+9));
        BigDecimal incre = BigDecimal.valueOf(0.015625*sign/Math.pow(2, 10*iterValue)).multiply(
                part1.add(part2).add(part3).add(part4).add(part5).add(part6).add(part7));
        pi.setPi(pi.getPi().add(incre));
        System.out.println(iterValue);
        pi.setIterValue((int)iterValue);
    }

}

3.  RuleResource.java

package sample.model;

import org.drools.builder.ResourceType;

public class RuleResource {

    private String ruleResourceFile;
    private ResourceType resType;

    public RuleResource(String ruleResourceFile, ResourceType resType) {
        this.ruleResourceFile = ruleResourceFile;
        this.resType = resType;
    }

    public String getRuleResourceFile() {
        return ruleResourceFile;
    }
    public void setRuleResourceFile(String ruleResourceFile) {
        this.ruleResourceFile = ruleResourceFile;
    }
    public ResourceType getResType() {
        return resType;
    }
    public void setResType(ResourceType resType) {
        this.resType = resType;
    }

}

4.  KnowledgeBaseHelper.java

package sample.helper;

import java.util.List;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.io.ResourceFactory;

import sample.model.RuleResource;

public class KnowledgeBaseHelper {

    private KnowledgeBaseHelper() {}

    public static KnowledgeBase readKnowledgeBase(List<RuleResource> resources) {
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        for (RuleResource res: resources) {
            try {
                kbuilder.add(ResourceFactory.newClassPathResource(res.getRuleResourceFile()), res.getResType());
            } catch (Exception ex) {
                kbuilder.add(ResourceFactory.newFileResource(res.getRuleResourceFile()), res.getResType());
            }
        }
        KnowledgeBuilderErrors errors = kbuilder.getErrors();
        if (errors.size() > 0) {
            for (KnowledgeBuilderError error: errors) {
                System.err.println(error);
            }
            throw new IllegalArgumentException("Could not parse knowledge.");
        }
        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
        return kbase;
    }

}

5.  规则文件

#created on: 2011-1-12
package mymath

import sample.model.PI;

rule "CalcPI"
    no-loop false

    when
        pi: PI(iterValue<183)
    then
         System.out.println("exec rule CalcPI ... ");
         System.out.println("PI: " + pi.getPi() + "    iterValue: " + pi.getIterValue());
         pi.iterOne();
         update(pi);
end

6.  POM 文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>drools-study</groupId>
  <artifactId>drools-study</artifactId>
  <version>1.0</version>
  <name>drools-study</name>
  <description>a project for learning drools5.1.1</description>

  <dependencies>
      <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-compiler</artifactId>
        <version>5.1.1</version>
    </dependency>

      <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-core</artifactId>
        <version>5.1.1</version>
    </dependency>

    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-api</artifactId>
        <version>5.1.1</version>
    </dependency>

    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-bpmn2</artifactId>
        <version>5.1.1</version>
    </dependency>

    <dependency>
        <groupId>com.thoughtworks.xstream</groupId>
        <artifactId>xstream</artifactId>
        <version>1.3.1</version>
</dependency>

  </dependencies>

</project>
时间: 2024-08-05 10:52:29

使用规则引擎Drools计算圆周率PI的相关文章

C语言计算圆周率PI的代码

下面的内容段是关于C语言计算圆周率PI的内容. #include "stdio.h" #include "stdlib.h" #define SCALE 10000 #define ARRINIT 2000 void pi_digits(int digits) { int carry = 0; int arr[digits + 1]; for (int i = 0; i <= digits; ++i) arr[i] = ARRINIT; for (int i

JAVA规则引擎 -- Drools

Drools是一个基于java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效. 本文所使用的demo已上传 http://download.csdn.net/source/3002213 1.Drools语法 开始语法之前首先要了解一下drools的基本工作过程,通常而言我们使用一个接口来做事情,首先要穿进去参数,其次要获取到接口的实现执行完毕后的结果,而drools也是一样的,我们需要传递进

[Drools]JAVA规则引擎 -- Drools

Drools是一个基于Java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效. 本文所使用的demo已上传 http://download.csdn.net/source/3002213 1.Drools语法 开始语法之前首先要了解一下drools的基本工作过程,通常而言我们使用一个接口来做事情,首先要穿进去参数,其次要获取到接口的实现执行完毕后的结果,而drools也是一样的,我们需要传递进

关于计算圆周率PI的经典程序

短短几行代码,却也可圈可点.如把变量s放在PI表达式中,还有正负值的处理,都堪称经典.尤其是处处考虑执行效率的思想令人敬佩. /* pi/4=1-1/3+1/5-1/7+1/9-…… */ #include <stdio.h> int main(){ int s=1; float pi=0.,n=1.,t=1.; while(t>1e-6) { pi+=s*t; n+=2.; s=-s; t=1./n; } printf("\tPI=%7.6f\n",pi*4); r

.Net Core 环境下构建强大且易用的规则引擎

本文源码: https://github.com/jonechenug/ZHS.Nrules.Sample 1. 引言 1.1 为什么需要规则引擎 在业务的早期时代,也许使用硬编码或者逻辑判断就可以满足要求.但随着业务的发展,越来越多的问题会暴露出来: 逻辑复杂度带来的编码挑战,需求变更时改变逻辑可能会引起灾难 重复性的需求必须可重用,否则必须重复性编码 运行期间无法即时修改规则,但重新部署可能会带来其他问题 上线前的测试变得繁琐且不可控,必须花大量的人力和时间去测试 这些困境在『 小明历险记:

规则引擎.Net Core

.Net Core 环境下构建强大且易用的规则引擎 https://www.cnblogs.com/chenug/p/9160397.html 本文源码: https://github.com/jonechenug/ZHS.Nrules.Sample 引言 1.1 为什么需要规则引擎 在业务的早期时代,也许使用硬编码或者逻辑判断就可以满足要求.但随着业务的发展,越来越多的问题会暴露出来: 逻辑复杂度带来的编码挑战,需求变更时改变逻辑可能会引起灾难 重复性的需求必须可重用,否则必须重复性编码 运行

【小白成长撸】--多项式求圆周率PI

1 /*程序的版权和版本声明部分: 2 *Copyright(c) 2016,电子科技大学本科生 3 *All rights reserved. 4 *文件名:多项式求PI 5 *程序作用:计算圆周率PI 6 *作者:Amoshen 7 *完成日期:2016.9.28 8 *版本号:V2.0 9 */ 10 11 #include<stdio.h> 12 13 int main(void) 14 { 15 double pi = 0.0,i = 1.0;//pi/4 = 1 - 1/3 + 1

业务规则引擎浅析

在CRM(客户关系管理)系统或者其他业务支撑型系统的开发过程中,最经常多变的就是复杂的业务规则.因为这些规则要迎合.顺应市场的变化,如何能有效到做到业务规则和整体的系统支撑架构解耦分离,这个是开发过程中必须考虑的一个问题.每当客户要求改变一个业务规则的时候,我们又如何能做到在最短的时间内完成需求的开发提交,提高系统的灵活度?业务规则引擎无非是一个比较好的解决方案.它把复杂.冗余的业务规则同整个支撑系统分离开,做到架构的可复用移植,这个就是我们的终极目标. 那规则引擎又是什么东西?严格来说,它是一

Drools规则引擎初窥---drl和决策表实现[实例]

因项目需要,看了下drools规则引擎.写了一个比较简单的drools的drl规则和决策表实现的例子. 规则说明: 网络商城要举办活动(奖励额外积分), 订单原价金额在 100以下, 不加分 100-500 加100分 500-1000 加500分 1000 以上 加1000分 1.建立最基本的Drools项目结构并引入必须的类库.(这里采用junit来执行单元测试).创建一个Java Project,建立maven形式的源码包. 2.定义实体类Order.java 1 import java.