張鵬海, 畢 璐, 劉 斌, 旺堆次仁
(1.西藏民族大學院體育學院, 陜西 咸陽 712082; 2.陜西科技大學電氣與信息工程學院, 陜西 西安 710021; 3.拉薩市北京中學, 拉薩 850000)
運動員的比賽成績受多方面的因素影響,比如賽場的情況、天氣環(huán)境、比賽期間的飲食、運動員賽前的心理狀態(tài)等[1],如果遇到這類不確定的問題,除了需要運動員有良好的適應力和應變力,能迅速給運動員提供教練員的知識經(jīng)驗和處理方法則是首要選項。運動員訓練專家系統(tǒng)就是把教練員的處理方案和涉及運動員選拔和訓練的知識經(jīng)驗在計算機上建立一個知識經(jīng)驗數(shù)據(jù)庫,使用Java語言進行系統(tǒng)前端用戶界面的開發(fā),使用Prolog邏輯編程語言構建輔助訓練專家系統(tǒng),該系統(tǒng)在給定環(huán)境模式進過簡潔準確推理,即可得到待解決問題的專家建議或者訓練計劃安排[2]。
專家系統(tǒng)知識庫的建立首先需要大量收集運動員教練時的比賽和訓練經(jīng)驗,然后把這類文字性知識經(jīng)驗進行分類整理,按照邏輯總體分為三個模塊,每個模塊根據(jù)教練的經(jīng)驗知識劃分為3-6個不同方面的考察點[3],最后得到一個樹狀邏輯結構圖(如圖1),為了保證知識結構化的細化和深入,以及知識經(jīng)驗的充實性,要能判斷每個模塊的子模塊是否可以再分。最后將總結好的知識經(jīng)驗存入到計算機的數(shù)據(jù)庫中以備調用[4-5]。
運動員選拔模塊主要根據(jù)身體形態(tài)和生理機能的各種指標對運動員進行擇優(yōu)培養(yǎng),達到最初運動員就占有一定身體優(yōu)勢的目的。運動員訓練計劃安排模塊是知識介紹性的模塊,根據(jù)運動員的生理機能指標,專家系統(tǒng)就會給出詳細而準確的訓練計劃安排,將運動員的身體機能指標訓練到最佳狀態(tài)。訓練和比賽中的故障排除的主要任務是根據(jù)訓練和比賽過程中可能出現(xiàn)的特殊狀況給出解決方案,比如賽場的情況、天氣環(huán)境、比賽期間的飲食、運動員賽前的心理狀態(tài)等[6]。
以知識庫的第三個模塊-訓練和比賽中的故障排除為例,使用判斷樹來描述這個功能模塊的處理過程,其基本思路是:從問題出發(fā),列出所有可能影響訓練和比賽的因素,主要通過用戶來選擇產生問題的原因,然后顯示出專家給出的解決方案。這種方法直觀、方便的表現(xiàn)出了知識庫的邏輯[7]。

圖1 運動員訓練專家系統(tǒng)樹狀邏輯結構圖
判斷樹是一種自頂向下的判斷方法。通常判斷樹這種樹形結構有三種不同的樹枝節(jié):①決策結點:主要作用就是判斷決策的走向,本系統(tǒng)在運動員選拔模塊所用的是二叉判斷樹,因此只有兩種決策分支。②狀態(tài)結點:每個結點代表一種解決方案,通過對各個狀態(tài)結點的對比選擇出所屬問題的最佳解決方案。③結果結點:也就是決策樹從根結點延伸到最后的葉子結點,也叫決策結果,這個結點可以清楚的看出該模型有多少個類別[8],存儲的內容是專家提供的解決方案或運動員訓練計劃。按照判斷樹的這種層次結構模型建立了如圖2所示的“運動員選拔”判斷樹。
通常使用判斷樹進行推理時,主要是通過用戶交互界面向用戶提問來收集信息,然后根據(jù)用戶點擊的答案按鈕確定判斷樹的分支,這樣隨著分支的深入,直到葉子結點止,也就是專家系統(tǒng)給出的最終解決方案或建議。在用戶界面中,使用單選按鈕為用戶選擇答案提供顯示,并用文本框控件來顯示最后的解決方案或運動員訓練計劃。充分使用Prolog程序的搜索和匹配功能,對所建立的知識庫進行動態(tài)加載,結合Java語言生成選擇按鈕和顯示最后的解決方案或運動員訓練計劃[9]。

