Drools決策表實踐運用

郭慕荣發表於2024-11-23

決策表使用方式
在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檔案的過程

相關文章