決策表使用方式
在Drools中,決策表通常是以Excel(.xls或.xlsx)或者CSV格式儲存的,這些格式的決策表並不能直接被Drools執行。它們需要被轉換成Drools規則語言(DRL)的文字格式,之後才能被編譯和執行。Drools提供了工具來幫助完成這一轉換,主要使用org.drools.decisiontable.SpreadsheetCompiler類,以下是一個基本的轉換過程
這是我的決策表:表一( Pricing bracket)
表二(Discounts)
檔名稱:ExamplePolicyPricing.xls,的結構目錄:
// 載入決策表檔案 InputStream is = DecisionTableToDRL.class.getResourceAsStream("/path/to/decisiontable.xls"); // 建立SpreadsheetCompiler例項 SpreadsheetCompiler compiler = SpreadsheetCompilerFactory.newCompiler(); // 轉換決策表為DRL String drl = compiler.compile(is, "UTF-8", "decisiontable"); // 列印DRL規則 System.out.println(drl);
xls轉為drl結果為:
package com.mk.examples.decisiontable; //generated from Decision Table import com.mking.drools.bean.decisiontable.*; // rule values at B9, header at B4 rule "Pricing bracket_9" when Driver(age >= 18, age <= 24, locationRiskProfile == "LOW", priorClaims == "1") policy: Policy(type == "COMPREHENSIVE") then policy.setBasePrice(450); end // rule values at B10, header at B4 rule "Pricing bracket_10" when Driver(age >= 18, age <= 24, locationRiskProfile == "MED") policy: Policy(type == "FIRE_THEFT") then policy.setBasePrice(200); System.out.println("Priors not relevant"); end // rule values at B11, header at B4 rule "Pricing bracket_11" when Driver(age >= 18, age <= 24, locationRiskProfile == "MED", priorClaims == "0") policy: Policy(type == "COMPREHENSIVE") then policy.setBasePrice(300); end // rule values at B12, header at B4 rule "Pricing bracket_12" when Driver(age >= 18, age <= 24, locationRiskProfile == "LOW") policy: Policy(type == "FIRE_THEFT") then policy.setBasePrice(150); end // rule values at B13, header at B4 rule "Pricing bracket_13" when Driver(age >= 18, age <= 24, locationRiskProfile == "LOW", priorClaims == "0") policy: Policy(type == "COMPREHENSIVE") then policy.setBasePrice(150); System.out.println("Safe driver discount"); end // rule values at B14, header at B4 rule "Pricing bracket_14" when Driver(age >= 18, age <= 24, locationRiskProfile == "MED", priorClaims == "1") policy: Policy(type == "COMPREHENSIVE") then policy.setBasePrice(700); end // rule values at B15, header at B4 rule "Pricing bracket_15" when Driver(age >= 18, age <= 24, locationRiskProfile == "HIGH", priorClaims == "0") policy: Policy(type == "COMPREHENSIVE") then policy.setBasePrice(700); System.out.println("Location risk"); end // rule values at B16, header at B4 rule "Pricing bracket_16" when Driver(age >= 18, age <= 24, locationRiskProfile == "HIGH") policy: Policy(type == "FIRE_THEFT") then policy.setBasePrice(550); System.out.println("Location risk"); end // rule values at B17, header at B4 rule "Pricing bracket_17" when Driver(age >= 25, age <= 30, priorClaims == "0") policy: Policy(type == "COMPREHENSIVE") then policy.setBasePrice(120); System.out.println("Cheapest possible"); end // rule values at B18, header at B4 rule "Pricing bracket_18" when Driver(age >= 25, age <= 30, priorClaims == "1") policy: Policy(type == "COMPREHENSIVE") then policy.setBasePrice(300); end // rule values at B19, header at B4 rule "Pricing bracket_19" when Driver(age >= 25, age <= 30, priorClaims == "2") policy: Policy(type == "COMPREHENSIVE") then policy.setBasePrice(590); end // rule values at B20, header at B4 rule "Pricing bracket_20" when Driver(age >= 25, age <= 35, priorClaims == "3") policy: Policy(type == "THIRD_PARTY") then policy.setBasePrice(800); System.out.println("High risk"); end // rule values at B27, header at B22 rule "Discounts_27" when Driver(age >= 20, age <= 24, priorClaims == "0") policy: Policy(type == "COMPREHENSIVE") then policy.applyDiscount(1); end // rule values at B28, header at B22 rule "Discounts_28" when Driver(age >= 18, age <= 24, priorClaims == "0") policy: Policy(type == "FIRE_THEFT") then policy.applyDiscount(2); end // rule values at B29, header at B22 rule "Discounts_29" when Driver(age >= 25, age <= 30, priorClaims == "1") policy: Policy(type == "COMPREHENSIVE") then policy.applyDiscount(5); end // rule values at B30, header at B22 rule "Discounts_30" when Driver(age >= 25, age <= 30, priorClaims == "2") policy: Policy(type == "COMPREHENSIVE") then policy.applyDiscount(1); end // rule values at B31, header at B22 rule "Discounts_31" when Driver(age >= 25, age <= 30, priorClaims == "0") policy: Policy(type == "COMPREHENSIVE") then policy.applyDiscount(20); end
執行drl程式碼及結果
動態載入drl可以參考該文:Drools實踐與動態載入
以下是drl解析過程:
KieHelper kieHelper = new KieHelper(); kieHelper.addContent(drl, ResourceType.DRL); KieSession ksession = kieHelper.build().newKieSession(); Driver def = new Driver(); Policy policy = new Policy(); ksession.insert(def); ksession.insert(policy); int count = ksession.fireAllRules(); ksession.dispose();
總結:決策表其實就是Excel轉化為DRL檔案的過程