圖2 判斷樹的一個分支
在判斷樹中,不但要記錄每個結點所存儲的數(shù)據(jù)內容,而且還要記錄結點之間的關系和結點之間轉移的條件。在結點中所存儲的數(shù)據(jù)內容一般是中文字符串的形式,但是系統(tǒng)使用的Amzi! Prolog編程環(huán)境不支持中文,改進方式為使用MySQL數(shù)據(jù)庫來存儲這些結點中需要顯示的中文字符串和結點名,需要注意的是每個結點命名也必須是英文字符串,將結點名當做事實語句的參數(shù)和查詢條件來查詢結點中所存儲的中文字符串[10]。
以下為系統(tǒng)定義的三個基本事實:
Contain事實:定義為父結點和子結點之間的關系,包含兩種參數(shù),一個代表父結點,另一個表示父結點下的所有子結點,是一個列表類型。列表中的數(shù)據(jù)具體表現(xiàn)為運動員的選拔標準:“體重超重或不足、身高超高或不足、體重/身高×1000、下肢長/身高×100”擇優(yōu)錄取這四種情況。用Prolog的事實表示就是:“contain(不達標的原因是什么,[體重超重或不足、身高超高或不足、體重/身高×1000、下肢長/身高×100擇優(yōu)錄取])。”。
connect事實:定義父結點與其子結點間的動態(tài)聯(lián)系,包含三個參數(shù),參數(shù)一表示父結點本身,參數(shù)二代表用戶的選擇,是用戶自己輸入關鍵詞或點擊按鈕,參數(shù)三表示在用戶的輸入下會由父結點轉到的子結點,用Prolog的事實表示就是:“connect(不達標的原因是什么,ans1,體重超重或不足)。”,具體在運動員選拔模塊實現(xiàn)的流程是:如果運動員的身體形態(tài)不達標,系統(tǒng)會提問“不達標的原因是什么?”,此時用戶輸入ans1或點擊解決方案按鈕,當前結點會轉到“體重超重或不足”結點。
end事實:表示最終的葉子結點,用Prolog的事實表示就是:“end(解決方案1)。”,也就是代表:“解決方案1”是一個葉子結點。
該運動員訓練專家系統(tǒng)的程序設計使用的是Java語言和Prolog邏輯編程語言混合編程,充分利用了各自語言的優(yōu)點。因Java語言特有的代碼簡單、平臺無關性、解釋性等優(yōu)點,所以選擇使用Java語言進行前端的用戶交互界面程序設計[11]。Prolog語言在邏輯推理上具有代碼可讀性強、實現(xiàn)的推理功能豐富、易移植等優(yōu)點,近乎用自然語言的方式描述了各種邏輯推理運算,使得程序更簡單,占用內存更小,是開發(fā)專家系統(tǒng)這一人工智能程序的最常用工具,選擇使用Prolog程序設計語言進行專家系統(tǒng)推理機制的程序設計。將Java和Prolog這兩大開發(fā)語言的優(yōu)勢充分結合起來,各顯其能,使程序更嚴謹整潔,縮短開發(fā)周期,可實現(xiàn)運動員訓練專家系統(tǒng)的開發(fā)[12]。
Amzi! Prolog不僅為Java(通過Java Servlets)和許多其他工具提供了插件,而且提供了基于規(guī)則的服務。Amzi! Prolog+邏輯服務器(Logic Server)可以將基于規(guī)則的組件與Windows和其他應用程序集成在一起[13]。集成是通過“邏輯服務器API(Logic Server API)”實現(xiàn)的,它可以像訪問數(shù)據(jù)庫一樣輕松地訪問規(guī)則的邏輯庫。其結果是一個可管理且行為良好的接口,使得在需要的任何地方都可以運用基于規(guī)則的編程。
Amzi!Prolog提供了Java與Prolog程序的編程接口。它包含一個封裝了Prolog引擎及其API的主要LogicServer類和一個用于錯誤處理的LSException類[14]。它們都包含在一個Java包中,'amzi.ls',如圖3所示。

圖3 Java package包封裝圖
專家系統(tǒng)給出的內容都是判斷樹的結點中包含的信息,通過Prolog設計的基于規(guī)則和事實的推理程序進行搜索匹配,當匹配到對應結點中的內容,會將結點所包含的內容動態(tài)加載到Java的窗體中[15]。在專家系統(tǒng)的用戶交互界面中顯示專家提問、解決方案、運動員訓練計劃等內容即是采用了這種模式匹配和動態(tài)加載,在充分利用了各自語言的優(yōu)點的基礎上,Prolog程序采用自然語言表達那些適用于計算機規(guī)則的復雜的不精確的語言,應用于基于事實和推論的知識庫,用Java程序直接控制用戶界面的顯示(見圖4)。
(1)Java的程序設計。
① 新建一個Java工程。
② 在主窗體中放入JRadioButton控件,用來顯示根結點內容;設置文本框控件,其內容為接收專家知識提問內容;為窗體增加控制進程的按鈕,提供進行“下一步”的選項。
③ 初始化Prolog程序,加載Prolog生成的.xpl文件,調用特定的對象方法初始化Logic Server,初始化邏輯服務器的函數(shù)是:lsInit,它的定義形式如下:RC lsInit(ENGid cureng, STRptr ininame)。
④ 根據(jù)用戶已經(jīng)選擇的結點按鈕,獲得當前的結點的名字,使用Java程序進行訪問,通過“下一步”、“上一步”或者“返回”按鈕控制程序的進程。其中下一步選項的部分代碼及偽代碼如下。
//或者所選的結點的內容
Component[] components = choice.getComponents();
next_node_name = jr.getText();
try {
pro_next_node_name = ls.CallStr(“node(Node,Type,”+next_node_name+“,Answer,_)”);
java_next_node_name = ls.GetStrArg(pro_next_node_name, 1);
node_type = ls.GetStrArg(pro_next_node_name, 2);
//ls.AssertzStr(“current_node(”+current_node_name+“)”);
}
//判斷結點類型偽代碼
if(node_type == 答案結點)
獲取答案結點名字,將當前結點設為答案結點;
答案顯示區(qū)域生成;
從數(shù)據(jù)庫中調取相應答案結點的內容;
else(node_type == 判斷結點)
調用next規(guī)則,將當前結點設置為所選結點;
獲取當前結點的子結點內容;
動態(tài)生成當前結點選項內容;
繼續(xù)選取下一結點。

