这是一个用以识别虎、金钱豹、斑马、长颈鹿、企鹅、鸵鸟、信天翁七种动物的产生式系统。为了实现对这些动物的识别,该系统建立了如下规则库:
R1: IF 该动物有毛 THEN 该动物是哺乳动物R2: IF 该动物有奶 THEN 该动物是哺乳动物R3: IF 该动物有羽毛 THEN 该动物是鸟R4: IF 该动物会飞 AND 该动物会下蛋 THEN 该动物是鸟R5: IF 该动物吃肉 THEN 该动物是食肉动物R6: IF 该动物有犬齿 AND 有爪 AND 眼盯前方 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 该动物是信天翁 最开始我就是直接通过给出的判决条件,用简单的if…else语句来实现这个推理系统,直接给出所有的判决条件,让用户输入,而用户未知的条件让用户进行否决,但是这样会带来问题,比如说会飞、会下蛋可以退出是鸟类动物,但是如果我已知是鸟类了,再去推导企鹅的过程中就会否定之前的条件,因为企鹅有一个不会飞,和之前的会飞推出的是鸟类产生冲突。所以可以先画出推理图,进行层次划分,如下图所示:
图中括号后的数字可以忽略,这个是我第一个版本的判决条件的编号。通过这个推理图,可以简单的将整个推理过程分为两大部分,其中的哺乳动物和食肉动物可以组成一个部分,鸟类单独作为一个部门,另外,值得注意的是,食肉动物不能单独推出金钱豹和虎,但是哺乳动物可推出斑马,这在这个图中容易引起读者的错误思考。
#include<stdio.h> int main() { printf("nn=====动物识别系统=====nn"); printf("判决条件:n"); printf(" 1. 有毛 2.有奶 3.有羽毛 4.会飞 5.会下蛋 6.眼盯前方n"); printf(" 7. 有蹄 8.反刍动物 9.吃肉 10.有犬齿 11.有爪 n"); printf("12.长脖子 13.长腿 14.暗斑点 15.有黑色条纹n"); printf("16.黄褐色 17.不会飞 18.黑白二色 19.会游泳 20.善飞n"); printf("n请输入已知条件序号(如2,输入999结束。):n"); const int num = 20; //条件个数 int inputs[num] = { 0 }; int i = 0; while (i < num) { int temp; scanf_s("%d", &temp); if (temp == 999) break; if (temp < 1 || temp >20) { printf("序号有误,请重新输入: n"); continue; } inputs[i] = temp; i++; } int sign[num] = { 0 }; //标志每一个条件(有就标志为1,没有就标志为0) int bf[num] = { 0 }; //用于备份 int j = 0; while (inputs[j] != 0) { sign[inputs[j] - 1] = 1; bf[inputs[j] - 1] = 1; j++; } if (sign[0] || sign[1]) { // 满足哺乳动物条件 if (bf[0]) { printf("n使用规则:有毛--->哺乳动物n"); } else { printf("n使用规则:有奶--->哺乳动物n"); } sign[0] = 0, sign[1] = 0; //printf("=====该动物是哺乳动物=====nn"); if (sign[6] || sign[7]) { // 满足有蹄类动物条件 if (bf[6]) { printf("n使用规则:哺乳动物+有蹄--->有蹄类动物n"); } else { printf("n使用规则:哺乳动物+反刍动物--->有蹄类动物n"); } sign[6] = 0, sign[7] = 0; //printf("=====该动物是有蹄类动物=====nn"); if (sign[11] && sign[12] && sign[13]) { sign[11] = sign[12] = sign[13] = 0; printf("n使用规则:有蹄类动物+有长脖子+有长腿+有暗斑点--->长颈鹿n"); printf("nn======该动物是长颈鹿======nn"); } else if(sign[14]){ sign[14] = 0; printf("n使用规则:有蹄类动物+有黑色条纹--->斑马n"); printf("nn======该动物是斑马======nn"); } else { printf("nn======无法具体判断=====nn"); } } else if (sign[8] || (sign[5] && sign[9] && sign[10])) { if (sign[8]) { printf("n使用规则:吃肉--->食肉动物n"); } else { printf("n使用规则:有犬齿+有爪+眼盯前方--->食肉动物n"); } sign[8] = sign[5] = sign[9] = sign[10] = 0; // 满足食肉动物条件 //printf("=====该动物是食肉动物=====nn"); if (sign[13] && sign[15]) { sign[13] = sign[15] = 0; printf("n使用规则:食肉动物+哺乳动物+黄褐色+有暗斑点--->金钱豹n"); printf("nn======该动物是金钱豹======nn"); } else if (sign[14] && sign[15]) { sign[14] = sign[15] = 0; printf("n使用规则:食肉动物+哺乳动物+黄褐色+黑色条纹--->虎n"); printf("nn======该动物是虎======nn"); } } else { printf("nn======无法具体判断=====nn"); } } else if (sign[2] || (sign[3] && sign[4])) { // 满足鸟类条件 if (sign[2]) { printf("n使用规则:有羽毛--->鸟类n"); } else { printf("n使用规则:会飞+会下蛋--->鸟类n"); } sign[2] = 0, sign[3] = 0, sign[4] = 0; //printf("nn=====该动物是鸟类=====nn"); if (sign[11] && sign[12] && sign[16] && sign[17]) { sign[11] = sign[12] = sign[16] = sign[17] = 0; printf("n使用规则:鸟类+有长脖子+有长腿+不会飞+有黑白二色--->鸵鸟n"); printf("nn======该动物是鸵鸟======nn"); } else if (sign[16] && sign[17] && sign[18]) { sign[16] = sign[17] = sign[18] = 0; printf("n使用规则:鸟类+会游泳+不会飞+有黑白二色--->企鹅n"); printf("nn======该动物是企鹅======nn"); } else if (sign[19]) { sign[19] = 0; printf("n使用规则:鸟类+善飞--->信天翁n"); printf("nn======该动物是信天翁======nn"); } else { printf("nn======无法具体判断=====nn"); } } else { printf("nn======无法具体判断=====nn"); } int xx = 0; //标记 for (int i = 0; i < num; i++) { if (sign[i]) { printf("nn推理最可能动物时,存在多余条件, 序号是 %dn",i+1); xx = 1; } } if (xx == 1) printf("nn=======以上推理失效=======n"); }
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132代码中的bf数组,是用于存放用户输入条件的备份数组,因为原始的数组在后期一旦经过判断,就将这个条件置0,也就是不能再使用了,另外最后一个标记循环,只能说是在已经进入第二层或者第三层 的情况下,给出了多余的条件,这个循环才会生效,不然测试一种失败条件时很可能所有的条件都会直接给出。
通过本次对动物识别系统的规则库的实现,对产生式系统的机制如推理方式等等有了一个基本的了解和认识。在对程序的改进过程中,弥补了最开始逻辑的漏洞,以及最开始仅仅是根据题目直接用if…else语句进行推导,到后来做出推理图,才真正对题目有了较为深刻的理解,对用户暂时还没有输入的条件进行全盘否定的做法进行了改正,并且在最后将具体的推理过程展现给用户。这不仅是对上课所学的内容有了基本巩固,同时,对此类题目出现的逻辑思维和程序设计思想也有了进一步的提升。这是一个简单的if…else语句实现,读者可以根据自己的需要进行修改。
相关知识
动物识别系统的规则库
毕业设计:基于深度学习的动物叫声识别系统
基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的鸟类识别系统(Python+PySide6界面+训练代码)
鸟类(动物)监控与生物多样化智能识别系统
鸟类声纹识别系统如何定制?-澳盾
基于深度学习的犬种识别系统详解(网页版+YOLOv8/v7/v6/v5代码+训练数据集)
雀巢中国布局宠物处方粮和湿粮;新瑞鹏上线AI鼻纹识别系统
基于深度学习的鸟类识别系统(网页版+YOLOv8/v7/v6/v5代码+训练数据集)
天信互通
狗狗库欣综合征能活多久(狗狗得了库欣综合征症状不治的结果)
网址: 动物识别系统的规则库 https://m.mcbbbk.com/newsview203405.html
上一篇: 养犬管理条例 |
下一篇: 《育儿宝典:如何为孩子建立坚实的 |