应用数据库函数约束化简解决动物识别系统问题(产生式系统)

来源:互联网 发布:乐视视频 mac版本 编辑:程序博客网 时间:2024/05/16 06:07

1.产生式系统介绍

总数据库
           存放求解过程中各种当前信息的数据结构
产生式规则
           规则库,存放与求解问题有关的某个领域知识的规则之集合及其交换规则
控制策略
           推理机构,控制产生式系统的运行,决定问题求解过程的推理线路

 

2.动物识别系统属性选择

   编号依次为(0~31)
   毛发   产乳   羽毛   飞行    产蛋     吃肉
   爪子   利齿   前视    蹄       反刍     黄褐色
   深色斑点      黑色条纹       长腿     长颈   白色    不会飞         黑白相杂       游水     善飞
   鸟类动物      哺乳动物      食肉动物   
    有蹄动物      猎豹     老虎   长颈鹿     斑马      鸵鸟    企鹅     海燕

3.规则建立

0->22              1->22              2->21
3+4->21          22+5->23       22+6+7+8->23
22+9->24        22+10->24     23+11+12->25
23+11+13->26     
24+14+15+11+12->27
24+16+13->28
21+17+15+14+18->29
21+17+19+18->30
21+20->31  

属性及规则划分

L类(只出现在产生式左边且可推出中间属性的属性)
LR类(在产生式左右两边都出现且是过渡的属性)
R类(只在产生式右边出现的且是目标的属性)

                    属性                                                                   规则

L类            0,1,2,3,4                                        0->22  1->22   2->21  3+4->21
LR类         23,24                                                       22+5->23  22+9->24  22+6+7+8->23   22+10->24
R类          25,26,27,28,29,30,31               23+11+12->25   23+11+13->26   24+14+15+11+12->27  24+16+13->28  21+17+15+14+18->29  21+17+18+19->30

 

 

4.算法描述

第一步:依据L类属性及其规则第一次扩充输入属性集合
第二步:依据LR类属性及其规则第二次扩充属性集合
第三步:依据R类规则及上述属性集合求出R类集合,若R类集合为空,则不能识别动物,
                若有唯一值,则可以唯一确定动物,
                若有多个值,则结论冲突,输入非法

5.算法实现

数据结构:
输入属性集合 get[24],其长度为length
目标事实个数:targetNum
目标事实确认集合:target1[7]
产生式规则,二维数组produce[15][6]

 

6.程序结构

reshape()刷新屏幕
getPro()输入属性编号
new1Num()第一次扩充
new2Num()第二次扩充
Search()查找目标
output()输出结论

 

7.源代码(完整)

 

//简单动物识别系统源代码实现  人工智能及其应用 研究生用书 2.7节例题

//语言:C,行界面形式
//日期:2011.10.29
//作者:唐裕凤 E201102057

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//事实编号数据,最多为24个
int get[24]={-1};

int length=0;//get数组长度

int targetNum=0;//目标事实个数

//动物目标编号
int target[7]={25,26,27,28,29,30,31};

//动物是否被确认
int target1[7]={0};

//产生式规则,用二维数组表示
int produce[15][6]={0,-1,-1,-1,-1,22,1,-1,-1,-1,-1,22,2,-1,-1,-1,-1,21,3,4,-1,-1,-1,21,22,5,-1,-1,-1,23,22,6,7,8,-1,23,22,9,-1,-1,-1,24,22,10,-1,-1,-1,24,23,11,12,-1,-1,25,
23,11,13,-1,-1,26,24,14,15,11,12,27,24,16,13,-1,-1,28,21,17,15,14,18,29,21,17,19,18,-1,30,21,20,-1,-1,-1,31};

void reshape(void)//刷新全局变量函数
{
 int i=0;
 for(i=0;i<24;i++)
   get[i]=-1;
  length=0;
  for(i=0;i<7;i++)
   target1[i]=0;
  targetNum=0;
}

void init1(void)//显示事实列表
{
 printf("/********************************************************************/\n");
 printf("/*                          动物识别系统                             /\n");
 printf("/*    姓名:唐裕凤       学号:E201102057    专业:计算机应用技术   */\n");
 printf("/********************************************************************/\n");
 printf("\n\n\n以下是可供选择的动武属性:\n");
 printf("0  毛发      1  产乳      2  羽毛      3  飞行      4  产蛋      5  吃肉\n");
 printf("6  爪子      7  利齿      8  前视      9  蹄        10 反刍      11 黄褐色\n");
 printf("12 深色斑点  13 黑色条纹  14 长腿      15 长颈      16 白色      17 不会飞\n");
 printf("18 黑白相杂  19 游水      20 善飞      21 鸟类动物  22 哺乳动物  23 食肉动物\n");
 printf("24 有蹄动物\n");
}