圖4 訓練知識節(jié)點界面顯示
(2)Prolog程序設計。
Prolog程序主要是動態(tài)加載當前結點以及當前結點子結點的所包含的內容,通過兩種Prolog功能可以完成對列表list的訪問。其中l(wèi)ist是變量通過模式匹配得到當前l(fā)ist的內容,允許引用列表的第一個元素和剩余的元素列表符號,其中X被綁定成為列表的第一個元素,稱為頭部,T被綁定到剩余元素的列表中,稱為尾部。之后通過show_radiolist()遞歸獲得每個子結點的內容,為之后動態(tài)加載選項提供基礎內容,具體代碼如下。
list_question(X,[H|T]):-%獲取列表中的內容
list_question(X,T). %訪問列表頭部和尾部元素
show_radiolist:- %動態(tài)獲得每個子結點內容模塊
current_node(Node), %加載當前結點
node(Node,_,_,_,List),%訪問當前結點列表中的內容
list_question(X,List),%加載當前結點子結點
node(X,decision,Question,_,_),%獲取子結點中的內容
write(Question), %寫入問題
asserta(store_radio(Question)), %加載列表中第一個子句到數(shù)據(jù)庫
nl,
fail.
以圖2所示的運動員選拔模塊為例,詳細介紹使用判斷樹方法進行推理的過程:設定一個當前結點的位置,我們選擇s結點為當前結點,此時專家系統(tǒng)的界面上會顯示專家提問:“運動員身體形態(tài)是否達標?”和備選答案“不達標的原因是什么?”、“身體機能測評”,若用戶選擇了“不達標的原因是什么?”,則進入下一個結點s1。用戶界面又會顯示結點s1所對應的信息備選答案“體重超重或不足”、“身高超高或不足”“體重/身高×1000、下肢長/身高×100擇優(yōu)錄取”,這時s1成為新當前結點。在這個推理過程中,專家系統(tǒng)掃描到的當前結點信息需要被記住,并且結點的信息在更新時需要釋放之前結點的數(shù)據(jù)內容。
Prolog程序在運行時的動態(tài)控制表現(xiàn)為:解釋器會把程序的所有子句存入到系統(tǒng)內存中,但是專家系統(tǒng)掃描到的當前結點信息需要被記錄,結點的信息在更新時需要釋放之前結點的數(shù)據(jù)內容。本文中會使用一些謂詞來對內存中的子句進行動態(tài)控制,主要有:①asserta(X),把第一個子句載入到動態(tài)數(shù)據(jù)庫中;②retract(X),從動態(tài)數(shù)據(jù)庫中刪除子句X,此過程完全不可逆。專家系統(tǒng)對父結點訪問結束后需要訪問其子結點時,將執(zhí)行如下代碼:
next:-
retract(current_node(_)),%刪除當前結點內容
next_node(Node),%獲得用戶輸入的結點
asserta(current_node(Node)),%將下一結點變?yōu)楫斍敖Y點
clear_radio,%刪除上一結點子結點內容
if_leaf. %判斷是否為答案結點
專家系統(tǒng)顯示的內容存儲在分支結點和葉子結點中,next謂詞可使專家系統(tǒng)對父結點訪問結束后轉移訪問其子結點,實現(xiàn)訪問狀態(tài)的改變。如果當前結點到達了葉子結點,需要進行回溯時,需要判斷是否到達了葉子結點,使用cut謂詞來判斷不同情況,cut謂詞的用法和其他程序開發(fā)語言中if語句的用法一樣。在程序中用“!”來表示。
Prolog語言的查詢依賴與模式匹配,查詢的模板為目標,如果有某個事實與目標相匹配,查詢即為成功,否則為查詢失敗,使用截斷謂詞cut,如果系統(tǒng)的事實成功匹配到目標進行回溯時,前面的選擇就會被釋放,不需要重新考慮,查詢就成功了。如圖5(A)所示帶有cut謂詞的程序對查詢控制流的影響,每一個方塊代表一個目標,目標就是需要查詢的內容。當目標進行回溯遇到cut時,控制權發(fā)生轉移,迅速轉移給上一級的目標,而不是其他目標,這樣其他目標就會被自動篩選掉,縮短查詢時間。圖5(B)是對單個目標的端口和控制流程的說明,具體工作流程為:從調用端口(call)進入目標,如果經(jīng)過目標匹配成功,就進入退出端口(exit),反之進入失敗端口(fail),如果用戶需要重新查詢或者引起回溯,則控制進入重試端口(redo),來重新進入目標。

圖5 (A)cut對控制流的影響,(B)goal(目標)的4個端口及控制流程
If_leaf的第一個子句表示獲取當前的結點位置,接下來判斷是否到達了葉子結點,如果到達葉子結點,則專家系統(tǒng)界面會顯示解決方案或運動員的訓練計劃等內容。下一步就需要使用cut謂詞執(zhí)行截斷搜索,阻止回溯。如果第一個子句不滿足目標條件,則說明未到達葉子結點,程序會進入到第二個子句,使用了cut后,還需要滿足第一個子句在cut之前就被目標排除了這一條件,這種情況下Prolog程序才會考慮第二個子句是否滿足目標,從而進行搜索匹配流程。具體程序如下:
if_leaf:-
current_node(Node), %獲取當前結點
node(Node,answer,Question,Answer,_), %判斷當前結點是否為葉子結點
retract(store_answer(_)), %清空答案列表的內容
asserta(store_answer(Answer)), %插入答案結點
!,
fail.
if_leaf:-
current_node(Node), %獲取當前結點
node(Node,decision,Question,_,_), %判斷當前結點是否為分支結點
nl,
show_radiolist, % 列出子結點
!,
fail.
本專家系統(tǒng)在大量收集了運動員教練的知識經(jīng)驗的基礎上構建專家系統(tǒng)知識庫。同時在輔助訓練專家系統(tǒng)中引入判斷樹方案,并采用Prolog和Java混合編程技術來具體實現(xiàn),用Prolog語言實現(xiàn)判斷樹的推理機制,Java平臺實現(xiàn)動態(tài)用戶界面的生成,充分發(fā)揮了各自程序設計語言的優(yōu)點,建立的專家系統(tǒng)占用內存小,程序便于修改和擴展,結構整潔靈活,經(jīng)試驗,本系統(tǒng)可以對提出的問題給出專家建議,達到了輔助訓練運動員,幫助運動員在比賽中取得優(yōu)異的成績的目的,收到了滿意的效果。