这次的人工智能实验是产生式系统——动物分类

规则:R1:动物有毛→ 哺乳类

     R2:动物产奶 → 哺乳类

     R3:动物有羽毛 → 鸟类

     R4:动物会飞 ∧会下蛋 → 鸟类

     R5:哺乳类∧动物吃肉→ 食肉类

     R6:动物有犬齿 ∧有爪 ∧眼盯前方→肉食类

     R7:哺乳类 ∧有蹄 →蹄类动物

     R8:哺乳类 ∧反刍 → 蹄类

     R9:食肉类 ∧ 黄褐色 ∧ 有斑点→ 金钱豹

     R10:食肉类 ∧ 黄褐色 ∧ 有黑色条纹→虎

     R11:蹄类 ∧ 长脖 ∧ 长腿 ∧ 有斑点→ 长颈鹿

     R12:蹄类 ∧  有黑色条纹→ 斑马

     R13:鸟类 ∧长脖 ∧ 长腿 ∧ 不会飞 →鸵鸟

     R14:鸟类 ∧会游泳 ∧黑白二色 ∧ 不会飞 →企鹅

     R15:鸟类 ∧善飞 →信天翁


这是给定的规则库,通过这个规则库,以及用户输入的已知条件,来判断所描述的动物。

产生式系统的问题求解过程即为对解空间的搜索过程,也就是推理过程。按照搜索的方向可把产生式系统分为正向推理、逆向推理和双向推理

正向推理:从一组表示事实的谓词或命题出发,使用一组产生式规则,用以证明该谓词公式或命题是否成立。

逆向推理:从表示目标的谓词或命题出发,使用一组产生式规则证明事实谓词或命题成立,即首先提出一批假设目标,然后逐一验证这些假设。

双向推理:双向推理的推理策略是同时从目标向事实推理和从事实向目标推理,并在推理过程中的某个步骤,实现事实与目标的匹配。

这里,我们采用双向推理。通俗来说,双向推理就是先采用正向推理,如果已经是无法进行下去的情况,采用逆向推理,这个时候就需要询问用户是否能观察到某

些逆向推理出来的特征,然后讲这些特征加入到已知的条件特征中,再次进行正向推理,如此反复,知道得到最后的结果。需要注意的是,上面给定的规则库中的

名词可以分为三类:1.已知类,即用户能实际观察到的动物特征,这些只会出现在每个条件的前半段;2.概念类,即对动物进行的抽象的概念概括,也算是推理的

中间产物,会出现在条件的前端或后端;3.结果类,即最后推理出来的结果,真实的动物,只会出现在条件的后端。

有了这些概念之后,下面就是具体的推理过程了,我所采用的方式是读取规则库txt文件,将所有名词编号,然后用编号来组织成一条条件,遍历这些条件,根据

用户给出的名词,进行比较,同时计算每个条件的符合程度,推理出的名词加入到已知的名词队列中,重新遍历条件,更新符合度,如果没有100%符合的条件,则

寻找符合度最高的条件,进行逆向推理,询问可能的且没有在已知名词队列中的名词,进行判断,加入名词队列,重新遍历,更新符合度,直至找到属于结果类的

名词,即是结果。

代码中,只要是按照这种格式编写的规则的txt文件,都可以进行推理,实现了更便捷的应用。

下面是实现代码:

首先是主处理流程类,Project:

