⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 animal.h

📁 动物识别的C++程序,可以选择输入动物的某些特征,程序自动识别出是什么动物类.
💻 H
字号:
/*==========================================================================
《用C++建造专家系统》书上的动物识别专家系统的程序
本人做了比较详细的注释,并对源程序略作修改。适合初学者研究!
                   QQ:185119416
CI OpenForum Group QQ:9874319
===========================================================================*/
#ifndef ANIMAL_H
#define ANIMAL_H
#define True 1
#define False 0
#define DontKnow -1

#include<stdio.h>
#include<math.h>
#include<string.h>
//事实集(概念集)
char *str[]={"",
                "chew_cud"    /*  1 */,  "hooves"           /* 2 */,   "mammal"        /* 3 */,
                "forward_eyes"/*  4 */,  "claws"            /* 5 */,   "pointed_teeth" /* 6 */,
				"eat_meat"    /*  7 */,  "lay_eggs"         /* 8 */,   "fly"           /* 9 */,
				"feathers"    /* 10 */,  "ungulate"         /* 11 */,  "carnivore"     /* 12 */,
				"bird"        /* 13 */,  "give_milk"        /* 14 */,  "has_hair"      /* 15 */,
				"fly_well"    /* 16 */,  "black&while_color"/* 17 */,  "can_swim"      /* 18 */,
				"long_legs"   /* 19 */,  "long_neck"        /* 20 */,  "black_stripes" /* 21 */,
				"dark_spots"  /* 22 */,  "tawny_color"      /* 23 */,  "albatross"     /* 24 */,
				"penguin"     /* 25 */,  "ostrich"          /* 26 */,  "zebra"         /* 27 */,
				"giraffe"     /* 28 */,	  "tiger"           /* 29 */,  "cheetah"       /* 30 */,
				"\0"};

//规则之前件(条件)集,注意与下面对应
int rulep[][6]={{22,23,12,3,0,0},  {21,23,12,3,0,0},  {22,19,20,11,0,0},
				{21,11,0,0,0,0},   {17,19,20,13,-9,0},{17,18,13,-9,0,0},
				{16,13,0,0,0,0},   {15,0,0,0,0,0},    {14,0,0,0,0,0},
				{10,0,0,0,0,0},    {8,7,0,0,0,0},     {7,0,0,0,0,0},
				{4,5,6,0,0,0},     {2,3,0,0,0,0},     {1,3,0,0,0,0}};
//规则之后件(结论)集,注意与上面对应
int rulec[]={      30,                  29,                 28,
                   27,                  26,                 25,
				   24,                  3,                  3,
				   13,                  13,                 12,
				   12,                  11,                 11};  //前7个是要识别的动物

//事实类
class fact{
	private:
		int Number;		//事实ID
		char Name[21];  //事实名
		int Active;     //激活标志
		int Succ;		//事实断言:真、假、不知道三种情况值
	public:
		fact *Next;		//事实链表后继指针
        
		/* <Function 事实类构造函数,由它激活事实对象集 />
		   <para> Num:事实ID </para>
		   <para> L:事实名   </para>
		*/
		fact(int Num,char *L)	
		{
			strcpy(Name,L);
			Number=Num;
			Active=False;		//初始不激活
			Succ=DontKnow;		//初始断言不确定
			Next=NULL;			//初始后继为空
		}
		
		char *GetName()			//获取事实名
		{
			char *L;
			L=new char[21];
			strcpy(L,Name);
			return L;
		}
		int GetNumber(){return Number;}  //获取事实ID
		int GetAct(){return Active;	}    //获取事实激活标志
		int GetSucc(){return Succ;}		 //获取事实断言值
		
		//设置事实激活标志和断言值
		void PutAct(const int Act0,int Suc0)   
		{
			 Active=Act0;
			 Succ=Suc0;
		}
};   //end fact

fact *Fact;    //事实链表

class list{    //前提(前提来源与事实集)链表类
	private:
		int Number;    //前提ID,即事实ID
	public:
		list *Next;    //前提链表后继指针
		/*<Function 前提链表类构造函数 />
		  <para> Num:事实ID  </para>
		*/
		list(int Num)
		{
			 Number=Num;
			 Next=NULL;
		}
		int GetNumber(){return Number;}   //获取前提ID(也就是事实ID)
};  //end list

class rule{   //规则类
		char *Name;		 //规则名
		list *Pre;		 //规则前件(前提、条件)链表头指针
		int Conc;        //规则后件(结论)ID(也是事实ID)
	public:
		rule *Next;      //规则链表后继指针
		rule(char *N,int P[],int C);  //规则类构造函数
		~rule();		 //析构函数
		int Query();     //推理机函数
		void GetName(){ printf("%s%",Name);}   //输出规则名
};

