zoukankan      html  css  js  c++  java
  • 使用规则引擎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>
  • 相关阅读:
    【转载】 Deepmind星际争霸2平台使用第一轮-完成采矿
    【转载】 星际争霸2的AI环境搭建
    【转载】 强化学习(八)价值函数的近似表示与Deep Q-Learning
    【转载】 强化学习在美团“猜你喜欢”的实践
    【转载】 强化学习(七)时序差分离线控制算法Q-Learning
    【转载】 强化学习(六)时序差分在线控制算法SARSA
    【转载】 强化学习(五)用时序差分法(TD)求解
    【转载】 强化学习(四)用蒙特卡罗法(MC)求解
    ubuntu 系统网络突然"网络已禁用"
    健康日志之口腔粘膜----7-13
  • 原文地址:https://www.cnblogs.com/lovesqcc/p/4192589.html
Copyright © 2011-2022 走看看