動物識別專家系統(Java實現)

產生式系統

在這裏插入圖片描述

  1. 規則庫
    規則庫是用於描述相應領域內知識的產生式集合。它是產生式系統求解問題的基礎,其中對領域知識表達的完整性、準確性、有效性,將直接影響到系統的性能和效率。因此必須要合理設計和組織規則庫中的知識,檢測並排除冗餘或矛盾的知識。
  2. 事實庫。
    事實庫用於存放問題的初始事實、當前已知的信息、推理過程中形成的中間結論以及最終結論。顯然,事實庫的內容是動態的,是不斷變化的
  3. 推理機。
    推理機由一組程序組成。它控制並協調着整個生產式系統的運行,從而實現對問題的推理求解。通常分 3 步完成:匹配、衝突解決和操作。

問題定義

動物識別專家系統是流行的專家系統實驗模型,它用產生式規則來表示知識,共15條規則、可以識別七種動物,這些規則既少又簡單,可以改造他們,也可以加進新的規則,還可以用來識別其他東西的新規則來取代這些規則。

系統實現

規則、事實和產生式的表示

識別七種動物共需要30個特徵和事實,用0~29給它們編號。

String[] features = {"有毛", "產奶", "有羽毛", "會飛", "會下蛋", "喫肉", "有犬齒", "有爪", "眼睛盯前方", "有蹄",
            "反芻", "黃褐色", "有斑點", "有黑色條紋", "長脖", "長腿", "不會飛", "會游泳", "黑白兩色", "善飛",
            "哺乳類", "鳥類", "肉食類", "蹄類", "企鵝", "海燕", "鴕鳥", "斑馬", "長頸鹿", "虎", "金錢豹"};

產生式規則就用三維數組表示:

int[][][] expr = new int[][][]{
                {{0}, {20}},
                {{1}, {20}},
                {{2}, {21}},
                {{3, 4}, {21}},
                {{20, 5}, {22}},
                {{6, 7, 8}, {22}},
                {{20, 8}, {23}},
                {{20, 9}, {23}},
                {{22, 11, 12}, {30}},
                {{22, 11, 13}, {29}},
                {{23, 14, 15, 12}, {28}},
                // 如果動物是蹄類(23),且有黑色條紋(13),則該動物對應事實數組的第27個“斑馬”
                {{23, 13}, {27}},
                {{21, 14, 15, 16}, {26}},
                {{21, 19}, {25}},
                {{21, 17, 18, 16}, {24}}};

類的設計

  1. Rule類:存放一條規則的前提和結論;能根據給定條件判斷該條規則是否滿足(即是否能得到該條規則的結論);
  2. RuleRepository類:存放事實庫、規則庫並實現推理機。
  3. AnimalIdentificationExpertSystem類:繼承自JFrame,界面類。
// 規則庫,存放已知的所有規則(產生式規則)	
List<Rule> rules = new ArrayList<>();
// 事實庫,動態變化的
List<Integer> conditions = new ArrayList<>();

使用可變的列表,容易添加和刪除已有條件、事實。

匹配順序

在30個事實中:

    String[] features = {"有毛", "產奶", "有羽毛", "會飛", "會下蛋", "喫肉", "有犬齒", "有爪", "眼睛盯前方", "有蹄",
            "反芻", "黃褐色", "有斑點", "有黑色條紋", "長脖", "長腿", "不會飛", "會游泳", "黑白兩色", "善飛",
            "哺乳類", "鳥類", "肉食類", "蹄類", "企鵝", "海燕", "鴕鳥", "斑馬", "長頸鹿", "虎", "金錢豹"};

前20個是用戶輸入的特徵,而下面的四個(“哺乳類”, “鳥類”, “肉食類”, “蹄類”)屬於推理的中間結果,最後的七個(“企鵝”, “海燕”, “鴕鳥”, “斑馬”, “長頸鹿”, “虎”, “金錢豹”)是最終的識別結果。

在用戶輸入條件到事實庫後(這些條件就是事實),事實庫並不是不變的

比如用戶輸入了0(“有毛”)、5(“喫肉”),那麼其實真正的事實庫是(0、5、20),因爲在匹配第一條規則:{{0}, {20}}的時候,有條件0,所以可以得到規則1的結論(20),並且該結論也應當加入事實庫,因爲這是已經知道的了,然後匹配到規則5:{{20, 5}, {22}}時,就可以得到結論22(“肉食類”)。

所以在從上到下匹配這15條產生式規則的過程中,如果匹配了某一條產生式規則,就該把這條規則的結論加入事實庫;而且也發現了匹配規則是要注意順序的,上面的例子中如果先匹配了規則5,那麼此時事實庫中只有(0和5),就得不到中間結論22。

這說明規則的擺放是要有順序的,產生某編號的規則(即結論爲某編號規則)應該排在使用該編號的規則(即條件爲某編號規則)之前。這15條結論是正好符合這樣的順序的。

推理機

有了上面的順序意識之後,推理機的實現就很容易了:就是從上到下,從第一條產生式規則開始判斷當前的事實庫能否匹配每條規則,匹配成功,就把該條規則的結論編號加入事實庫,匹配完規則庫中所有產生式規則後就可以輸出結論了(我的處理):

  • 中間結論(“哺乳類”, “鳥類”, “肉食類”, “蹄類”)輸出到推理框中展示正向推理過程;
  • 最終結論(七種動物)框出對應的圖片;

結果演示

什麼結論都推不出(一條結論都沒匹配上):
在這裏插入圖片描述
推出中間結果:
在這裏插入圖片描述
推出最終結果,識別到了動物:
在這裏插入圖片描述
在這裏插入圖片描述

源代碼

Java實現(IDE爲IDEA)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章