Animal_match简单的动物匹配系统

全部的事实集(30个):

    "反刍","有蹄","哺乳类","眼向前方","有爪",      

    "犬齿","吃肉","下蛋","能飞","有羽毛",  
    "蹄类","食肉类","鸟类","有奶","毛发",  
    "善飞","黑色白条纹","游泳","长腿","长脖子",  
    "黑条纹","暗斑点","黄褐色"  

    "信天翁","企鹅","鸵鸟","斑马","长颈鹿","虎","豹"


所有的规则(15条):

    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 动物是信天翁 


完整代码:

#include<iostream>
using namespace std;
bool OK;
bool allzero = false;
typedef struct rule {
	int factnum;
	int fact[8];
	int matchnum;
	int result;
}start;
char *allfacts[] = { "f1:反刍","f2:有蹄","f3:哺乳类","f4:眼向前方","f5:有爪",
"f6:犬齿","f7:吃肉","f8:下蛋","f9:能飞","f10:有羽毛",
"f11:蹄类","f12:食肉类","f13:鸟类","f14:有奶","f15:毛发",
"f16:善飞","f17:黑白相间","f18:游泳","f19:长腿","f20:长脖子",
"f21:黑条纹","f22:暗斑点","f23:黄褐色" ,"f24:信天翁","f25:企鹅","f26:鸵鸟","f27:斑马",
"f28:长颈鹿","f29:虎","f30:豹" };
rule r[15] = {
	{1,{15,0,0,0,0,0,0,0},0,3},{ 1,{14,0,0,0,0,0,0,0},0,3 },{ 1,{10,0,0,0,0,0,0,0},0,13 },
    {2,{ 9,8,0,0,0,0,0,0 },0,13},{ 1,{ 7,0,0,0,0,0,0,0 },0,12 },{ 3,{ 6,5,4,0,0,0,0,0 },0,12 },
	{ 2,{ 3,2,0,0,0,0,0,0 },0,11 },{ 2,{ 3,1,0,0,0,0,0,0 },0,11 },{ 4,{ 3,12,23,22,0,0,0,0 },0,30 },
	{4,{ 3,12,23,21,0,0,0,0 },0,29},{ 4,{ 11,20,19,22,0,0,0,0 },0,28 },{ 2,{ 11,21,0,0,0,0,0,0 },0,27 },
	{ 5,{ 13,-9,20,19,17,0,0,0 },0,26 },{ 4,{ 13,-9,18,17,0,0,0,0 },0,25 },{ 2,{ 13,16,0,0,0,0,0,0 },0,24 }
};
start s;
int match(rule r[], start s,int result)
{
	int rule_num=0;
	start s2 = s;//s2用于拷贝s,以免未匹配时fact数组值被修改
	start s3 = s;//s3作为一条规则后s的更新情况
	while (rule_num < 15)
	{
		for(int i=0;i<s.factnum;i++)
			for (int j = 0; j < r[rule_num].factnum; j++)
			{
				if (s.result != 0 && s.result == r[rule_num].fact[j])
				{
					s.result = 0;
					r[rule_num].matchnum++;
					break;
				}
				if (s.fact[i] == r[rule_num].fact[j])
				{
					s.fact[i] = 0;
					r[rule_num].matchnum++;
					break;
				}
			}
		if (r[rule_num].matchnum == r[rule_num].factnum)
		{
			s.result = r[rule_num].result;
			s3 = s;
		}
		else
			s = s3;
		r[rule_num].matchnum = 0;//回归初始值
		rule_num++;
	}
	for (int m = 0; m < 8; m++)//判断此时fact数组是否为空,为空则说明匹配成功
	{
		if (s.fact[m] != 0)
		{
			allzero = false;
			break;
		}
		else
			allzero = true;
	}
	if (allzero == true)
		OK = true;
	else
		OK = false;
	result = s.result;
	return result;
}
start clean_re(start s)//去重函数
{
	for (int i = s.factnum-1; i >0; i--)
	{
		for (int j = 0; j < i; j++)
		{
			if (s.fact[i] == s.fact[j])
				s.fact[i] = 0;
			else
				continue;
		}
	}
	return s;
}
int main()
{
	bool exit_system=true;
	char exit_sign;
	for (int j = 0; j < 30; j++) //输出数据库中所有事实
		cout << allfacts[j] << endl;
	cout << "开发者:赵裴翔 201577D0556 欢迎您的使用" << endl;
	int i;
	int result=0;
	while (exit_system)
	{
		cout << "请输入现有事实的数量:";
		cin >> i;
		s.factnum = i;
		cout << "请依次输入每条事实:" << endl;
		for (int num = 0; num < 8; num++)
			if (num < i)
				cin >> s.fact[num];
			else
				s.fact[num] = 0;
		s = clean_re(s); //将现有的事实集去除重复事实
		result = match(r, s, result);//匹配算法执行,获得最终结果
		if (OK == true)
			cout << result << "  " << allfacts[result - 1] << endl << "是否退出识别系统?(Y/N):";
		else
			cout << "未找到匹配项"<<endl << "是否退出识别系统?(Y/N):";
		while (cin >> exit_sign)
		{
			if (exit_sign == 'Y')
			{
				exit_system = false;
				break;
			}
			else if (exit_sign == 'N')
			{
				exit_system = true;
				break;
			}
			if (exit_sign != 'N' || exit_sign != 'Y')
				cout << "输入错误请重新输入(Y/N):";
		}
	}
	cout << "感谢您的使用,开发者:赵裴翔" << endl;
	return 0;
}

设计的匹配原则是:将当前输入的事实集(start)中的fact数组以及非零的result结论与rule规则集的每一条规则里的fact进行比对,如果符合要求,则将start的fact数组中对应元素置0并将该条规则的matchnum加1,如此循环当matchnum与factnum相等时,即可判定匹配成功,此时将规则中的result赋给start中的result,继续进行匹配,直到与所有规则比较完毕,得到最终结论。

在整个系统运行过程中,我的匹配算法避免了输入事实的顺序问题以及解决了事实没有推理到最终结论的问题。我添加了去重函数(clean_re)解决了输入的事实重复的问题。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值