精华内容
下载资源
问答
  • 动物识别专家系统

    2018-05-06 17:05:43
    简单的动物识别专家系统说明文档(附代码),希望有帮到你们
  • 人工智能动物识别专家系统 依照以下15条规则,根据所提供的条件,实现对某种动物的识别。 R1: 如果某动物有毛发,则该动物是哺乳类动物; R2:如果某动物有奶,则该动物是哺乳类动物; R3:如果某动物有羽毛,则该动物...
  • 智能信息 大作业 代码 专家系统 作业 专家系统 动物识别专家系统设计 含代码
  • c++语言写的mfc动物识别专家系统。界面友好,实现了数据和推理的分离,实现了事实库与规则库的增删改查功能,可模糊识别,是本人人工智能课程亲自写的产生式系统实验,欢迎下载!
  • 专家系统的实例—动物识别专家系统 识别7种动物
  • 使用MFC实现的动物识别专家系统小的模拟程序,可以识别老虎、金钱豹、信天翁等7中动物,仅供参考~
  • 使用vs2010写的简单的动物识别专家系统,代码能运行,有界面
  • 可编辑 可编辑 题目 动物识别专家系统 二 实验目的 理解并掌握基于规则系统的表示与推理 学会编写小型的生产式系统理解正向推理和反向推理的过程以及两者的区 别 学会设计简单的人机交互界面 三 实验内容 动物识别...
  • 动物识别专家系统是流行的专家系统实验模型
  • 一个动物识别专家系统在 JAVA语言下的实现<br>内附有 Java原代码 打包的jar文件 相关的论文等
  • title: 动物识别专家系统课程设计 date: 2017-12-23 18:44:13 tags: categories: python 设计一个可以识别7种动物的专家系统,可以根据前提推导出结论,如果只有部分前提,询问提示。 RD.txt是规则库,一行一条,...

    title: 动物识别专家系统课程设计
    date: 2017-12-23 18:44:13
    tags:
    categories: python


    设计一个可以识别7种动物的专家系统,可以根据前提推导出结论,如果只有部分前提,询问提示。
    RD.txt是规则库,一行一条,每条空格分隔,前面是前提,最后一个是结论。
    用PyQt5设计界面

    RD.txt

    
    有毛发 哺乳动物
    有奶 哺乳动物
    有羽毛 鸟
    会飞 下蛋 鸟
    吃肉 食肉动物
    有犬齿 有爪 眼盯前方 食肉动物
    哺乳动物 有蹄 有蹄类动物
    哺乳动物 嚼反刍动物 有蹄类动物
    哺乳动物 食肉动物 黄褐色 暗斑点 金钱豹
    哺乳动物 食肉动物 黄褐色 黑色条纹 虎
    有蹄类动物 长脖子 长腿 暗斑点 长颈鹿
    有蹄类动物 黑色条纹 斑马
    鸟 长脖子 长腿 黑白二色 不飞 鸵鸟
    鸟 会游泳 不飞 黑白二色 企鹅
    鸟 善飞 信天翁
    

    主要文件,包含界面
    main.py

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    from PyQt5 import QtCore, QtGui, QtWidgets
    import sys
    
    
    class Ui_Form(object):
        def setupUi(self, Form):
            Form.setObjectName("Form")
            Form.setGeometry(100, 200, 623, 300)
            self.groupBox = QtWidgets.QGroupBox(Form)
            self.groupBox.setGeometry(QtCore.QRect(10, -20, 600, 311))
            self.groupBox.setTitle("")
            self.groupBox.setObjectName("groupBox")
            self.label = QtWidgets.QLabel(self.groupBox)
            self.label.setGeometry(QtCore.QRect(30, 40, 61, 18))
            self.label.setAlignment(QtCore.Qt.AlignCenter)
            self.label.setObjectName("label")
            self.label_2 = QtWidgets.QLabel(self.groupBox)
            self.label_2.setGeometry(QtCore.QRect(470, 40, 101, 18))
            self.label_2.setAlignment(QtCore.Qt.AlignCenter)
            self.label_2.setObjectName("label_2")
            self.pushButton = QtWidgets.QPushButton(self.groupBox)
            self.pushButton.setGeometry(QtCore.QRect(230, 35, 88, 27))
            self.pushButton.setObjectName("pushButton")
            self.pushButton_2 = QtWidgets.QPushButton(self.groupBox)
            self.pushButton_2.setGeometry(QtCore.QRect(475, 190, 88, 27))
            self.pushButton_2.setObjectName("pushButton_2")
            self.pushButton_2.clicked.connect(self.btn2_click)
            self.pushButton_3 = QtWidgets.QPushButton(self.groupBox)
            self.pushButton_3.setGeometry(QtCore.QRect(475, 240, 88, 27))
            self.pushButton_3.setObjectName("pushButton_3")
            self.pushButton_3.clicked.connect(QtCore.QCoreApplication.instance().quit)
            self.pushButton_4 = QtWidgets.QPushButton(self.groupBox)
            self.pushButton_4.setGeometry(475, 140, 88, 27)
            self.pushButton_4.setObjectName("pushButton_4")
            self.pushButton_4.clicked.connect(self.topological)
            self.textEdit = QtWidgets.QTextEdit(self.groupBox)
            self.textEdit.setGeometry(QtCore.QRect(20, 80, 80, 211))
            self.textEdit.setObjectName("textEdit")
            self.textEdit_2 = QtWidgets.QTextEdit(self.groupBox)
            self.textEdit_2.setGeometry(QtCore.QRect(110, 80, 331, 211))
            self.textEdit_2.setObjectName("textEdit_2")
            self.textEdit_2.setReadOnly(True)
            self.lineEdit = QtWidgets.QLineEdit(self.groupBox)
            self.lineEdit.move(460, 90)
            self.lineEdit.setReadOnly(True)
            self.pushButton.clicked.connect(self.go)
    
            self.retranslateUi(Form)
            QtCore.QMetaObject.connectSlotsByName(Form)
    
        def btn2_click(self):
            if self.pushButton_2.text() != "确定输入":
                self.pushButton_2.setText("确定输入")
            else:
                self.pushButton_2.setText("修改知识库")
    
        def retranslateUi(self, Form):
            _translate = QtCore.QCoreApplication.translate
            Form.setWindowTitle(_translate("Form", "动物识别专家系统"))
            self.label.setText(_translate("Form", "输入事实"))
            self.label_2.setText(_translate("Form", "显示推理结果"))
            self.pushButton.setText(_translate("Form", "进行推理"))
            self.pushButton_2.setText(_translate("Form", "修改知识库"))
            self.pushButton_3.setText(_translate("Form", "退出程序"))
            self.pushButton_4.setText(_translate("From", "整理知识库"))
    
        # 将知识库做拓扑排序
        def topological(self):
            Q = []
            P = []
            ans = ""  # 排序后的结果
            for line in open('RD.txt'):
                line = line.strip('\n')
                if line == '':
                    continue
                line = line.split(' ')
                Q.append(line[line.__len__() - 1])
                del (line[line.__len__() - 1])
                P.append(line)
    
            # 计算入度
            inn = []
            for i in P:
                sum = 0
                for x in i:
                    if Q.count(x) > 0:  # 能找到,那么
                        sum += Q.count(x)
                inn.append(sum)
    
            while (1):
                x = 0
                if inn.count(-1) == inn.__len__():
                    break
                for i in inn:
                    if i == 0:
                        str = ' '.join(P[x])
                        # print("%s %s" %(str, Q[x]))
                        ans = ans + str + " " + Q[x] + "\n"  # 写入结果
                        # print("%s -- %s" %(P[x],Q[x]))
                        inn[x] = -1
                        # 更新入度
                        y = 0
                        for j in P:
                            if j.count(Q[x]) == 1:
                                inn[y] -= 1
                            y += 1
                    x += 1
            print(ans)
    
            # 将结果写入文件
            fw = open('RD.txt', 'w', buffering=1)
            fw.write(ans)
            fw.flush()
            fw.close()
    
        # 进行推理
        def go(self, flag=True):
            # 将产生式规则放入规则库中
            # if P then Q
            # 读取产生式文件
            self.Q = []
            self.P = []
            fo = open('RD.txt', 'r', encoding='utf-8')
            for line in fo:
                line = line.strip('\n')
                if line == '':
                    continue
                line = line.split(' ')
                self.Q.append(line[line.__len__() - 1])
                del (line[line.__len__() - 1])
                self.P.append(line)
            fo.close()
            print("go按钮按下")
            self.lines = self.textEdit.toPlainText()
            self.lines = self.lines.split('\n')  # 分割成组
            self.DB = set(self.lines)
            print(self.DB)
            self.str = ""
            print(self.str)
            flag = True
            temp = ""
            for x in self.P:  # 对于每条产生式规则
                if ListInSet(x, self.DB):  # 如果所有前提条件都在规则库中
                    self.DB.add(self.Q[self.P.index(x)])
                    temp = self.Q[self.P.index(x)]
                    flag = False  # 至少能推出一个结论
                    # print("%s --> %s" %(x, self.Q[self.P.index(x)]))
                    self.str += "%s --> %s\n" % (x, self.Q[self.P.index(x)])
    
            if flag:  # 一个结论都推不出
                print("一个结论都推不出")
                for x in self.P:  # 对于每条产生式
                    if ListOneInSet(x, self.DB):  # 事实是否满足部分前提
                        flag1 = False       # 默认提问时否认前提
                        for i in x:  # 对于前提中所有元素
                            if i not in self.DB:  # 对于不满足的那部分
                                btn = s.quest("是否" + i)
                                if btn == QtWidgets.QMessageBox.Ok:
                                    self.textEdit.setText(self.textEdit.toPlainText() + "\n" + i)  # 确定则增加到textEdit
                                    self.DB.add(i)  # 确定则增加到规则库中
                                    flag1 = True    # 肯定前提
                                    # self.go(self)
                        if flag1:  # 如果肯定前提,则重新推导
                            self.go()
                            return
    
            self.textEdit_2.setPlainText(self.str)
            print("----------------------")
            print(self.str)
            if flag:
                btn = s.alert("啥也推不出来!!!")
                # if btn == QtWidgets.QMessageBox.Ok:  # 点击确定
                #     self.textEdit.setText(self.textEdit.toPlainText() + "\n确定")
            else:
                self.lineEdit.setText(temp)
    
    
    # 判断list中至少有一个在集合set中
    def ListOneInSet(li, se):
        for i in li:
            if i in se:
                return True
        return False
    
    
    # 判断list中所有元素是否都在集合set中
    def ListInSet(li, se):
        for i in li:
            if i not in se:
                return False
        return True
    
    
    class SecondWindow(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(SecondWindow, self).__init__(parent)
            self.setWindowTitle("修改知识库")
            self.setGeometry(725, 200, 300, 300)
            self.textEdit = QtWidgets.QTextEdit(self)
            self.textEdit.setGeometry(8, 2, 284, 286)
    
    
        # 警告没有推导结果
        def alert(self, info):
            QtWidgets.QMessageBox.move(self, 200, 200)
            QtWidgets.QMessageBox.information(self, "Information", self.tr(info))
    
        # 询问补充事实
        def quest(self, info):
            # 如果推理为空,需要询问用户是否要添加已知条件
            QtWidgets.QMessageBox.move(self, 200, 200)
            button = QtWidgets.QMessageBox.question(self, "Question",
                                                    self.tr(info),
                                                    QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel,
                                                    QtWidgets.QMessageBox.Cancel)
            return button
    
        def handle_click(self):
            if not self.isVisible():
                # 读取文件放到多行文本框中
                str = ""
                fo = open('RD.txt', 'r', encoding='utf-8')
                for line in fo:
                    line = line.strip('\n')
                    if line == '':
                        continue
                    str = str + line + "\n"
                fo.close()
                self.textEdit.setText(str)
                self.show()
            else:
                # 输出文本框内容
                self.str = self.textEdit.toPlainText()
                print(self.str)
    
                # 将文本框内容写入文件
                self.fw = open('RD.txt', 'w')
                self.fw.write(self.str)
                self.fw.close()  # 关闭文件
                self.close()  # 关闭窗口
    
        def handle_close(self):
            self.close()
    
    
    if __name__ == "__main__":
        app = QtWidgets.QApplication(sys.argv)
        widget = QtWidgets.QWidget()
        ui = Ui_Form()
        ui.setupUi(widget)
        widget.show()
        s = SecondWindow()
        ui.pushButton_2.clicked.connect(s.handle_click)
        sys.exit(app.exec_())

    linux下开发,在Windows下运行可能需要将open函数的encoding设定为gbk

    转载于:https://www.cnblogs.com/lepeCoder/p/8094136.html

    展开全文
  • 动物识别专家系统 Java 简单实现

    千次阅读 多人点赞 2019-07-23 17:02:48
    不再BB什么是专家系统了,自行百度,这篇博客专门帮助写作业的,人工智能导论课要求写一个动物识别专家系统,这就是一个很好的实现,编了2天,有界面,有功能,分享给需要的同学。 直接上源代码,开箱即用,包括正向...

    不再BB什么是专家系统了,自行百度,这篇博客专门帮助写作业的,人工智能导论课要求写一个动物识别专家系统,这就是一个很好的实现,编了2天,有界面,有功能,分享给需要的同学。
    直接上源代码,开箱即用,包括正向推理,反向推理,知识库的维护等功能,具体讲解有时间会更新。

    注:启动的时候由于没有知识库文件,会有一次报错,之后自动创建知识库文件,首次运行之后便不再报错。

    完整项目地址参考(包括写好的知识库文件):https://github.com/qianqianjun/AI_HomeWork

    程序运行截图:

    • 正向推理:
      在这里插入图片描述

    • 反向推理:
      从一个假设出发,基于这个假设来询问你一些问题,根据实际回答,根据回答判断假设是否成立。
      在这里插入图片描述
      一边问问题,一边进行推理并且展示当前得到的结论:
      在这里插入图片描述
      连续问了几个问题之后就可以推理出结果了。
      在这里插入图片描述

    • 规则库的维护,增加,修改,查找,删除都有,不再赘述:
      在这里插入图片描述

    • ProfessionalSystem.java

      用于实现主要的界面和主要的程序功能逻辑,代码很长,绝大部分都是界面代码,真正的逻辑不多

    package expert;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.io.*;
    import java.util.ArrayList;
    import java.util.List;
    public class ProfessionalSystem {
        private List<Regular> regulars;
        private JFrame frame;
        private Regular currentRegular;
        private Integer currentRegularIndex;
        private Boolean addToRegulars(Regular regular){
            for(Regular re:regulars){
                if(re.equals(regular)){
                    return false;
                }
            }
            this.regulars.add(regular);
            return true;
        }
        private Regular getByIndex(String id) {
            for(Integer i=0;i<this.regulars.size();i++){
                if(this.regulars.get(i).getIndex().toString().equals(id)){
                    return this.regulars.get(i);
                }
            }
            return null;
        }
        private void addMenu(){
            this.frame=new JFrame("专家系统");
            try {
                UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
            }catch (Exception e){
                e.printStackTrace();
            }
            JMenuBar menuBar=new JMenuBar();
            JMenu direction=new JMenu("推理方向");
            JMenuItem item=new JMenuItem("正向推理");
            JMenuItem item0=new JMenuItem("反向推理");
            direction.add(item);
            direction.add(item0);
            menuBar.add(direction);
    
            JMenu function=new JMenu("功能");
            JMenuItem item1=new JMenuItem("添加规则");
            JMenuItem item2=new JMenuItem("删除规则");
            JMenuItem item3=new JMenuItem("修改规则");
            function.add(item1);
            function.add(item2);
            function.add(item3);
            menuBar.add(function);
            /**
             * 为每一个菜单栏添加事件
             */
            // 正向推理:
            item.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    positive();
                }
            });
            // 反向推理:
            item0.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    reverse();
                }
            });
    
            //添加规则
            item1.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    addRegular();
                }
            });
            //删除规则
            item2.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    removeRegular();
                }
            });
            //修改规则
            item3.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    fixRegular();
                }
            });
            this.frame.setJMenuBar(menuBar);
            this.frame.setLocationRelativeTo(null);
            this.frame.setSize(1000,800);
            this.frame.addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent e) {
                    super.windowClosing(e);
                    for(Integer i=0;i<regulars.size();i++){
                        regulars.get(i).setIndex(i);
                    }
                    try {
                        OutputStream outputStream=new FileOutputStream(new File("./regularSet.dat"));
                        ObjectOutputStream objectOutputStream=new ObjectOutputStream(outputStream);
                        objectOutputStream.writeObject(regulars);
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                }
            });
            this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
        private void positive(){
            this.frame.getContentPane().removeAll();
            positiveUi();
            this.frame.repaint();
        }
        private void reverse(){
            this.frame.getContentPane().removeAll();
            reverseUi();
            this.frame.repaint();
        }
        private void fixRegular(){
            this.frame.getContentPane().removeAll();
            fixUi();
            System.out.println("修改规则");
            this.frame.repaint();
        }
        private void addRegular(){
            this.frame.getContentPane().removeAll();
            addUi();
            System.out.println("添加规则");
            this.frame.repaint();
        }
        private void removeRegular(){
            this.frame.getContentPane().removeAll();
            removeUi();
            System.out.println("删除规则");
            this.frame.repaint();
        }
        private void fixUi(){
            final JPanel inputPanle=new JPanel();
            inputPanle.setPreferredSize(new Dimension(600,100));
            inputPanle.setLayout(null);
            JLabel title=new JLabel("输入关键词搜索知识库");
            title.setFont(new Font("宋体",0,20));
            title.setBounds(10,10,300,30);
            final JTextField keyWord=new JTextField();
            keyWord.setBounds(10,50,400,40);
            keyWord.setFont(new Font("宋体",0,20));
            keyWord.setMargin(new Insets(5,10,5,10));
            JButton searchBtn=new JButton("搜 索");
            searchBtn.setBounds(420,50,90,40);
            searchBtn.setFont(new Font("宋体",0,20));
    
            final JTextField fixId=new JTextField();
            fixId.setFont(new Font("宋体",0,20));
            fixId.setMargin(new Insets(5,10,5,10));
            fixId.setBounds(540,50,265,40);
    
            JButton selectBtn=new JButton("选择规则");
            selectBtn.setBounds(820,50,120,40);
            selectBtn.setFont(new Font("宋体",0,20));
    
    
            inputPanle.add(selectBtn);
            inputPanle.add(fixId);
            inputPanle.add(keyWord);
            inputPanle.add(searchBtn);
            inputPanle.add(title);
    
            // 初始化结果展示界面:
            final JTextArea textArea=new JTextArea();
            textArea.setFont(new Font("宋体",0,20));
            textArea.setMargin(new Insets(10,10,10,10));
            textArea.setLineWrap(true);
            JLabel label =new JLabel("查询到的结果如下:");
            label.setBounds(10,5,300,30);
            label.setFont(new Font("宋体",0,20));
            JScrollPane scrollPane=new JScrollPane(textArea);
            scrollPane.setBounds(10,40,500,575);
            scrollPane.setBackground(new Color(0xD9FFDE));
    
            JPanel searchResult=new JPanel();
            searchResult.setLayout(null);
            searchResult.add(scrollPane);
            searchResult.add(label);
            searchResult.setPreferredSize(new Dimension(520,580));
    
    
            JPanel deleteInfo=new JPanel();
            deleteInfo.setLayout(null);
            deleteInfo.setPreferredSize(new Dimension(450,500));
            final JTextArea info=new JTextArea();
            info.setFont(new Font("宋体",0,20));
            info.setMargin(new Insets(10,10,10,10));
            final JScrollPane deleteItemScrollPane=new JScrollPane(info);
            deleteItemScrollPane.setBounds(10,40,400,250);
    
            JLabel resLabel=new JLabel("您将修改下面规则的结论");
            resLabel.setBounds(10,300,400,40);
            resLabel.setFont(new Font("宋体",0,20));
            final JTextArea res=new JTextArea();
            res.setMargin(new Insets(10,10,10,10));
            res.setFont(new Font("宋体",0,20));
            JScrollPane result=new JScrollPane(res);
            result.setBounds(10,350,400,150);
            JLabel deleteLabel=new JLabel("您将修改下面规则的条件");
            deleteLabel.setFont(new Font("宋体",0,20));
            deleteLabel.setBounds(10,5,300,40);
            JButton submit=new JButton("提 交");
            submit.setFont(new Font("宋体",0,20));
            submit.setBounds(10,510,100,40);
            deleteInfo.add(deleteItemScrollPane);
            deleteInfo.add(submit);
            deleteInfo.add(deleteLabel);
            deleteInfo.add(result);
            deleteInfo.add(resLabel);
            searchBtn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    textArea.setText("");
                    String key=keyWord.getText();
                    if(key.equals("")){
                        for(Regular re:regulars){
                            textArea.append(re.toString());
                            textArea.append("\n==========================\n");
                        }
                    }
                    else{
                        for(Regular re:regulars){
                            List<String> conditions=re.getConditions();
                            for(String con:conditions){
                                if(key.equals(con) || key.indexOf(con)!=-1 || con.indexOf(key)!=-1){
                                    textArea.append(re.toString());
                                    textArea.append("\n==========================\n");
                                    break;
                                }
                            }
                            if(re.getResult().indexOf(key)!=-1||
                                    key.indexOf(re.getResult())!=-1 ||
                                    re.getResult().equals(key)){
                                textArea.append(re.toString());
                                textArea.append("\n==========================\n");
                            }
                        }
                    }
                }
            });
            selectBtn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    String id=fixId.getText();
                    Regular re=getByIndex(id);
                    if(re==null){
                        JOptionPane.showMessageDialog(null,"当前知识库没有您查询的知识",
                                "提示",JOptionPane.ERROR_MESSAGE);
                    }
                    else{
                        info.setText(re.conditionToString());
                        res.setText(re.getResult());
                        currentRegularIndex = Integer.parseInt(id);
                    }
                }
            });
            submit.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    String condition=info.getText();
                    String result=res.getText();
                    if(result.equals("")|| condition.equals("")){
                        JOptionPane.showMessageDialog(null,"请您将内容填写完整","提示",
                                JOptionPane.ERROR_MESSAGE);
                    }
                    else{
                        Integer type=JOptionPane.showConfirmDialog(null,
                                "这条规则设置为终止规则?","提示",
                                JOptionPane.YES_NO_OPTION);
    
                        // -1 直接关闭  0 是  1 否
                        if(type==-1){
                            JOptionPane.showMessageDialog(null,"取消修改","提示",
                                    JOptionPane.PLAIN_MESSAGE);
                        }
                        else {
                            if(type==0){
                                regulars.get(currentRegularIndex).setTerminal(true);
                            }
                            else{
                                regulars.get(currentRegularIndex).setTerminal(false);
                            }
                            regulars.get(currentRegularIndex).setConditions(condition.split("\n"));
                            regulars.get(currentRegularIndex).setResult(result);
                            JOptionPane.showMessageDialog(null, "修改成功", "提示",
                                    JOptionPane.PLAIN_MESSAGE);
                        }
                    }
                }
            });
    
            this.frame.add(inputPanle,BorderLayout.NORTH);
            this.frame.add(searchResult,BorderLayout.WEST);
            this.frame.add(deleteInfo,BorderLayout.EAST);
            this.frame.setVisible(true);
        }
        private void addUi(){
            final JPanel inputPanle=new JPanel();
            inputPanle.setPreferredSize(new Dimension(600,300));
            inputPanle.setLayout(null);
            final JTextArea textAreaLeft=new JTextArea();
            textAreaLeft.setFont(new Font("宋体",0,20));
            textAreaLeft.setMargin(new Insets(10,10,10,10));
            textAreaLeft.setLineWrap(true);
    
            final JTextArea textAreaRight=new JTextArea();
            textAreaRight.setFont(new Font("宋体",0,20));
            textAreaRight.setMargin(new Insets(10,10,10,10));
            textAreaRight.setLineWrap(true);
    
            JLabel label =new JLabel("添加规则");
            label.setBounds(10,10,300,30);
            label.setFont(new Font("宋体",0,20));
    
    
    
            JLabel leftTip =new JLabel("输入条件");
            leftTip.setFont(new Font("宋体",0,15));
            leftTip.setBounds(10,40,400,20);
            JScrollPane scrollLeft=new JScrollPane(textAreaLeft);
            scrollLeft.setBounds(10,65,460,150);
            scrollLeft.setBackground(new Color(0xD9FFDE));
    
            final JLabel rightTip=new JLabel("输入结论,只可以填写一个");
            rightTip.setFont(new Font("宋体",0,15));
            rightTip.setBounds(485,40,400,20);
            JScrollPane scrollRight=new JScrollPane(textAreaRight);
            scrollRight.setBounds(480,65,485,150);
            scrollRight.setBackground(new Color(0xD9FFDE));
    
            inputPanle.add(scrollLeft);
            inputPanle.add(scrollRight);
            inputPanle.add(leftTip);
            inputPanle.add(rightTip);
            JButton button=new JButton("规则预览");
            inputPanle.add(button);
    
            button.setBounds(10,240,100,30);
            inputPanle.add(label);
            JPanel displayPanel=new JPanel();
            displayPanel.setLayout(null);
    
            final JTextArea output=new JTextArea();
            output.setLineWrap(true);
            output.setFont(new Font("宋体",0,20));
            output.setMargin(new Insets(10,10,10,10));
            JScrollPane display=new JScrollPane(output);
            JLabel tip=new JLabel("生成的规则如下:");
            tip.setBounds(10,0,300,30);
            display.setBounds(10,32,960,300);
            tip.setFont(new Font("宋体",0,20));
    
            JButton submit=new JButton("提交");
            submit.setBounds(10,340,100,30);
            displayPanel.add(submit);
    
            displayPanel.add(tip);
            displayPanel.add(display);
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    String regu=textAreaLeft.getText();
                    String result=textAreaRight.getText();
                    if(regu.equals("")){
                        JOptionPane.showMessageDialog(null,"请输入规则","提示",JOptionPane.ERROR_MESSAGE);
                    }
                    if(result.equals("")){
                        JOptionPane.showMessageDialog(null,"请您输入结果","提示",JOptionPane.ERROR_MESSAGE);
                    }
                    if(!result.equals("") && !regu.equals("")){
                        Regular regular=new Regular(regu.split("\n"));
                        regular.setResult(result);
                        currentRegular=regular;
                        output.setText(regular.toString());
                    }
                }
            });
            submit.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if(currentRegular==null){
                        JOptionPane.showMessageDialog(null,"请你先预览规则",
                                "提示",JOptionPane.ERROR_MESSAGE);
                    }
                    else {
                        Integer type=JOptionPane.showConfirmDialog(null,"将这条规则设置为终止规则么?","提示",
                                JOptionPane.YES_NO_OPTION);
                        if(type==-1){
                            JOptionPane.showMessageDialog(null,"取消添加","提示",
                                    JOptionPane.PLAIN_MESSAGE);
                        }
                        else {
                            if(type==0)
                                currentRegular.setTerminal(true);
                            else
                                currentRegular.setTerminal(false);
                            Boolean ok = addToRegulars(currentRegular);
                            if (ok) {
                                currentRegular.setIndex(regulars.size() - 1);
                                JOptionPane.showMessageDialog(null, "添加成功!",
                                        "提示", JOptionPane.PLAIN_MESSAGE);
                            } else {
                                JOptionPane.showMessageDialog(null, "添加失败,已经存在",
                                        "提示", JOptionPane.ERROR_MESSAGE);
                            }
                            currentRegular = null;
                        }
                    }
                }
            });
            this.frame.add(displayPanel,BorderLayout.CENTER);
            this.frame.add(inputPanle,BorderLayout.NORTH);
            this.frame.setVisible(true);
        }
        private void removeUi(){
            final JPanel inputPanle=new JPanel();
            inputPanle.setPreferredSize(new Dimension(600,100));
            inputPanle.setLayout(null);
            JLabel title=new JLabel("输入关键词搜索知识库");
            title.setFont(new Font("宋体",0,20));
            title.setBounds(10,10,300,30);
            final JTextField keyWord=new JTextField();
            keyWord.setBounds(10,50,400,40);
            keyWord.setFont(new Font("宋体",0,20));
            keyWord.setMargin(new Insets(5,10,5,10));
            JButton searchBtn=new JButton("搜 索");
            searchBtn.setBounds(420,50,90,40);
            searchBtn.setFont(new Font("宋体",0,20));
    
            final JTextField deleteId=new JTextField();
            deleteId.setFont(new Font("宋体",0,20));
            deleteId.setMargin(new Insets(5,10,5,10));
            deleteId.setBounds(540,50,265,40);
    
            JButton deleteBtn=new JButton("删除规则");
            deleteBtn.setBounds(820,50,120,40);
            deleteBtn.setFont(new Font("宋体",0,20));
    
    
            inputPanle.add(deleteBtn);
            inputPanle.add(deleteId);
            inputPanle.add(keyWord);
            inputPanle.add(searchBtn);
            inputPanle.add(title);
    
            // 初始化结果展示界面:
            final JTextArea textArea=new JTextArea();
            textArea.setFont(new Font("宋体",0,20));
            textArea.setMargin(new Insets(10,10,10,10));
            textArea.setLineWrap(true);
            JLabel label =new JLabel("查询到的结果如下:");
            label.setBounds(10,5,300,30);
            label.setFont(new Font("宋体",0,20));
            JScrollPane scrollPane=new JScrollPane(textArea);
            scrollPane.setBounds(10,40,500,575);
            scrollPane.setBackground(new Color(0xD9FFDE));
    
            JPanel searchResult=new JPanel();
            searchResult.setLayout(null);
            searchResult.add(scrollPane);
            searchResult.add(label);
            searchResult.setPreferredSize(new Dimension(520,580));
    
    
            JPanel deleteInfo=new JPanel();
            deleteInfo.setLayout(null);
            deleteInfo.setPreferredSize(new Dimension(450,500));
            final JTextArea info=new JTextArea();
            info.setFont(new Font("宋体",0,20));
            info.setMargin(new Insets(10,10,10,10));
            JScrollPane deleteItemScrollPane=new JScrollPane(info);
            deleteItemScrollPane.setBounds(10,40,400,400);
            JLabel deleteLabel=new JLabel("您已将下面的规则删除");
            deleteLabel.setFont(new Font("宋体",0,20));
            deleteLabel.setBounds(10,5,300,40);
            deleteInfo.add(deleteItemScrollPane);
            deleteInfo.add(deleteLabel);
            searchBtn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    textArea.setText("");
                    String key=keyWord.getText();
                    if(key.equals("")){
                        for(Regular re:regulars){
                            textArea.append(re.toString());
                            textArea.append("\n==========================\n");
                        }
                    }
                    else{
                        for(Regular re:regulars){
                            List<String> conditions=re.getConditions();
                            for(String con:conditions){
                                if(key.equals(con) || key.indexOf(con)!=-1 || con.indexOf(key)!=-1){
                                    textArea.append(re.toString());
                                    textArea.append("\n==========================\n");
                                    break;
                                }
                            }
                            if(re.getResult().indexOf(key)!=-1||
                                    key.indexOf(re.getResult())!=-1 ||
                                    re.getResult().equals(key)){
                                textArea.append(re.toString());
                                textArea.append("\n==========================\n");
                            }
                        }
                    }
                }
            });
            deleteBtn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    String id =deleteId.getText();
                    Regular re=getByIndex(id);
                    if(re==null)
                        JOptionPane.showMessageDialog(null,"当前知识库没有您要找的知识",
                                "提示",JOptionPane.ERROR_MESSAGE);
                    else {
                        info.setText(re.toString());
                        regulars.remove(re);
                    }
                }
            });
            this.frame.add(inputPanle,BorderLayout.NORTH);
            this.frame.add(searchResult,BorderLayout.WEST);
            this.frame.add(deleteInfo,BorderLayout.EAST);
            this.frame.setVisible(true);
        }
        private void reverseUi() {
            final JPanel inputPanle=new JPanel();
            inputPanle.setPreferredSize(new Dimension(600,250));
            inputPanle.setLayout(null);
            final JTextArea textArea=new JTextArea();
            textArea.setFont(new Font("宋体",0,20));
            textArea.setMargin(new Insets(10,10,10,10));
            textArea.setLineWrap(true);
            JLabel label =new JLabel("输入假设,回答问题,逆向推理!");
            label.setBounds(10,10,300,30);
            label.setFont(new Font("宋体",0,20));
            JScrollPane scrollPane=new JScrollPane(textArea);
            scrollPane.setBounds(10,40,960,150);
            scrollPane.setBackground(new Color(0xD9FFDE));
            inputPanle.add(scrollPane);
            JButton button=new JButton("推理");
            button.setBounds(10,200,100,30);
    
            inputPanle.add(button);
            inputPanle.add(label);
            JPanel displayPanel=new JPanel();
            displayPanel.setLayout(null);
    
            final JTextArea output=new JTextArea();
            output.setLineWrap(true);
            output.setFont(new Font("宋体",0,20));
            output.setMargin(new Insets(10,10,10,10));
            JScrollPane display=new JScrollPane(output);
            JLabel tip=new JLabel("推理过程和结果如下:");
            tip.setBounds(10,0,300,30);
            display.setBounds(10,32,960,450);
            tip.setFont(new Font("宋体",0,20));
    
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    String factStr=textArea.getText();
                    if(factStr.equals("")){
                        JOptionPane.showMessageDialog(null,"请你输入内容",
                                "提示",JOptionPane.ERROR_MESSAGE);
                    }
                    else{
                        ReasoningMachine machine=new ReasoningMachine(new Fact(),regulars,factStr,output);
                        machine.reverseReasoning();
                    }
                }
            });
            displayPanel.add(tip);
            displayPanel.add(display);
            this.frame.add(displayPanel,BorderLayout.CENTER);
            this.frame.add(inputPanle,BorderLayout.NORTH);
            this.frame.setVisible(true);
        }
        private void positiveUi(){
            final JPanel inputPanle=new JPanel();
            inputPanle.setPreferredSize(new Dimension(600,250));
            inputPanle.setLayout(null);
            final JTextArea textArea=new JTextArea();
            textArea.setFont(new Font("宋体",0,20));
            textArea.setMargin(new Insets(10,10,10,10));
            textArea.setLineWrap(true);
            JLabel label =new JLabel("填写事实,(回车分隔)正向推理");
            label.setBounds(10,10,300,30);
            label.setFont(new Font("宋体",0,20));
            JScrollPane scrollPane=new JScrollPane(textArea);
            scrollPane.setBounds(10,40,960,150);
            scrollPane.setBackground(new Color(0xD9FFDE));
            inputPanle.add(scrollPane);
            JButton button=new JButton("推理");
            button.setBounds(10,200,100,30);
    
            inputPanle.add(button);
            inputPanle.add(label);
            JPanel displayPanel=new JPanel();
            displayPanel.setLayout(null);
    
            final JTextArea output=new JTextArea();
            output.setLineWrap(true);
            output.setFont(new Font("宋体",0,20));
            output.setMargin(new Insets(10,10,10,10));
            JScrollPane display=new JScrollPane(output);
            JLabel tip=new JLabel("推理过程和结果如下:");
            tip.setBounds(10,0,300,30);
            display.setBounds(10,32,960,450);
            tip.setFont(new Font("宋体",0,20));
    
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    String factStr=textArea.getText();
                    if(factStr.equals("")){
                        JOptionPane.showMessageDialog(null,"请你输入内容",
                                "提示",JOptionPane.ERROR_MESSAGE);
                    }
                    else{
                        Fact fact=new Fact(factStr,"\n");
                        System.out.println(fact.getFactItemList());
                        ReasoningMachine machine=new ReasoningMachine(fact,regulars);
                        String res=machine.positiveReasoning();
                        output.setText(res);
                    }
                }
            });
            displayPanel.add(tip);
            displayPanel.add(display);
            this.frame.add(displayPanel,BorderLayout.CENTER);
            this.frame.add(inputPanle,BorderLayout.NORTH);
            this.frame.setVisible(true);
        }
        public ProfessionalSystem(Object object) throws IOException, ClassNotFoundException {
            this.regulars=(List<Regular>) object;
            this.addMenu();
            this.positiveUi();
        }
        public static void main(String[] args) {
            try {
                FileInputStream fileInputStream=new FileInputStream(new File("./regularSet.dat"));
                ObjectInputStream objectInputStream=new ObjectInputStream(fileInputStream);
                ProfessionalSystem pro = new ProfessionalSystem(objectInputStream.readObject());
                objectInputStream.close();
                fileInputStream.close();
    
            }catch (IOException e){
                System.out.println("找不到知识库文件");
                try {
                    FileOutputStream fileOutputStream = new FileOutputStream(new File("./regularSet.dat"));
                    ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
                    objectOutputStream.writeObject(new ArrayList<Regular>());
                }catch (Exception fe){
                    fe.printStackTrace();
                }
            }catch (ClassNotFoundException e){
                System.out.println("知识库文件损坏,无法打开知识库文件");
            }
        }
    }
    
    
    
    • Fact.java

      一个数据结构,来表述一个事实

    package expert;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author  qianqianjun
     * 综合数据记录实现。
     */
    public class Fact{
        private List<String> factItemList;
        private List<String> originItemList;
        public Fact(String input,String regex){
            this.factItemList=new ArrayList<>();
            this.originItemList=new ArrayList<>();
            String[] arr=input.split(regex);
            for(Integer i=0;i<arr.length;i++){
                this.factItemList.add(arr[i]);
                this.originItemList.add(arr[i]);
            }
        }
    
        public Fact(){
            this.factItemList=new ArrayList<>();
        }
    
        public List<String> getFactItemList() {
            return factItemList;
        }
    
        public void setFactItemList(List<String> factItemList) {
            this.factItemList = factItemList;
        }
    
        public Boolean addFactItem(String result) {
            for(Integer i=0;i<this.factItemList.size();i++){
                if(this.factItemList.get(i).equals(result)){
                    return false;
                }
            }
            this.factItemList.add(result);
            return true;
        }
    
        public boolean contains(String condition) {
            for(Integer i=0;i<this.factItemList.size();i++){
                if(this.factItemList.get(i).equals(condition))
                    return true;
            }
            return false;
        }
    }
    
    
    • Regular.java

      用于描述推理规则的数据结构。

    package expert;
    
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author  qianqianjun
     * 推理规则实现。
     */
    public class Regular implements Serializable {
        private List<String> conditions;
        private String result;
        private Integer index;
        private Boolean terminal;
    
        public void setTerminal(Boolean terminal) {
            this.terminal = terminal;
        }
    
        public Integer getIndex() {
            return index;
        }
    
        public void setIndex(Integer index) {
            this.index=index;
        }
    
        public Regular(String[] arr){
            this.conditions=new ArrayList<>();
            this.setConditions(arr);
        }
        public List<String> getConditions() {
            return conditions;
        }
    
        public void setConditions(String[] arr) {
            this.conditions=new ArrayList<>();
            for(String item:arr){
                this.conditions.add(item);
            }
        }
    
        public String getResult() {
            return result;
        }
        public void setResult(String result) {
            this.result = result;
        }
        public Boolean addCondition(String condition){
            for(String elem:this.conditions){
                if(elem.equals(condition)){
                    return false;
                }
            }
            this.conditions.add(condition);
            return true;
        }
        public Boolean satisfy(List<String> factItems){
            for(String item:this.conditions){
                Boolean in=false;
                for(String other:factItems){
                    if(other.equals(item)){
                        in=true;
                        break;
                    }
                }
                if(!in){
                    return false;
                }
            }
            return true;
        }
    
        @Override
        public String toString() {
            StringBuilder sb=new StringBuilder();
            sb.append("IF \n");
            sb.append(this.conditions.get(0)+"\n");
            for(Integer i=1;i<this.conditions.size();i++){
                sb.append("AND "+this.conditions.get(i)+"\n");
            }
            sb.append("THEN "+this.result);
            if(this.index!=null){
                sb.append("\n"+index.toString());
            }
            return sb.toString();
        }
    
        public boolean equals(Regular regular) {
            for(Integer i=0;i<this.conditions.size();i++){
                Boolean flag=false;
                for(String item:regular.getConditions()){
                    if(item.equals(this.conditions.get(i))){
                        flag=true;
                        break;
                    }
                }
                if(!flag){
                    return false;
                }
            }
            if(!result.equals(regular.result)){
                return false;
            }
            return true;
        }
    
        public String conditionToString() {
            StringBuilder sb=new StringBuilder();
    
            for(Integer i=0;i<this.conditions.size()-1;i++){
                sb.append("and "+this.conditions.get(i)+"\n");
            }
            sb.append(this.conditions.get(this.conditions.size()-1));
            return sb.toString();
        }
    
        public boolean isTerminal() {
            return this.terminal;
        }
    }
    
    
    • ReasoningMachine.java

      用于实现推理机

    package expert;
    import javax.swing.*;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author  qianqianjun
     * 推理机实现。
     */
    public class ReasoningMachine {
        private Fact fact;
        private List<Regular> regulars;
        private String assume;
        private JTextArea log;
        public ReasoningMachine(Fact fact,List<Regular> regulars){
            this.fact=fact;
            this.regulars=regulars;
        }
    
        public ReasoningMachine(Fact fact,List<Regular> regulars,String condition,JTextArea console){
            this.regulars=regulars;
            this.fact=fact;
            this.assume=condition;
            this.log=console;
        }
    
    
        public Boolean isEvidence(String condition) {
            for(Integer i=0;i<this.regulars.size();i++){
                if(this.regulars.get(i).getResult().equals(condition)){
                    return false;
                }
            }
            return true;
        }
    
        public List<Regular> getPreKnowledge(String condition){
            List<Regular> arr=new ArrayList<>();
            for(Integer i=0;i<this.regulars.size();i++){
                if(this.regulars.get(i).getResult().equals(condition)){
                    arr.add(this.regulars.get(i));
                }
            }
            return arr;
        }
    
        /**
         *  正向推理:
         * @return
         */
        public String positiveReasoning(){
            StringBuilder sb=new StringBuilder("开始推理\n");
            Boolean isContinue=true;
            while(isContinue){
                isContinue=false;
                for(Integer i=0;i<this.regulars.size();i++){
                    if(this.regulars.get(i).satisfy(fact.getFactItemList())){
                        Boolean success=this.fact.addFactItem(this.regulars.get(i).getResult());
                        if(success) {
                            sb.append("匹配规则 " + this.regulars.get(i).getIndex().toString());
                            sb.append("\n添加结论 " + this.regulars.get(i).getResult());
                            sb.append("\n当前事实:");
                            for (Integer j = 0; j < this.fact.getFactItemList().size(); j++) {
                                sb.append(this.fact.getFactItemList().get(j) + " ");
                            }
                            sb.append("\n============================\n");
                            if (this.regulars.get(i).isTerminal()) {
                                sb.append("\n找到答案:" + this.regulars.get(i).getResult());
                                isContinue = false;
                                break;
                            } else {
                                isContinue = true;
                            }
                        }
                    }
                }
            }
            return sb.toString();
        }
        /**
         *  反向推理
         */
        public void reverseReasoning(){
            log.setText("");
            if(isSatisfy(assume)){
                log.append("假设成立!");
            }
            else{
                log.append("假设不成立!");
            }
        }
    
        public Boolean isSatisfy(String condition){
            if(fact.contains(condition))
                return true;
            else{
                // 判断是不是证据:
                if(isEvidence(condition)){
                    Integer type=JOptionPane.showConfirmDialog(null,"判断下面的说法: "+condition+"?","确认",
                            JOptionPane.YES_NO_OPTION);
                    if(type==0){
                        //肯定回答,说明证据满足
                        fact.addFactItem(condition);
                        log.append("\n数据库:\n");
                        for(String temp:fact.getFactItemList()){
                            log.append(temp+" ");
                        }
                        return true;
                    }
                    else{
                        // 否定回答,说明这个证据不满足,返回false;
                        return false;
                    }
                }
                else{
                    // 如果不是一个证据:
                    List<Regular> preKnowledge=getPreKnowledge(condition);
                    // 遍历所有可以导出这个条件的知识
                    for(Integer i=0;i<preKnowledge.size();i++){
                        // 对于每一个知识,查看他的所有条件是不是满足,可以设置一个标志flag
                        Boolean allSatisfy=true;
                        List<String> conditions=preKnowledge.get(i).getConditions();
                        for(Integer j=0;j<conditions.size();j++){
                            // 如果出现了一个不成立的条件,则不用继续比较了,这条知识推导不出来这个条件。
                            if(!isSatisfy(conditions.get(j))){
                                allSatisfy=false;
                                break;
                            }
                        }
                        // 如果存在一条知识,可以推导出条件,可以不用往下看其他知识了,直接返回就好。
                        if(allSatisfy){
                            fact.addFactItem(condition);
                            log.append("\n数据库:\n");
                            for(String temp:fact.getFactItemList()){
                                log.append(temp+" ");
                            }
                            return true;
                        }
                    }
                    return false;
                }
            }
        }
    }
    
    
    展开全文
  • C# winform 动物识别专家系统

    万次阅读 多人点赞 2018-06-05 12:12:41
    1、功能需求本实例完成的是人工智能作业--简单动物识别专家系统。要求能输入一个或者多个特征推理出结果,能有简单的界面,对知识库的修改等。需要的基础知识有C#,winform, 以及对文本的简单处理,数组结构用的是...

    1、功能需求

    本实例完成的是人工智能作业--简单动物识别专家系统。要求能输入一个或者多个特征推理出结果,能有简单的界面,对知识库的修改等。需要的基础知识有C#,winform, 以及对文本的简单处理,数组结构用的是数组和字典。

    2、界面设计

    程序界面有两个Form,一个是主窗口如图1,一个是修改知识库的窗口如图2,设计都非常简单,在此不用详细给出具体啦。


    图1 Main.Form


    图2 Update.Form

    3、数据准备

    因为只是个简单的案例,数据不多,因此数据采用的文本的形式如图3,每行是一条规则,中间以空格隔开,最后一个是结果。


    图3 知识库

    4、代码实现

    我的思想是,以每行数据的特征为key,结果为value,然后获取输入的特征,去遍历知识库,如果输入的特征有几个在全部在一行知识里,那么把这几个特征移除并把这行知识的value添加到输入的features中,按这个步骤,直到遍历完知识库,得到最后的结果。代码如下:

    文件读写类:FileUtil.cs

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;


    namespace WindowsFormsAppAnimalRegonize
    {
        class FileUtils
        {
            //读取文件
            public static string read_data(string data_path)
            {
                string text = null;
                //【1】创建文件流
                FileStream fs = new FileStream(data_path, FileMode.Open);
                //【2】创建读取器
                StreamReader sr = new StreamReader(fs, Encoding.Default);
                //【3】以流的方式读取数据
                text = sr.ReadToEnd();
                //【4】关闭读取器
                sr.Close();
                //【5】关闭文件流
                fs.Close();
               return text;
            }
            //写入文件
            public static void save_update(string data_path,string text)
            {
                FileStream fs = new FileStream(data_path, FileMode.Create);
                StreamWriter sw = new StreamWriter(fs, Encoding.Default);
                sw.Write(text.Trim());
                sw.Close();
                fs.Close();
            }
        }

    }

    修改知识类:FormUpdate.cs

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;


    namespace WindowsFormsAppAnimalRegonize
    {
        public partial class FormUpdate : Form
        {
            private string data_path = Environment.CurrentDirectory + "\\rule.txt";
            public FormUpdate()
            {
                Console.WriteLine(data_path);
                InitializeComponent();
                textBox_update.Text = FileUtils.read_data(data_path);
            }
            private void button_save_Click(object sender, EventArgs e)
            {
                FileUtils.save_update(data_path,textBox_update.Text);
                this.Close();
            }
        }

    }

    主类:Form1.cs

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;


    namespace WindowsFormsAppAnimalRegonize

    {

        //一行事实bean类

        class RowFact
        {
            private List<string> ls = null;
            public RowFact(List<string> ls)
            {
                this.ls = ls;
            }
            public void setLs(List<string> ls)
            {
                this.ls = ls;
            }
            public List<string> getLs()
            {
                return this.ls;
            }
        }
        public partial class Form1 : Form
        {
            private string data_path = Environment.CurrentDirectory + "\\rule.txt";


            public Form1()
            {
                InitializeComponent();
            }


            private void button_update_Click(object sender, EventArgs e)
            {
                FormUpdate formUpdate = new FormUpdate();
                formUpdate.Show();
            }
            //解析知识库
            private Dictionary<RowFact, string> parse_text(string text)
            {
                var array_facts = text.Split(Environment.NewLine.ToCharArray());
                var dic_result = new Dictionary<RowFact, string>();
                for (int i = 0; i < array_facts.Length; i++)
                {
                    var fact_items = array_facts[i].Split(" ".ToCharArray());
                    var row_fact_list = new List<string>();
                    for (int j = 0; j < fact_items.Length; j++)
                    {
                        if (j == fact_items.Length - 1)
                        {
                            var row_fact = new RowFact(row_fact_list);
                            dic_result.Add(row_fact,fact_items[j]);
                        }
                        else
                        {
                            row_fact_list.Add(fact_items[j]);
                        }
                    }
                }
                return dic_result;
            }
            //推理过程
            private void reasoning(List<string> features,Dictionary<RowFact,string> dict)
            {
                foreach (KeyValuePair<RowFact, string> pair in dict)
                {
                    if (list_contains_list( pair.Key.getLs(),features) )
                    {
                        foreach (var item in pair.Key.getLs())
                            if (features.Contains(item))
                            {
                                features.Remove(item);
                                textBox_process.AppendText(item +"->");
                            }
                        if (!features.Contains(pair.Value))
                        {
                            features.Add(pair.Value);
                            textBox_process.AppendText(pair.Value);
                            textBox_process.AppendText("\n");
                        }
                    }
                }
                var temp_item = features[features.Count - 1];
                foreach (var item in dict.Values)
                {
                    if (item == temp_item)
                    {
                        label_result.Text = item;
                        return;
                    }
                }
                label_result.Text = "推理不出来";
            }
            //规则库中的一行规则的特征是否满足输入的特征中的几条
            private bool list_contains_list(List<string> list1, List<string> list2)
            {
                bool is_contains = true;
                if (list1.Count>list2.Count)
                {
                    foreach (var item in list2)
                    {
                        if (!list1.Contains(item))
                        {
                            is_contains = false;
                            return is_contains;
                        }
                    }
                }
                else
                {
                    foreach (var item in list1)
                    {
                        if (!list2.Contains(item))
                        {
                            is_contains = false;
                            return is_contains;
                        }
                    }
                }
                return is_contains;
            }
            private void button_search_Click(object sender, EventArgs e)
            {
                var input_features = textBox_features.Text.Split(Environment.NewLine.ToCharArray());
                reasoning(input_features.ToList<string>(), parse_text(FileUtils.read_data(data_path)));
            }
        }
    }

    5、结果

    修改和推理都能正确进行。输入例子如图4,每行为一个特征。


    图4 测试结果

    展开全文
  • 动物识别专家系统(C++版)

    千次阅读 多人点赞 2018-10-09 08:12:53
    --------------------- 本文来自 Robin_just 的CSDN 博客 ,全文地址请点击:... 本实验仿照书中例题,用C++语言实现了一个简单的动物识别专家系统。该系统可以识别老虎、金钱豹、斑马、长颈鹿、鸵鸟、企鹅、信天...

    --------------------- 本文来自 Robin_just 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/shaguabufadai/article/details/71699372?utm_source=copy

    本实验仿照书中例题,用C++语言实现了一个简单的动物识别专家系统。该系统可以识别老虎、金钱豹、斑马、长颈鹿、鸵鸟、企鹅、信天翁这7种动物及根据一些特征识别部分物种。

    知识库

    在本系统当中,知识库中的知识用产生式规则来表示,共有如下15条规则。
    R1 IF该动物有奶THEN该动物是哺乳动物
    R2 IF该动物有毛发THEN该动物是哺乳动物
    R3 IF该动物有羽毛THEN该动物是鸟
    R4 IF该动物会飞AND会下蛋THEN该动物是鸟
    R5 IF该动物有爪AND有犬齿AND眼盯前方THEN该动物是食肉动物
    R6 IF该动物吃肉THEN该动物是肉食动物
    R7 IF该动物是哺乳动物AND有蹄THEN该动物是有蹄类动物
    R8 IF该动物是哺乳动物AND嚼反刍THEN该动物是有蹄类动物
    R9 IF 该动物是哺乳动物 AND 该动物是食肉动物 AND 是黄褐色 AND身上有黑色条纹 THEN 该动物是虎
    R10 IF该动物是哺乳动物 AND 该动物是食肉动物AND是黄褐色AND身上有暗斑点THEN该动物是金钱豹
    R11 IF该动物是有蹄类动物AND有长脖子AND有长腿AND身上有暗斑点THEN该动物是长颈鹿
    R12 IF该动物是有蹄类动物AND身上有黑色条纹THEN该动物是斑马
    R13 IF该动物是鸟AND有不会飞AND有长腿AND长脖子AND是黑白二色THEN该动物是鸵鸟
    R14 IF该动物是鸟AND不会飞AND会游泳AND是黑白二色THEN该动物是企鹅
    R15 IF该动物是鸟AND善飞THEN该动物是信天翁

    #include <iostream>
    #include <iomanip>
    #include <string>
    using namespace std;
    int RULENUM=15;//动物识别系统的规则库有条规则
    int CAUSENUM=5;//各条规则中的前提条件最多有个
    int count = 0;//记录所选择的动物特征的个数
    /*事实*/
    string fact[] ={ "", "有毛发", "有奶", "有羽毛", "会飞", "会下蛋", "吃肉", "有犬齿", "有爪","眼盯前方", "有蹄", "嚼反刍", "黄褐色", "身上有暗斑点", "身上有黑色条纹", "有长脖子","有长腿", "不会飞", "会游泳", "有黑白二色", "善飞", "哺乳动物", "鸟", "食肉动物", "蹄类动物", "金钱豹", "虎", "长颈鹿", "斑马", "鸵鸟", "企鹅", "信天翁" };
    /*规则*/
    int rule[][6]={{ 0, 0, 0, 0, 0, 0 },{21, 1, 0, 0, 0, 0 },{ 21, 2, 0, 0, 0, 0 }, { 22, 3, 0, 0, 0, 0 }, {22, 4, 5, 0, 0, 0 },{ 23, 6, 0, 0, 0, 0 }, { 23, 7, 8, 9, 0, 0 }, { 24, 21, 10, 0, 0, 0 }, { 24, 21, 11, 0, 0, 0 }, { 25, 21, 23, 12, 13, 0 }, { 26, 21, 23, 12, 14, 0 }, { 27, 24, 15, 16, 13, 0 }, { 28, 24, 14, 0, 0, 0 }, { 29, 22, 15, 16, 17, 19 }, { 30, 22, 18, 17, 19, 0 }, { 31, 22, 20, 0, 0, 0 } };
    
    int conditionlist[24];//所选择的动物特征
    
    bool match(int a);           //函数声明
    int inference();
    
    int main()
    {
        cout<<"以下是一些动物的特征:"<<endl;
        for (int i=1;i<=24;i++)
        {
            cout<<i<<".";
            cout<<setiosflags(ios::left)<<setw(14)<<fact[i]<<"  ";
            if (i%4==0)
            {
                cout<<endl;
            }
        }
        int a;
        int k=0;
    
         cout<<"请选择动物的特征:"<<endl;
         while((cin>>a))                      //a为整形的,按任意字母可结束循环
         {
           conditionlist[k]=a;                   
           k++;
           count++;
         }
         cout<<"该动物名称为:"<<endl;
         inference();
    
    return 0;   
    }
    
     /*知识匹配*/
    bool match(int a)
    {
        int i=1;
        int j=0;
        int flag=0;
        int flag1=0;
        int num=0;
        while ((flag==i-1)&&(flag1!=count))
        {   
            flag=0;
            for (i=1;i<=CAUSENUM;i++)
            {
                if (rule[a+num][i]==0)
                    break;                              
                for (j=0;j<count;j++)                     //所选择的动物特征的条数
                {
             if (rule[a+num][i]==conditionlist[j])//匹配上一个条件flag计数加一
                    {
                        flag++;
                        flag1++;        
                        break;
                    }
                }
            }
            num++;
        }
    
        if ((flag!=i-1)||(count==0))
        {
            return false;
        }
        else
        {   
            for (i=0;i<num;i++)
            {
                for (j=0;j<num;j++)
                {
                    if ((i!=j)&&(rule[a+i][0]!=rule[a+j][0]))
                    {
                        return false;
                    }
                }
        }
            return true;
        }
    }
    /*推理*/
    int inference()
    {
        int i;
    
        int j=0;
        for (i=1; i<=RULENUM;i++)
        {
            if (match(i)==true)
            {
                cout<<fact[rule[i][0]]<<endl;
                return 0;
            }
    
        }
        cout<<"未知动物"<<endl;
        return 0;
     }
    
    ---------------------
    
    本文来自 Robin_just 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/shaguabufadai/article/details/71699372?utm_source=copy 

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 127
精华内容 50
关键字:

动物识别专家系统