void init2(void)//可以得出的动物名称
{
 printf("\n\n\n下面是可以得出的动物名称:\n");
 printf("25  猎豹      26  老虎      27  长颈鹿      28  斑马\n");
 printf("29  鸵鸟      30  企鹅      31  海燕\n");
}

void output()//输出所有的产生式
{
 int i=0,j=0,k=0;
 printf("\n\n\n下面是15条产生式规则\n\n");
 for(i=0;i<15;i++)
 {
  for(j=0;j<5;j++)
   if(produce[i][j]==-1)
    break;
   else
   {
    printf("%d",produce[i][j]);
    k=j+1;
    if(produce[i][k]!=-1&&k!=5)
     printf("+");
   }
  printf("->%d\n",produce[i][5]);
 }
}

//输入事实编号数据,以-1结束,最多为24个
void getPro()
{
 printf("\n\n\n请输入选择的条件,以-1结束");
 int temp,i=0;
 do
 {
  scanf("%d",&temp);
  if(temp<-1||temp>24)
  {
   printf("\n该输入非法,请重新输入\n");
   continue;
  }
  get[i++]=temp;
 }while(temp!=-1);
 length=i;
}

void outputGet()
{
 for(int i=0;i<length-1;i++)
  printf("%d\t",get[i]);
 printf("\n");
}

//计算事实个数,即get数组个数
void Length(int get[])
{
 int i=0;
 while(get[i]!=-1)
 {
  i++;
 }
 length=i;
}

//是否用到规则0
int find0(void)
{
 int i=0;
 for(;i<length;i++)
  if(get[i]==0) return 1;
 return 0;
}

//是否用到规则1
int find1(void)
{
 int i=0;
 for(;i<length;i++)
  if(get[i]==1) return 1;
 return 0;
}

//是否用到规则2
int find2(void)
{
 int i=0;
 for(;i<length;i++)
  if(get[i]==2) return 1;
 return 0;
}

//是否用到规则3
int find3(void)

 int i=0,flag1=0,flag2=0;
 for(;i<length;i++)
  if(get[i]==3) flag1=1;
  else if(get[i]==4) flag2=1;
 if(flag1&&flag2)  return 1;
 else
  return 0;
}

//更新后的事实数组
void new1Num(void)
{
 int m=length;
 if(find0()||find1())
 {
  get[m]=22;
  m++;
 }

 if(find2()||find3())
 {
  get[m]=21;
  m++;
 }
 
 length=m;
}

//利用中间规则推导出中间数据

//是否用到规则4
int find4(void)
{
 int i=0,flag1=0,flag2=0;
 for(;i<length;i++)
  if(get[i]==5) flag1=1;
  else if(get[i]==22) flag2=1;
 if(flag1&&flag2) return 1;
 else
  return 0;
}

//是否用到规则5
int find5(void)
{
 int i=0,flag1=0,flag2=0,flag3=0,flag4=0;
 for(;i<length;i++)
  switch(get[i])
 {
  case 6:flag1=1;break;
  case 7:flag2=1;break;
  case 8:flag3=1;break;
  case 22:flag4=1;break;
  default:break;
 }

 if(flag1&&flag2&&flag3&&flag4) return 1;
 else
  return 0;
}

//是否用到规则6
int find6(void)
{
 int i=0,flag1=0,flag2=0;
 for(;i<length;i++)
  if(get[i]==9) flag1=1;
  else if(get[i]==22) flag2=1;
 if(flag1&&flag2) return 1;
 else return 0;
}

//是否用到规则7
int find7(void)
{
 int i=0,flag1=0,flag2=0;
 for(;i<length;i++)
  if(get[i]==10) flag1=1;
  else if(get[i]==22) flag2=1;
 if(flag1&&flag2) return 1;
 else return 0;
}

//第二次更新事实数组get[]
void new2Num(void)
{
 int m=length;
 if(find4()||find5())
 {
  get[m]=23;
  m++;
 }

 if(find6()||find7())
 {
  get[m]=21;
  m++;
 }
 length=m;
}

//利用所有的事实数据判断最终的结论

//判断是否是猎豹25
int IsLieBao(void)
{
 int i=0,flag1=0,flag2=0,flag3=0;
 for(;i<length;i++)
  if(get[i]==11) flag1=1;
  else if(get[i]==12) flag2=1;
  else if(get[i]==23) flag3=1;
 if(flag1&&flag2&&flag3)
  return 1;
 else
  return 0;
}

