摘 要: 以中國電信行業計費系統為研究對象,從批價優惠業務需求層面進行分析,提出了基于語法樹的批價優惠方法,并在理論和實踐上給出了一個電信行業中應用的解決方案。
關鍵詞: 計費系統;語法樹;批價;解決方案
計費系統[1]是電信運營商業務支撐系統中最為核心的部分,其靈活性、響應速度、支撐能力的高低也在很大程度上決定了前端業務模式的多樣性和客戶體驗的滿意程度。隨著電信行業的發展,電信運營商需要構建一個能夠支持3G網絡多業務發展的融合計費系統,以滿足復雜的資費套餐以及多業務融合的需求[2]。
面對更加復雜的全業務運營模式,運營商想要推出適應全業務運營環境下的計費系統,必然需要對原有的計費系統進行整合和改造。為了提高計費系統性能、支持多業務組合、個性化資費套餐靈活配置的能力,本文提出了基于語法樹的批價優惠方法。
1 業務介紹
計費系統框架圖如圖1所示,計費系統的核心是批價優惠處理,批價優惠分為三種類型:前向優惠、優惠和后向優惠。傳統上的套餐是指優惠,前向優惠和后向優惠是優惠的補充,主要是針對所有用戶的計費策略,可以把其視為標準資費的補充。批價優惠處理的過程是,首先與局數據(公共數據中心)建立連接進行全局零件庫加載操作(這里的局數據存儲在內存數據庫MDB[3]中),然后創建業務處理線程(如網絡服務線程、讀文件處理線程、業務處理線程、寫文件處理線程等),根據業務導航將CDR話單類(如語音話單、數據業務話單、GPRS話單、VPMN話單等)分配給不同業務處理線程處理,即對用戶話單中的費用進行優惠。
用戶訂購的每一個套餐資費即記賬資費包括多個子項,這些子項稱之為子記賬資費,每一個子記賬資費對應的有一個費率方案和一種場景,每一個費率方案由不同的零件組合而成,場景是用戶打電話產生的信息,包括用戶品牌、日期、地區、呼叫類型、用戶類型、費用類型等。優惠過程實質上是用記帳計費,子記帳資費再到優惠零件一級一級分解任務并執行任務的過程,因此,優惠過程是一個子記帳資費作用效果的描述串。這里記帳資費與子記帳資費的關系通過語法樹實現,每一個子記帳資費唯一地使用一個優惠零件,即優惠規則,且唯一地匹配一套參數,理論上,由于采用縱表結構的優惠零件具有擴展性,因此所有的優惠計費策略都可以通過優惠零件來實現。所以在最關鍵的優惠處理過程中,用戶訂購的每一種記帳資費都可以通過優惠語法樹進行描述、解析、計算。
2 語法樹與零件設計
2.1 優惠語法樹
2.1.1 語法樹定義
語法樹是一棵二叉樹,其中非葉子節點的值為子節點或子樹之間的關系,葉子節點為記賬資費或者子記賬資費。定義了以下五種業務關系:
(1)互斥關系(mut):兩節點之間只能取一個節點執行(子記帳資費)。先執行左節點,如果符合優惠條件則執行優惠,否則執行右節點。
(2)疊加關系(add):在左節點優惠的基礎上,再執行右節點。
(3)最優關系(max):取兩個節點最大優惠值。分別執行兩個子節點,然后進行比較,取優惠值最大節點。
(4)最劣關系(min):取兩個子節點最小優惠值,max的逆操作。
(5)特殊疊加關系(mad):針對分段的費用對象取最優后進行組合,顆粒度更細,其他關系針對整段費用對象做總費用判斷。一般針對打折跟忙閑時類優惠做mad的分時段最優處理。即在add的基礎上,針對費用對象分段考慮。
2.1.2 構建語法樹
假如用戶定購了A、B、C三個記帳資費,A和B兩個資費為互斥關系,A的子資費表達式為add(F01, F02),B的子資費表達式為add(F03,F04),C的子資費表達式為add(F05,F06)。記賬資費的優先順序為:A、B、C,所以資費表達式為:add(mut(add(a,b),add(c,b)),add(e,f)),優惠語法樹構造如圖2所示。
用戶訂購的所有套餐需要先按照優先級進行排序,以保證語法樹的唯一性,然后按照套餐間的關系以及業務類型來生成記帳資費表達式。其實就是將所有的套餐構造一顆二叉樹的過程。
2.2 優惠零件
(1)優惠零件定義
基本零件:也稱簡單零件,打折、置費率、減值優惠零件,實現最基礎的操作。
派生零件:也稱復雜零件,是在簡單零件的基礎上增加條件功能或者輔助邏輯功能,組合成功能更健壯的優惠零件,如圖3所示。
(2)優惠零件模板定義
在計費系統里,具體的計費優惠規則是體現在優惠零件里,根據優惠的業務特點把相近的一批優惠規則提煉出來,用一段簡單的代碼來實現這些規則,每一個優惠零件都代表了一種優惠規則。先使用C++模板[4]定義優惠零件,再用零件的有限組合構成各種優惠類型。
模板定義如下:
cFavBase:每個具體的優惠零件都需要繼承優惠零件基類;
cFav000:對費用對象賦值的最基本的優惠零件,所有優惠零件最后都是歸結為對次優惠零件的調用;
cFav001:基本打折類優惠零件;
cFav002:簡單分段優惠零件;
cFav003:忙閑時類優惠零件;
cFav004:節假日簡單無階梯話單優惠類零件;
cFav005:親情號碼優惠零件;
cFav006:小區優惠零件。
因此可以組成多種優惠類型,舉例如下:
基本打折類優惠零件:cFav001<cFav000>;
忙閑時類優惠零件:cFav001<cFav003<cFav000, cFav000>>;
節假日簡單無階梯話單優惠類:cFav001<cFav004<cFav000>>;
親情號碼優惠:cFav001<cFav009<cFav000>>;
所以節假日,親情號碼與忙閑時:
cFav001<cFav004<cFav009<cFav003<cFav000,cFav000>>>>
3 語法樹處理的C++實現
圖4是批價優惠處理的實現類圖,為了簡明只給出基本的屬性和方法,圖中cDataBase是CDR、cFeeObj、cUserInfoNode、cStatisObj、cFavProc的基類。話單基類CDR存放話單的基本信息和中間變量結構體等信息,費用對象類cFeeObj創建費用對象,cUserInfoNode用于生成用戶資料節點地址對象,引用用戶信息類cUserInfo類來創建用戶資料節點上的記帳資費語法樹,cStatisObj類負責創建累計對象,cFavProc類負責創建優惠過程對象。
3.1 記賬資費表達式的解析和調用
首先按照優先級對cUserInfo中的所有套餐進行排序,然后按照套餐間的關系以及業務類型生成記賬資費表達式,其實就是將所有的套餐構造成一顆二叉樹的過程。下面以語音業務的記賬資費表達式為例說明表達式的解析和調用的過程。語音業務的優惠語法樹如圖5所示,生成的記賬資費表達式為2:add(2:add(1:nam1e:index:effdate:expdate:type:id,1:name:index:effdate:expdate:type:id),0:subname:index)。
從圖5可以看出記賬資費表達式的結構實際上是一顆二叉樹,解析記賬資費表達式的過程是先將表達式中信息放到一個結構體p,屬性有節點類型type、函數名稱name、左子樹pl、右子樹pr、生效日期effDate、失效日期expDate、索引index等。下面對記賬資費表達式構成的樹中的節點進行說明:
(1)以“2:”開頭,稱之為函數節點,表明此節點有子節點(記賬資費或子記賬資費);“2:add”中的2代表節點類型,add代表函數,表示子節點之間的關系,其中“add”表示子節點之間為疊加關系,執行左節點后又執行右節點,經過解析之后,p.type=2、p.name=函數名、p.pl=左子樹、p.pr=右子樹。
(2)以“1:”開頭,稱之為記賬資費節點,此節點為葉子節點,比如:1:name:index:effdate:expdate:type:id分別代表的含義為節點類型、記賬資費名稱、索引、開始時間、失效時間、業務類型、產品id;表達式經過解析后p.type=1、p.name=記賬資費名稱、p.index=索引、p.effData=開始時間、p.expData=失效時間。
(3)以“0:”開頭,稱之為子記賬資費節點,此節點為葉子節點,比如:0:c1:18258分別代表的含義為節點類型、子記賬資費名稱、索引,表達式經過解析后,p.type=0、p.name=子記賬資費名稱、p.index=索引。
根據記賬資費表達式進行批價處理函數為favProcess(…char*expression,int sFlag..),先聲明一個結構體變量p,對表達式expression進行解析并將相關的信息存放到變量p中,然后根據p.type和p.name做不同的遞歸調用。
(1)當p.type=2、p.name=mut:若favProcess(…p.pl,int sFlag..)的返回值不等于0時,整個函數返回整個返回值;否則返回favProcess(..p.pr,int sFlag..);當p.name=add、min、max或者mad時進行不同方式的遞歸調用。
(2)當p.type=1時,根據p.index從局數據中獲取名為p.name記賬資費的子記賬資費的組合表達式billpalnexp,然后遞歸執行favProcess(…billpalnexp,int sFlag..)。
(3)當p.type=0時,根據p.index從局數據中獲取名為p.name的子記賬資費的詳細信息,生成子記賬資費費率計劃對象T_PP_SubPrcPLAN*pSubBillPlan并調用函數execSubBillPlan(…expnod.name…,pSubBillPlan,…),再將其返回值作為favProcess的返回值;執行execSubBillPlan的過程實際上就是調用優惠零件的過程。
3.2 優惠零件調用
因為優惠模板種類太多,挑出其中最基本的cFavBase、cFav000、cFav001和cFav002作為示例,類關系如圖6所示,圖中,類cFavBase是所有優惠零件的基類,每個具體的優惠零件都由它派生出來,并實現其中參數初始化和優惠過程的接口;cFav000是cFavBase的子類,它是對費用對象賦值的最基本的優惠零件,所有優惠零件最后都歸結為對此優惠零件的調用;cFav001是基本打折類優惠零件;cFav002是簡單優惠分段優惠零件。
調 用exeSubBillPlan(cFeeObj*pFeeObj…T_PP_ SubPrcPLAN *pSubBillPlan…)函數時,實際上是根據子記賬資費調用優惠零件進行批價處理。不同的子記賬資費的優惠零件模板可能不一樣,但是它們的核心處理過程process最終都會調用最簡單的優惠零件(cFav000)的處理函數。下面以簡單分段優惠零件組合為例,闡述優惠零件的調用過程,圖7為一個簡單分段優惠的子記賬資費的參數列表。
(1)創建優惠零件cFavBase*p=new cFav001<cFav002<cFav000,cFav000>>:創建零件時,cFav002< cFav000,cFav000>將被實例化作為cFav001的成員T* pFavBase;同時cFav000和cFav000分別實例化為T1* pltFavBase(小于等于閾值ThresholdVal用到的具體的優惠零件)和T2*pgtFavBase(大于閾值ThresholdVal用到的具體的優惠零件)。
(2)參數初始化p->initPara():從子記賬資費參數中讀出conditionCode和bill_rebill_flag,然后調用cFav002<cFav000,cFav000>(pFavBase)的初始化操作,讀出其中的ThresholdVal、Thresholdtype、feetype和unit,同時調用兩個cFav000(pltFavBase和pgtFavBase)的初始化操作,將前綴lt和gt的參數項分別賦值給pltFavBase和pgtFavBase。
(3)優惠過程p->process():首先獲取話單的相關條件信息(如通話類型,漫游類型,對端類型,費用類型等)和標批二批標識,然后與子記賬中conditionCode限制的相關條件信息進行匹配,若匹配失敗則返回0;若成功,繼續調用cFav002<cFav000,cFav000>(pPavBase)的優惠過程,根據話單中的計費量與閾值的關系,最終調用cFav000的優惠過程,即將feetype、value、unit、favortype等值傳遞給費用對象feeObj,讓其負責最后費用的計算。
本文通過對移動計費系統批價優惠業務的分析,提出了一種基于語法樹的優惠方法并使用面向對象語言C++的模板類設計了語法樹的解析和調用過程,構建優惠語法樹實現多套餐的疊加優惠,調用配置好的優惠零件使得程序具有更高的靈活性。該方法實現了各種復雜的優惠邏輯組合,可以支撐靈活的市場營銷策略,提高了計費系統的支撐能力,在理論和實踐上給出了一個電信行業計費系統應用中的解決方案。
參考文獻
[1] 陳龍,張春紅,云亮,等.電信運營支撐系統[M].北京:人民郵電出版社,2007.
[2] 倪然.融合計費:全業務運營的必由之路[J].通訊世界,2008(11):88.
[3] 劉全.內存數據庫在帳務后臺中的應用[D].南京:南京理工大學,2004.
[4] LAFORE R. C++面向對象程序設計[M].鄧子梁譯.北京:中國電力出版社,2004.