import java.util.ArrayList;
import java.util.Scanner;/*** 主函数,处理* @author 41571**/public class Project {public static ArrayList<Condition> word = new ArrayList<Condition>();    //存放所有的词汇,用下标来编号public static ArrayList<Sentence> sentenceList = new ArrayList<Sentence>();  //存放句子private ArrayList<Condition> now = new ArrayList<Condition>();    //存放用户输入的条件public static ArrayList<Integer> know = new ArrayList<Integer>();public static void main(String args[]){new Project();}public Project(){new ReadFile();System.out.println("请输入你已知的信息(空格间隔):");Scanner in = new Scanner(System.in);dealKnow(in.nextLine());/*    for(int i = 0;i < word.size();i ++){System.out.print(i+": ");word.get(i).show();}*/domain();}private void dealKnow(String nextLine) {    //处理输入的已知信息// TODO Auto-generated method stubchar[] temp = nextLine.toCharArray();int a = temp.length -1 ;for(int i = temp.length - 1;i >= 0;i --){if(temp[i] == ' '){toString(temp,i+1,a);a = i -1;}if(i == 0){toString(temp,0,a);}}addKnow();}private void toString(char[] temp, int j, int i) {   //转化为字符串,开始位置,结束位置// TODO Auto-generated method stubString str = "";for(int m = j;m <= i;m ++){str = str+temp[m];}now.add(new Condition(str));}private void addKnow() {// TODO Auto-generated method stubfor(int i = 0;i < now.size();i ++){know.add(find(now.get(i).getStr()));}//sortKnow();}/*private void sortKnow(){int a;for(int i = 0;i < know.size();i ++){for(int j = i+1;j < know.size();j ++){if(know.get(i) > know.get(j)){a = know.get(j);know.set(j, know.get(i));know.set(i, a);}}}}*/private int find(String str) {// TODO Auto-generated method stubfor(int i = 0;i < Project.word.size();i ++){if(str.equals(Project.word.get(i).getStr())){return i;}}return -1;}public void domain(){       //主进程int a,z = 0;boolean out = true;while(out){a = 0;z = 0;for(int i = 0;i < sentenceList.size();i ++){if(sentenceList.get(i).isLook()){     //isLook==true时,表示这个还没有完全匹配sentenceList.get(i).compare();if(sentenceList.get(i).getMay() == 1.0){know.add(sentenceList.get(i).getResult());sentenceList.get(i).setLook(false);       //不再遍历sentenceList.get(i).setNeglect(false);    //忽视这个语句a = 1;z = 1;if(word.get(sentenceList.get(i).getResult()).isBaceOK()){System.out.println("你所描述的对象是"+word.get(sentenceList.get(i).getResult()).getStr()+"。");out = false;break;}}}}/*for(int i = 0;i < sentenceList.size();i ++){if(!sentenceList.get(i).isNeed()){sentenceList.get(i).setNeglect(false);}}*/if(a == 0){/*for(int i = 0;i < know.size();i ++){System.out.println(word.get(know.get(i)).getStr());}*/float max = 0;int tag = 0;  //找出最有可能的句子,询问用户for(int i = 0;i < sentenceList.size();i ++){if(sentenceList.get(i).isLook()&&sentenceList.get(i).isNeglect()&&sentenceList.get(i).isNeed()){//isLook == true时,说明当前语句没有完全匹配,isNeglect == true 说明这个句子在询问查询时不能忽略sentenceList.get(i).compare();if(sentenceList.get(i).getMay()>max){max = sentenceList.get(i).getMay();tag = i;}}}for(int k = 0;k < sentenceList.get(tag).getNotExist().length;k ++){if(word.get(sentenceList.get(tag).getNotExist()[k]).isFrontOK()){System.out.println("请问你是否发现该对象有 “"+word.get(sentenceList.get(tag).getNotExist()[k]).getStr()+"” 特征吗?(是的回答“y”,否或不知道回答“n”)");Scanner in = new Scanner(System.in);String input = in.nextLine();char[] inputs = input.toCharArray();z = 1;if(inputs[0] == 'y'){know.add(sentenceList.get(tag).getNotExist()[k]);break;}else{sentenceList.get(tag).setNeglect(false);  //忽略这个句子break;}}else{sentenceList.get(tag).setNeglect(false);}}}if(z == 0){System.out.println("抱歉!系统暂时未包含该对象!");out = false;}/*if(a == 0){        //如果没有匹配的了,就要询问用户可能的情况了int m = 0;while(m == 0){for(int j = 0;j < sentenceList.size();j ++){if(sentenceList.get(j).isLook()){if(sentenceList.get(j).getNotExist()!=null)for(int k = 0;k < sentenceList.get(j).getNotExist().length;k ++){if(word.get(sentenceList.get(j).getNotExist()[k]).getBack()&&  //即出现在前端又word.get(sentenceList.get(j).getNotExist()[k]).getFront());        //出现在后端else{System.out.println("请问你是否发现该对象有 “"+word.get(sentenceList.get(j).getNotExist()[k]).getStr()+"” 特征吗?(是的回答“y”,否回答“n”)");Scanner in = new Scanner(System.in);String input = in.nextLine();char[] inputs = input.toCharArray();if(inputs[0] == 'y'){know.add(sentenceList.get(j).getNotExist()[k]);m = 1;}else{if(k+1==sentenceList.get(j).getNotExist().length){sentenceList.get(j).setNeglect(false);break;}}}}}}}}*/}}
}