/*  <Function 规则类构造函数,激活规则对象集 />  
    <para>N:规则名</para>
	<para>P:规则前件数组</para>
	<para>C:规则后件ID</para>
*/
rule::rule(char *N,int P[],int C)
{
	int i;list *L;
	
	Pre=NULL;   //前提链头指针初始化
	Next=NULL;  //规则链后继指针初始化
	Name=new char[strlen(N)+1];
	strcpy(Name,N);
	i=0;
	while(P[i]!=0){   //有前提情况下
	
		L=new list(P[i++]);   //加入前提链
		L->Next=Pre;          //注意:前插入
		Pre=L;
	}
	Conc=C;      //填入规则后件(结论)
}

/*  <Function 释放规则链表节点之前提链空间 />  
    <Note  规则链本身空间为释放 />
*/
rule::~rule()
{
	list *L;
	while(Pre)
	{
		L=Pre->Next;
		delete Pre;
		Pre=L;
	}
	delete Name;
}

/*  <Function 主要实现推理机 />  
    <Return  规则使用成功与否 />
*/
int rule::Query()
{
//  int i;
  char c;        //保存用户输入按键符号
  list *L;       //临时前提链
  fact *F;       //临时事实链

  L=Pre;		 //L指向前提链
  F=Fact;
  if(L==NULL) printf("\nError!");   //如果推理时,本规则前提链为空,出错,后面while循环也退出!
  while(L!=NULL)  //前提链未处理完
  {
	 F=Fact;      //F指向事实链表
	 for(;;)      //以当前前提,在事实链表中查询(根据ID)
	 {            //因为前提为“-事实ID”,表示该事实不成立,所以取绝对值
		 if(abs(L->GetNumber())==F->GetNumber()) break;    
	      //一旦查询到,有这样的前提(不管其是否成立)则中止查询。我们的知识库必须保证一定能查许到,否则dead loop
		 F=F->Next;   //查询下一事实
	 }  //退出循环时,F指向查询到的事实节点

	 if(L->GetNumber()>0)   //如果前提为真
	 {
		 if((F->GetSucc())==True){  //而且事实链表中的这个事实断言也为真
			 L=L->Next;             //则本规则的当前前提在推理中满足
			 continue;              //继续下一前提的判断
		 }    
		 if((F->GetSucc())==False)  //Sorry,该前提在事实链表中断言不成立
			 return False;          //该规则推理使用结束,直接返回
	 }
	 else					//如果前提为假,表现为-ID
	 {
		 if((F->GetSucc())==True)	//Sorry,该前提在事实链表中断言却为真
			 return False;		    //该规则推理使用结束,直接返回
		 if((F->GetSucc())==False){ //同上类似
			 L=L->Next;
			 continue;
		 }
	 }  //end if-else
	     
     printf("%s(Y/N)",F->GetName());  //向用户提问,这里简单以事实名为问题
	 c=getchar();   //接受用户输入
     flushall();
     
	 /*注意:事实链表中节点的Succ域指:该事实的用户断言或中间推出的断言*/
	 if((c=='Y')||(c=='y'))   //回答“是”
	 {
		 if(L->GetNumber()>0) F->PutAct(1,True);  //且当前规则中的当前前提要求为“真”,置激活和“真”断言
		 if(L->GetNumber()<0){   //且若当前规则中的当前前提要求为“假”
			 F->PutAct(1,True);  //置激活和用户的断言
			 return False;       //本规则推理结束,不成功;后面的前提不判断了!
		 }
	 }
	 else
	 {  //分析同上                 
		if(L->GetNumber()<0) F->PutAct(-1,False);
		if(L->GetNumber()>0){
			 F->PutAct(-1,False);
			 return False;
		 } 
	 }

	 L=L->Next;   //用户断言和当前规则的当前前提符合,则取当前规则的下一前提进行判断!
  }   //end while

  //只要上述while循环正常退出,表明当前规则的所有前件都满足,下面要得出当前规则的推理结论了
  F=Fact;
  for(;;)
  {
	  if(Conc==F->GetNumber()) break;  //在事实表中查找与当前规则得后件相同得事实(结论性)
	  F=F->Next;
  }
  
  if(Conc<24)   //如果规则后件(结论)不是最终最终性得(即不是7种要识别得动物)
  {
	  F->PutAct(1,True);  //那就是中间事实性结论,设置其激活和中间推理确证了的断言
	  return False;       //然后返回,本规则并不能结束整个推理
  }
  //当前规则之后件是最终结论,得出要识别的动物,返回真!
  printf("\nThis annimal is %s",F->GetName());
  return True;
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -