動物識別專家系統
一、本系統通過HTML+JavaScript語言實現,通過HTML5+CSS3設計頁面的基本結構,並且加入了一些動畫效果,JavaScript指令碼語言則執行邏輯結構和觸發事件。前臺介面主要包括四部分:條件新增按鈕框,綜合資料庫區,規則事例區,和匹配結果及分析過程區。
二、字元組主要分為三個:
(1)fact事實組,包括所有條件以及結論。
(2)rule規則陣列,第0位為結果,其他位為條件,條件為空時值為0。
(3)con選定陣列,包括自己選定的推理條件。
邏輯上在每個條件按鈕中加入觸發器按鈕,當點選條件按鈕後,按鈕樣式改變並且將該事實的值傳到已經定義的字元陣列con中,再次點選條件按鈕代表取消該選項,則恢復原樣式並且將其移出con組中。
三、當條件選擇完畢後,將已經選定的con組與規則庫中的規則rule組進行比較,比較的結果分為四種情況:
(1)con選定組與rule規則組完全一致,但結果並不是已知結果的七種,而是中間結果,這是彈窗提示使用者是否要繼續新增條件或者直接輸出結果,繼續新增條件後需要再次點選搜尋按鈕進行查詢。(例如由有羽毛規則推理出來是鳥,這時會提示是否繼續,繼續後繼續新增條件善飛,會輸出最終結果信天鷹)
(2)con選定組與rule規則組完全一致,且結果為已知結果的七種,這時直接輸出結果。(例如輸入善飛和是鳥類,會直接輸出信天鷹)
(3)con選定組與rule規則組不完全匹配但rule包含con組,這時會在提示使用者該條件不完整和該規則還需要哪些條件。(例如輸入是鳥類,會提示條件不完整,並給出該條件可能組成的規則:鳥類+善飛=信天鷹 鳥類+不會飛+長腿+有黑白二色=鴕鳥)
//具體每一條規則的判斷函式 function match(a) { var i = 1, j = 0; var sum2 = 0; var flag = 0; var c = new Array(6); c[0] = 0; //把此規則非零的值賦給新的陣列C if(used == 1) { for(i = 1; i <= 5; i++) { if(rule[a][i] != 0) { sum2++; c[i] = rule[a][i]; } } for(i = 0; ne[i] < 100; i++) { //判斷C陣列中是否含有Con陣列的值 if(c.find(function(value) { if(value == ne[i]) { return true; } })) {} else //不包含直接退出迴圈 return false; } return true; } for(i = 1; i <= 5; i++) { if(rule[a][i] != 0) { sum2++; c[i] = rule[a][i]; } } //驗證已選的CON函式是否符合rule規則 for(i = 0; i < count; i++) { //判斷C陣列中是否含有Con陣列的值 if(c.find(function(value) { if(value == con[i]) { return true; } })) { } else //不包含直接退出迴圈 return false; } //完全匹配 if(count == sum2) { if(rule[a][0] < 25) { ne[0] = rule[a][0]; return 3; } return true; } //非完全匹配 else { return 2; } } //推斷函式 function inference() { var end = ""; //最後輸出的結果 var flag = 0; //判斷匹配型別 var sum = 0; //判斷符合條件的個數 //對每一個規則進行遍歷 for(var i = 1; i <= rulenum; i++) { //完全匹配時 if(match(i) == true) { flag = 1; end = fact[rule[i][0]] //把結果是怎樣得來的條件輸出 1+2=3 document.getElementById('conclusion').innerHTML = document.getElementById('conclusion').innerHTML + " " + fact[rule[i][0]]; document.getElementById('al').innerHTML = document.getElementById('al').innerHTML + "<br>" + '符合R' + i + "規則 "; for(var j = 1; j <= 5; j++) { if(rule[i][j] != 0) { if(j == 1) { document.getElementById('al').innerHTML = document.getElementById('al').innerHTML + "" + fact[rule[i][j]]; } else document.getElementById('al').innerHTML = document.getElementById('al').innerHTML + '+' + fact[rule[i][j]]; } } document.getElementById('al').innerHTML = document.getElementById('al').innerHTML + '=' + fact[rule[i][0]] + '<br>'; break; } //相對匹配時 if(match(i) == 2) { sum++; flag = 2; //第一次時輸出 if(sum == 1) document.getElementById('al').innerHTML = "條件不完整,根據已知條件:可能為以下公式,請繼續選擇條件<br>" //把結果是怎樣得來的條件輸出 1+2=3 for(var j = 1; j <= 5; j++) { if(rule[i][j] != 0) { if(j == 1) { document.getElementById('al').innerHTML = document.getElementById('al').innerHTML + "" + fact[rule[i][j]]; } else document.getElementById('al').innerHTML = document.getElementById('al').innerHTML + '+' + fact[rule[i][j]]; } } document.getElementById('al').innerHTML = document.getElementById('al').innerHTML + '=' + fact[rule[i][0]] + '<br>'; } if(match(i) == 3) { used = 1; sum++; flag = 3; //第一次時輸出 if(sum == 1) { document.getElementById('conclusion').innerHTML = document.getElementById('conclusion').innerHTML + " " + fact[rule[i][0]]; document.getElementById('al').innerHTML = '暫時符合R' + i + ":"; for(var j = 1; j <= 5; j++) { if(rule[i][j] != 0) { if(j == 1) { document.getElementById('al').innerHTML = document.getElementById('al').innerHTML + "" + fact[rule[i][j]]; } else document.getElementById('al').innerHTML = document.getElementById('al').innerHTML + '+' + fact[rule[i][j]]; } } document.getElementById('al').innerHTML = document.getElementById('al').innerHTML + "=" + fact[rule[i][0]] + "<br>" } //把結果是怎樣得來的條件輸出 1+2=3 var pre = rule[i][0]; document.getElementById('al').innerHTML = document.getElementById('al').innerHTML + "目前為" + fact[pre] + "<br>結果可能為"; for(var k = 9; k <= 15; k++) { for(var j = 1; j <= 5; j++) { if(pre == rule[k][j]) { document.getElementById('al').innerHTML = document.getElementById('al').innerHTML + " " + fact[rule[k][0]]; break; } } } if(confirm('推理結果為中間結果,您是否要繼續新增條件') == false) { document.getElementById('result').innerHTML = fact[pre]; document.getElementById('result').style.top = "65px"; document.getElementById('al').innerHTML = '符合R' + i + ":"; for(var j = 1; j <= 5; j++) { if(rule[i][j] != 0) { if(j == 1) { document.getElementById('al').innerHTML = document.getElementById('al').innerHTML + "" + fact[rule[i][j]]; } else document.getElementById('al').innerHTML = document.getElementById('al').innerHTML + '+' + fact[rule[i][j]]; } } document.getElementById('al').innerHTML = document.getElementById('al').innerHTML + "=" + fact[rule[i][0]] + "<br>" }; count = 1; break; } } //不匹配 if(flag == 0) { document.getElementById('al2').style.display = 'block'; document.getElementById('result').innerHTML = '未知動物'; } //完全匹配 else if(flag == 1) { document.getElementById('al').style.display = 'block'; document.getElementById('result').innerHTML = end; document.getElementById('result').style.top = "65px"; } //相對匹配 else if(flag == 2) { document.getElementById('al').style.display = 'block'; } else if(flag == 3) { document.getElementById('al').style.display = 'block'; } return 0; } function clickev(id) { //當沒有這個ID值時,把id加入到CON陣列中 if(used == 1) { ne[1] = id; document.getElementById('conclusion').innerHTML = document.getElementById('conclusion').innerHTML + " " + fact[id]; document.getElementById(id).style.background = 'skyBlue'; document.getElementById(id).style.color = 'white'; } else { if(con.indexOf(id) == -1) { if(count >= 5) { alert('最多選擇五個標籤'); return false; } document.getElementById('conclusion').innerHTML = document.getElementById('conclusion').innerHTML + " " + fact[id]; con[count] = id; count++; document.getElementById(id).style.background = 'skyBlue'; document.getElementById(id).style.color = 'white'; } //存在時 則為取消操作 刪除掉此ID值 else { con.splice(con.indexOf(id), 1); var word = document.getElementById('conclusion').innerHTML; word = word.replace(fact[id], ""); document.getElementById('conclusion').innerHTML = word; document.getElementById(id).style.background = 'white'; document.getElementById(id).style.color = 'black'; count--; } } } //點選搜尋後的開始推斷的函式 function start() { document.getElementById('al').style.display = "none"; document.getElementById('pro').style.width = '100%'; inference(); } //重置函式 function reset() { //將所有東西歸零 for(var id = 1; id < 25; id++) { con.splice(con.indexOf(id), 1); document.getElementById('al').innerHTML = ""; document.getElementById(id).style.background = 'white'; document.getElementById(id).style.color = 'black'; document.getElementById('al').style.display = 'none'; document.getElementById('al2').style.display = 'none'; document.getElementById('pro').style.width = '0%'; document.getElementById('result').innerHTML = ""; document.getElementById('result').style.top = "-250px"; document.getElementById('conclusion').innerHTML = "綜合事實庫:<br>"; } count = 0; }
(4)con選定組和rule規則組完全不匹配,這時提示使用者規則庫中無該規則,為未知動物。
四、當每次點選搜尋匹配成功後,在提示框中都會提示該規則使用的條件和推理過程,在綜合資料庫中也會新增選擇的條件選項。提供點選函式(clicked),重置函式(reset)以及執行推理函式(start),分別在點選條件、點選重置、點選搜尋時使用。使頁面的操作變得更加順暢,選擇錯條件時可以再次點選該條件取消條件。