//判断是否是老虎
int IsLaoHu(void)
{
 int i=0,flag1=0,flag2=0,flag3=0;
 for(;i<length;i++)
  if(get[i]==11) flag1=1;
  else if(get[i]==13) flag2=1;
  else if(get[i]==23) flag3=1;
 if(flag1&&flag2&&flag3)
  return 1;
 else
  return 0;
}

//判断是否是长颈鹿
int IsChangJiuLu(void)
{
 int i=0,flag1=0,flag2=0,flag3=0,flag4=0,flag5=0;
 for(;i<length;i++)
  if(get[i]==11) flag1=1;
  else if(get[i]==12) flag2=1;
  else if(get[i]==14) flag3=1;
  else if(get[i]==15) flag4=1;
  else if(get[i]==24) flag5=1;
 if(flag1&&flag2&&flag3&&flag4&&flag5)
  return 1;
 else
  return 0;
}

//判断是否是斑马
int IsBanMa(void)
{
 int i=0,flag1=0,flag2=0,flag3=0;
 for(;i<length;i++)
  if(get[i]==13) flag1=1;
  else if(get[i]==16) flag2=1;
  else if(get[i]==24) flag3=1;
 if(flag1&&flag2&&flag3)
  return 1;
 else
  return 0;
}

//判断是否是鸵鸟
int IsTuoNiao(void)
{
 int i=0,flag1=0,flag2=0,flag3=0,flag4=0,flag5=0;
 for(;i<length;i++)
  if(get[i]==14) flag1=1;
  else if(get[i]==15) flag2=1;
  else if(get[i]==17) flag3=1;
  else if(get[i]==18) flag4=1;
  else if(get[i]==21) flag5=1;
 if(flag1&&flag2&&flag3&&flag4&&flag5)
  return 1;
 else
  return 0;
}

//判断是否是企鹅
int IsQiE(void)
{
 int i=0,flag1=0,flag2=0,flag3=0,flag4=0;
 for(;i<length;i++)
  if(get[i]==17) flag1=1;
  else if(get[i]==18) flag2=1;
  else if(get[i]==19) flag3=1;
  else if(get[i]==21) flag4=1;
 if(flag1&&flag2&&flag3&&flag4)
  return 1;
 else
  return 0;
}

//判断是否是海燕
int IsHaiYan(void)
{
 int i=0,flag1=0,flag2=0;
 for(;i<length;i++)
  if(get[i]==20) flag1=1;
  else if(get[i]==21) flag2=1;
 if(flag1&&flag2)
  return 1;
 else
  return 0;
}

//搜索过程,根据输入事实,利用前项推导结论
void Search(void)
{
 if(IsLieBao()) target1[0]=1;
 if(IsLaoHu()) target1[1]=1;
 if(IsChangJiuLu()) target1[2]=1;
 if(IsBanMa()) target1[3]=1;
 if(IsTuoNiao()) target1[4]=1;
 if(IsQiE()) target1[5]=1;
 if(IsHaiYan()) target1[6]=1;
}

//输出结论
void output2(void)
{
 int i=0;
 for(i=0;i<7;i++)
  if(target1[i]==1) targetNum++;
 printf("\n\n\n");
    switch(targetNum)
 {
 case 0:printf("不能判断动物的名称\n");break;
    case 1:
  {
   printf("可以唯一确定动物的类型\n");
   for(i=0;i<7;i++)
    if(target1[i]==1)
     switch(i)
    {
                 case 0:printf("该动物是猎豹\n");break;
     case 1:printf("该动物是老虎\n");break;
     case 2:printf("该动物是长颈鹿\n");break;
     case 3:printf("该动物是斑马\n");break;
     case 4:printf("该动物是鸵鸟\n");break;
     case 5:printf("该动物是企鹅\n");break;
     case 6:printf("该动物是海燕\n");break;
     default:break;
    }

   break;
  }
 case 2:
 case 3:
 case 4:
 case 5:
 case 6:
 case 7:printf("得出的是冲突的结论\n");break;
 default:
  break;
 }
}

void main(void)
{
 char ch;
 init1();
 init2();
 output();
 do{
  reshape();
  getPro();
  printf("当前输入的事实数据:\n");
  outputGet();
  new1Num();
  printf("事实数据第一次扩充后的结果:\n");
  outputGet();
  new2Num();
  printf("事实数据第二次扩充后的结果:\n");
  outputGet();
  Search();
  output2();
  printf("\n\n是否继续,请输入Y or N\n");
  ch=getchar();//此句为接收换行的字符
  ch=getchar();
 }while(ch=='Y'||ch=='y');
}

 


 

原创粉丝点击