接下来是条件句子类Sentence:


/*** 经过处理的一个句子* 包括条件* 还有结果* @author 41571**/public class Sentence {private int[] begin;private int result;private int[] notExist;private float may;private boolean isLook = true;       //是否完全匹配private boolean neglect = true; //询问用户时是否忽略public boolean isNeglect() {return neglect;}public void setNeglect(boolean neglect) {this.neglect = neglect;}public Sentence(){}public boolean isLook() {return isLook;}public void setLook(boolean isLook) {this.isLook = isLook;}public void compare(){int[] temp = new int[10];int a,m = 0;for(int i = 0;i < begin.length;i ++){a = 0;for(int j = 0;j < Project.know.size();j ++){if(Project.know.get(j) == begin[i]){a = 0;break;}a = 1;}if(a == 1){temp[m++] = begin[i];}}notExist = new int[m];for(int i = 0;i < m;i ++){notExist[i] = temp[i];}may = ((float)(begin.length-notExist.length))/begin.length;}public int[] getNotExist() {return notExist;}public void setNotExist(int[] notExist) {this.notExist = notExist;}public float getMay() {return may;}public int[] getBegin() {return begin;}public void setBegin(int[] begin) {this.begin = sort(begin);}private int[] sort(int[] begin) {// TODO Auto-generated method stubint a;for(int i = 0;i < begin.length;i ++){for(int j = i+1;j < begin.length;j ++){if(begin[i] > begin[j]){a = begin[j];begin[j] = begin[i];begin[i] = a;}}}return begin;}public int getResult() {return result;}public void setResult(int result) {this.result = result;}public boolean isNeed() {// TODO Auto-generated method stubfor(int i = 0;i < Project.know.size();i ++){if(this.result == Project.know.get(i)){return false;}}return true;}
}

名词条件类Condition:

/*** 名词条件类,属性包括两个boolean型变量* @author 41571**/public class Condition {private String str;private boolean front;  //是前端的private boolean back; //是后端的//如果既是前端的,也是后端的,那就是中间属性public Condition(String str){this.str = str;}public String getStr(){return this.str;}public void setFront(boolean front){this.front = front;}public void setBack(boolean back){this.back = back;}public boolean getFront(){return this.front;}public void show(){System.out.println("字符串:"+this.str+" Front:"+this.front+" Back:"+this.back);}public boolean getBack(){return this.back;}public boolean isFrontOK(){      //是否是前端if(this.front&&!this.back){return true;}return false;}public boolean isBaceOK(){     //是否是后端if(!this.front&&this.back){return true;}return false;}
}

最后是读取文件及加工的类ReadFile:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Scanner;
import java.io.OutputStreamWriter;/*** 读取文件类,将文件内容加工成* @author 41571**/public class ReadFile {private final String filePath = "file\\knowledge.txt";private ArrayList<String> content = new ArrayList<String>(); //存放读取到的所有数据//public ArrayList<String> word = new ArrayList<String>();  //存放所有的词汇,用下标来编号public ReadFile(){getData();}private void getData() {// TODO Auto-generated method stub/*try{        //写入文件File file = new File(filePath);OutputStreamWriter write = new OutputStreamWriter(new FileOutputStream(file),"gbk");BufferedWriter writer = new BufferedWriter(write);writer.write(content);writer.close();}catch(Exception e){e.printStackTrace();}*/try{     //读取文件File file = new File(filePath);if(file.isFile()&&file.exists()){InputStreamReader read = new InputStreamReader(new FileInputStream(file),"gbk");BufferedReader reader = new BufferedReader(read);String line;while((line = reader.readLine())!=null){content.add(line);}read.close();}}catch(Exception e){e.printStackTrace();}collectWord(); //收集所有关键词collectSentence(); //收集所有的句子}private void collectSentence() {// TODO Auto-generated method stubfor(int i = 0;i < content.size();i ++){char[] temp = content.get(i).toCharArray();for(int j = (temp.length-1);j > 0;j --){if(temp[j] == '>'){String str = toString(temp,j+1,temp.length-1);Sentence sen = new Sentence();sen.setResult(find(str));setBegin(temp,j,sen);}}}}private void setBegin(char[] temp, int j, Sentence sen) {// TODO Auto-generated method stubint a = j-1;int[] test = new int[10];int total = 0;int[] begin;for(int i = j-1;i >= 0;i --){if(temp[i] == '^'){String str = toString(temp,i+1,a); //数组,开始位置,结束位置test[total++] = find(str);a = i-1;}if(i == 0){String str = toString(temp,0,a);test[total++] = find(str);}}begin = new int[total];for(int i = 0;i < total;i ++){begin[i] = test[i];}sen.setBegin(begin);Project.sentenceList.add(sen);/*  for(int i = 0;i < sen.getBegin().length;i ++){System.out.print(sen.getBegin()[i]+" ");}System.out.println("result:"+sen.getResult());*/}private int find(String str) {// TODO Auto-generated method stubfor(int i = 0;i < Project.word.size();i ++){if(str.equals(Project.word.get(i).getStr())){return i;}}return 0;}private void collectWord() {// TODO Auto-generated method stubfor(int i = 0;i < content.size();i ++){char[] temp = content.get(i).toCharArray();for(int j = (temp.length-1);j > 0;j --){if(temp[j] == '>'){String str = toString(temp,j+1,temp.length-1);addStr(str,1,1);      //position = 1表示后条件,a = 1 表示在后面遇到precondition(temp,j);   //前提}}}}private void precondition(char[] temp, int j) {// TODO Auto-generated method stubint a = j-1;for(int i = j-1;i >= 0;i --){if(temp[i] == '^'){String str = toString(temp,i+1,a);  //数组,开始位置,结束位置addStr(str,-1,-1);  //position = -1表示前条件,a = -1 表示在前面遇到a = i-1;}if(i == 0){String str = toString(temp,0,a);addStr(str,-1,-1);}}}private void addStr(String str,int position,int a) {// TODO Auto-generated method stubboolean is = true;for(int i = 0;i < Project.word.size();i ++){if(str.equals(Project.word.get(i).getStr())){is = false;Project.word.get(i).setFront(true);}}if(is){Condition con = new Condition(str);if(position == 1){con.setBack(true);}else if(position == -1){con.setFront(true);}Project.word.add(con);}}private String toString(char[] temp, int j, int i) {// TODO Auto-generated method stubString str = "";for(int m = j;m <= i;m ++){str = str+temp[m];}return str;}
}

人工智能之产生式系统相关推荐

  1. 人工智能 - 球星产生式系统

    什么是产生式 产生式 一组产生式,互相配合/协调,其中一个产生式产生的结论可以作为另一个产生式的事实使用,以求解问题. 产生式系统基本结构 如下图为产生式系统的基本结构 规则库 用于描述相应领域内过程 ...

  2. 人工智能作业之产生式推理系统

    Title:已知有规则: if 动物有毛发 then 动物是哺乳动物 if 动物有奶 then 动物是哺乳动物 if 动物有羽毛 then 动物是鸟 if 动物会飞 and 会生蛋 then 动物是鸟 ...

  3. 广州大学人工智能原理实验三:产生式系统推理

    相关资料 广州大学人工智能原理实验一:知识的表示与推理实验 广州大学人工智能原理实验二:八数码问题 广州大学人工智能原理实验三:产生式系统推理 广州大学人工智能原理实验四:TSP问题的遗传算法实现 广 ...

  4. 人工智能原理复习 | 产生式系统

    文章目录 一.概述 二.八数码问题 三.特殊的产生式系统 四.一些补充 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 通过学习人工智能原理课程了解基本的人工智能问 ...

  5. 吉林大学-研究生课程-人工智能基础-基础、产生式系统

    写在前面: 第一章基础部分考的很细,ppt里的都容易考,但分值少.第二章没什么可注意的. 20世纪图灵奖获得者中的人工智能学者: Marvin Minsky马文·明斯基(1969年), 美国知识的框架 ...

  6. 人工智能基础---上机2:产生式系统

    文章目录 一.题目 二.实验过程 三.完整代码 四.结果展示 一.题目 建造用以识别虎.金钱豹.斑马.长颈鹿.企鹅.鸵鸟和信天翁 7 种动物的产生式实验系统(包括规则库和事实库),然后实现推理过程.即 ...

  7. 人工智能原理复习 | 可分解产生式系统的搜索策略

    文章目录 一.前言 二.基础知识 三.AO* 算法 四.博弈树搜索 五.总结 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 主要内容: 与 / {/} /或图搜索 ...

  8. 人工智能--野人过河

    课程简介 人工智能(Artificial Intelligence),英文缩写为AI.它是研究.开发用于模拟.延伸和扩展人的智能的理论.方法.技术及应用系统的一门新的技术科学.人工智能的定义可以分为两 ...

  9. 本科-人工智能模拟卷

    人工智能模拟卷 一.选择题 1 . 1997 年 5 月,著名的"人机大战",最终计算机以 3.5 比 2.5 的总比分将世界国际象棋棋王卡斯帕罗夫击败,这台计算机被称为(  A  ...

  10. 本科-人工智能复习题

    填空题 首次提出"人工智能"是在(1956)年 . 下列不属于人工智能的研究方法的是(动作模拟法). (语义网络法)是知识的一种结构化图解表示,它由节点和弧线或链线组成,能把实体的 ...

最新文章

  1. 图解用Scientific Toolworks Understand分析Microsoft DirectX SDK (June 2010)自带D3D示例
  2. Android targetSdkVersion详解
  3. 【转】误差矩阵(混淆矩阵)评价法
  4. Android官方开发文档Training系列课程中文版:目录
  5. C#LeetCode刷题之#203-删除链表中的节点(Remove Linked List Elements)
  6. 微软希望通过监控开发者结束软件 bug
  7. xampp 2016支持php7.0,xampp 装php7
  8. Linux C/C++实现时间戳转换工具
  9. 计算机文化与计算机技术有什么区别,什么是计算机文化?
  10. 手把手教你实现基于eTS的分布式计算器
  11. testerhome学习笔记3_Bash应用一
  12. Django快速上手
  13. 你有你的计划,世界另有计划这本书 万维钢
  14. 【01】 Nastran 生成adams接口模态中性文件(mnf文件)
  15. SpringBoot 整合ElasticSearch全文检索
  16. MathType在word中的安装使用方法(要配合microsoft公式3.0才能使用)(ps:弄得不好可能造成word中Ctrl+V失灵)
  17. 如何将视频中的某一段截取制作gif动图
  18. 如何阅读一本书——“功利性”阅读法
  19. IT行业岗位分析丨我们要不要学习Linux?
  20. 邮件(mail)服务器

热门文章

  1. 【数据可视化】免费开源BI工具DataEase实现了SQL数据集和Excel数据集关联?(什么?快别挡着我,冲!)
  2. win10 linux 无法下载,更新win10后不能安装ubuntu的解决方法
  3. HTML5期末大作业:直播网站设计——仿在线媒体歪秀直播官网模板html源码(11个页面) HTML+CSS+JavaScript 期末作业HTML代码...
  4. 需求分析岗的一点总结
  5. websockets 和 socketio 的比较
  6. 打砖块 如何实现三个球 java_小球弹砖块游戏(JAVA)
  7. hivesql:行列转换
  8. Intellij IDEA免费版方法(1)
  9. PHP - 主流开发框架 - 介绍
  10. sql列转行逗号连接_SQL 拼接字符串 列转行 | 学步园