使用规则引擎Drools计算圆周率PI
实际上是使用规则引擎能够更新工作内存区重新匹配规则实现迭代功能。 使用了策略模式实现。
《规则引擎与RETE算法介绍》 PPT :
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>
使用规则引擎Drools计算圆周率PI的更多相关文章
- 开源规则引擎 drools
java语言开发的开源业务规则引擎 DROOLS(JBOSS RULES )具有一个易于访问企业策略.易于调整以及易于管理的开源业务规则引擎,符合业内标准,速度快.效率高.业务分析师或审核人员可以利用 ...
- 规则引擎drools封装
一.前言 网上规则引擎drools介绍很多,并且有很多细致的说明,作者也不敢托大说自己的好用,但作者经过2个项目使用过规则引擎后,自己对规则引擎的理解并进行封装,对规则内容及如何使用,有自己的一番实践 ...
- 开源规则引擎 Drools 学习笔记 之 -- 1 cannot be cast to org.drools.compiler.kie.builder.impl.InternalKieModule
直接进入正题 我们在使用开源规则引擎 Drools 的时候, 启动的时候可能会抛出如下异常: Caused by: java.lang.ClassCastException: cn.com.cheng ...
- 小明历险记:规则引擎drools教程一
小明是一家互联网公司的软件工程师,他们公司为了吸引新用户经常会搞活动,小明常常为了做活动加班加点很烦躁,这不今天呀又来了一个活动需求,我们大家一起帮他看看. 小明的烦恼 活动规则是根据用户购买订单的金 ...
- JAVA规则引擎 -- Drools
Drools是一个基于java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效. 本文所使用的de ...
- [Drools]JAVA规则引擎 -- Drools 2
上一篇文章 http://blog.csdn.net/quzishen/archive/2011/01/25/6163012.aspx 描述了一些常用的drools的语法标签和一个模拟实例即发送积分的 ...
- [Drools]JAVA规则引擎 -- Drools
Drools是一个基于Java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效. 本文所使用的de ...
- 规则引擎 drools
https://www.jianshu.com/p/725811f420db 深入了解Drools 简单介绍 笔者正在做风控系统,风控系统里边存在非常多的规则(比如:age < 16 || ag ...
- 用python计算圆周率PI
1.蒙特卡洛求圆周率 向区域内随即撒点 当点的数目足够多时,落在圆的点数目与在正方形点数目成正比 即圆的面积和正方形的面积成正比 可以得出计算圆周率的算法 DARTS=100000000 hits ...
随机推荐
- [CareerCup] 16.6 Synchronized Method 同步方法
16.6 You are given a class with synchronized method A and a normal method B. If you have two threads ...
- 安装redis和php的redis扩展
一.安装Redis 在服务器上下载好最新的redis解压包后,解压 #tar -zxvf redis-3.2.0-tar-gz #cd redis-3.2.0-tar-gz #make (redis- ...
- jq最新前三篇文章高亮显示
/*---------最新前三篇文章高亮显示-------------*/ function latest(){ var color_arr=new Array( "blue", ...
- IIS 8 下使用 WCF
按照以下步骤添加后,IIS8即支持WCF服务. 首先添加MIME类型 扩展名“.svc”,MIME类型 “application/octet-stream” 2. 然后在“Handler Mappin ...
- 【HDU 3401 Trade】 单调队列优化dp
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3401 题目大意:现在要你去炒股,给你每天的开盘价值,每股买入价值为ap,卖出价值为bp,每天最多买as ...
- ubuntu安装Python环境以及科学计算环境
参考:http://blog.csdn.net/a1311543690/article/details/ 1.sudo apt-get install python-pip pip是Python的一个 ...
- 关于struts2上传图片临时文件
- php课程---练习连接数据库及增删改
方式一:用php中的内置函数来做 (适用于5.1之前的版本) //1.生成连接 $conn = mysql_connect("localhost","root" ...
- LoadRunner11.00入门教程
安装成功后,根据教程,有自带的应用程序供新手快速掌握Loadrunner的使用.测试应用是一个基于web的旅行社应用程序,也就是供用户在线预订机票的应用.根据教程和操作,重新总结一下测试流程以及遇到的 ...
- python中raw_input输入数字问题
如果按照下面方式,则无论你输入什么,都会打印12,因为raw_input接受的输入是按照字符串处理的 num = raw_input('please enter a num:') if num > ...