基于回溯推理的小型专家系统.docx

上传人:b****0 文档编号:10114890 上传时间:2023-05-23 格式:DOCX 页数:25 大小:308.10KB
下载 相关 举报
基于回溯推理的小型专家系统.docx_第1页
第1页 / 共25页
基于回溯推理的小型专家系统.docx_第2页
第2页 / 共25页
基于回溯推理的小型专家系统.docx_第3页
第3页 / 共25页
基于回溯推理的小型专家系统.docx_第4页
第4页 / 共25页
基于回溯推理的小型专家系统.docx_第5页
第5页 / 共25页
基于回溯推理的小型专家系统.docx_第6页
第6页 / 共25页
基于回溯推理的小型专家系统.docx_第7页
第7页 / 共25页
基于回溯推理的小型专家系统.docx_第8页
第8页 / 共25页
基于回溯推理的小型专家系统.docx_第9页
第9页 / 共25页
基于回溯推理的小型专家系统.docx_第10页
第10页 / 共25页
基于回溯推理的小型专家系统.docx_第11页
第11页 / 共25页
基于回溯推理的小型专家系统.docx_第12页
第12页 / 共25页
基于回溯推理的小型专家系统.docx_第13页
第13页 / 共25页
基于回溯推理的小型专家系统.docx_第14页
第14页 / 共25页
基于回溯推理的小型专家系统.docx_第15页
第15页 / 共25页
基于回溯推理的小型专家系统.docx_第16页
第16页 / 共25页
基于回溯推理的小型专家系统.docx_第17页
第17页 / 共25页
基于回溯推理的小型专家系统.docx_第18页
第18页 / 共25页
基于回溯推理的小型专家系统.docx_第19页
第19页 / 共25页
基于回溯推理的小型专家系统.docx_第20页
第20页 / 共25页
亲,该文档总共25页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

基于回溯推理的小型专家系统.docx

《基于回溯推理的小型专家系统.docx》由会员分享,可在线阅读,更多相关《基于回溯推理的小型专家系统.docx(25页珍藏版)》请在冰点文库上搜索。

基于回溯推理的小型专家系统.docx

基于回溯推理的小型专家系统

《基于回溯推理的小型专家系统》

实验报告

 

 

2011年11月25日

目录

一、实验题目3

二、实验目的3

三、实验要求6

四、实验步骤6

基本设计思路8

流程框图10

数据测试12

五、实验方案设计实现16

六、实验程序使用说明17

八、实验心得体会17

九、源程序清单22

一、实验要求

利用产生式规则构建一个简单的专家系统

a)题目自拟(手机选择、电脑选择、玉石选择……)

b)要求:

1、确定推理方法(正向还是反向),并根据问题设计实现一个简单的不通用推理机(匹配、冲突消解)

2、规则库要求至少包含15条规则

3、初始事实可以任意给定,输入初始事实后能够得到推理结果

4、设计人机界面,解释模块提供查询规则的功能

5、可以不考虑知识库管理模块

6、提交实验报告,实验名称为:

基于回溯推理的小型专家系统

7、报告中要有推理树

二、实验目的

通过编写设计专家推理系统,加深对产生式表示的理解。

三、实验步骤

基本设计思路

步1将初始事实置入动态数据库;

步2用动态数据库中的事实,匹配目标条件,若目标条件满足,则推理成功,结束。

步3用待测试规则集中各规则的前件匹配动态数据库中的事实,将匹配成功的规则组成冲突集;

步4若冲突集为空,则运行失败,退出。

步5对冲突集做冲突消解,对选择执行的各规则,将其结论加入动态数据库,或执行其动作,转步2。

 

流程框图

 

数据测试

//Unicode编码_测试数据_规则集.txt

它种子的胚有两个子叶∨它的叶脉为网状=它是双子叶植物

它种子的胚有一个子叶=它是单子叶植物

它的叶脉平行=它是单子叶植物

(它是双子叶植物∧它的花托呈杯形)∨(它是双子叶植物∧它的花为两性∧它的花瓣有5枚)=它是蔷薇科植物

它是蔷薇科植物∧它的果实为核果=它是李亚科植物

它是蔷薇科植物∧它的果实为梨果=它是苹果亚科植物

它是李亚科植物∧它的果皮有毛=它是桃

它是李亚科植物∧它的果皮光滑=它是李

它的果实为扁圆形∧它的果实外有纵沟=它是桃

它是苹果亚科植物∧它的果实里无石细胞=它是苹果

它是苹果亚科植物∧它的果实里有石细胞=它是梨

它的果肉为乳黄色∧它的果肉质脆=它是苹果

 

//Unicode编码_测试数据_初始事实.txt

它种子的胚有两个子叶

它的果肉为乳黄色

它的果实里无石细胞

它的果实为梨果

它的果实无毛

它的花托呈杯形

四、实验方案设计实现

由于规则集和初始事实集可能非常大,所以这里采用读入文件的方法。

为了支持中文,这里采用了Unicode编码,文本文件保存时,必须选择以Unicode的形式保存,否则会出现乱码。

对文本进行解剖的过程比较麻烦,主要是因为Unicode文本中含有很多不可视的控制字符,两个字符串,看上去一模一样,但进行比对操作后并不相等,就是因为这些不可视的控制字符导致的。

所以对文本进行解剖的过程中,必须多加注意对不可视控制字符的过滤。

为了让用户能看清整个推理过程,设了一个“推理下一步”的按钮,让用户一步步执行。

比较棘手的是前提是否成立的验证过程,运算符有∧)∨(,还要考虑运算符优先级问题。

这里模仿了利用栈进行四则运算的过程。

使用两个栈,一个保存运算符,一个保存操作数。

在表达式最后面加一个”#”作为结束符,不断提取前提中的下一个元素,当为操作数时,进操作数栈。

当为运算符时,对比它和运算符栈里最后一个运算符的优先级,如果栈中的那个优先级低,直接进栈。

否则要以栈中那个运算符为运算符,操作数栈最后两个为操作数,进行一次运算。

结果为真时,用字符串”@true”表示,结果为假时,用”@false”表示。

当匹配成功,把结论增加到事实集中,把该规则从“待测试规则”转移到“匹配规则集”列表中。

为了画面简洁,这里用规则号表示规则,用户如果要查看详细规则的说明,点击“查看规则”,就会弹出一个新的对话框。

在MFC中,我们用一个类对表示这个对话框,当用户点击按钮时,我们将其实例化,并调用ShowWindows。

为了从父对话框更新子对话框的控件,子对话框的类中,设计了专门的接口。

enumMATCH_RESULT

{

MATCH_RESULT_SUCCESSED,

MATCH_RESULT_FAILED,

};

enumOPERATOR_CMP_RESULT

{

OPERATOR_CMP_LESS,

OPERATOR_CMP_EQUAL,

OPERATOR_CMP_GREATER,

};

CStringOpenAndReadFile(CString&str);

voidPrintStr(vector&vec,HWNDwnd,INTitemId);

voidPrintInt(vector&vec,HWNDwnd,INTitemId);

voidSeperateRule(constCString&rule,CString&left,CString&right);

MATCH_RESULTMatch(CStringpre,vector&truths);

OPERATOR_CMP_RESULTOperatorCmp(CStringa,CStringb);

CStringCalcute(CStringa,CStringoper,CStringb,vector&truths);

voidNextElement(CString&res,CString&str);

boolIsOperator(WCHARoper);

boolFind(vector&vec,CStringv);

voidNextLine(CString&res,CString&str);

boolIsEmptyWChar(WCHARch);

voidinit();

voidUpdateAllLists();

afx_msgvoidOnBnClickedChooseRule();

afx_msgvoidOnBnClickedCheckRule();

afx_msgvoidOnBnClickedChooseTruth();

afx_msgvoidOnBnClickedStart();

voidUpdateTotalRules(vectorvec);

 

五、实验程序使用说明

启动程序

选择规则集

规则集载入成功

选择初始事实集

初始事实集载入成功

查看规则集详细描述

不断按“推理下一步”,得到最后结果

 

六、实验心得体会

通过这次实验,加深了对正向推理的理解。

 正向推理又称为正向链接推理,其推理基础是逻辑演绎的推理链,它从一组表示事实的谓词或命题出发,使用一组推理规则,来证明目标谓词公式或命题是否成立。

  实现正向推理的一般策略是:

先提供一批数据(事实)到总数据库中,系统利用这些事实与规则的前提匹配,触发匹配成功的规则(即启用规则),把其结论作为新的事实添加到总数据库中。

继续上述过程,用更新过的总数据库中的所有事实再与规则库中另一条规则匹配,用其结论再修改总数据库的内容,直到没有可匹配的新规则,不再有新的事实加到总数据库为止。

 

同时加强了对MFC和Unicode的实践。

七、源程序清单

enumMATCH_RESULT

{

MATCH_RESULT_SUCCESSED,

MATCH_RESULT_FAILED,

};

enumOPERATOR_CMP_RESULT

{

OPERATOR_CMP_LESS,

OPERATOR_CMP_EQUAL,

OPERATOR_CMP_GREATER,

};

 

//打开文件,并返回其内容

CStringOpenAndReadFile(CString&str)

{

CFileDialogfd(TRUE,NULL,NULL,NULL,L"所有文件(*.*)|*.*");;

if(fd.DoModal()==IDOK)

{

CFilef;

f.Open(fd.GetPathName(),CFile:

:

modeRead|CFile:

:

modeNoTruncate);

intlen=f.GetLength()/sizeof(TCHAR);

TCHAR*buf=newTCHAR[len+5];

f.Read(buf,f.GetLength());

buf[len]=L'\0';

str=CString(buf);

delete[]buf;

}

returnfd.GetPathName();

}

 

//把CString列表打印到对应的控件上

voidPrintStr(vector&vec,HWNDwnd,INTitemId)

{

CStringstr;

for(inti=0;i

str=str+vec[i]+L"\r\n";

SetDlgItemText(wnd,itemId,str);

}

 

//把Int列表打印到对应的控件上

voidPrintInt(vector&vec,HWNDwnd,INTitemId)

{

CStringstr;

for(inti=0;i

{

CStringtmp;

tmp.Format(L"%d\r\n",vec[i]);

str=str+tmp;

}

SetDlgItemText(wnd,itemId,str);

}

 

//把规则根据等号分成左右两部分

voidSeperateRule(constCString&rule,CString&left,CString&right)

{

intp=rule.Find(L'=');

left=rule.Mid(0,p);

right=rule.Mid(p+1,rule.GetLength());

}

 

//通过两个栈来实验运算,看规则前提是否成立

MATCH_RESULTMatch(CStringpre,vector&truths)

{

pre=pre+L"#";

stackoperatorStack;

stackoperandStack;

operatorStack.push(L"#");

CStringnext;

NextElement(next,pre);

while(next!

=L"#"||operatorStack.top()!

=L"#")

{

if(!

IsOperator(next[0]))

{

operandStack.push(next);

NextElement(next,pre);

}

else

switch(OperatorCmp(operatorStack.top(),next))

{

caseOPERATOR_CMP_LESS:

operatorStack.push(next);

NextElement(next,pre);

break;

caseOPERATOR_CMP_EQUAL:

operatorStack.pop();

NextElement(next,pre);

break;

caseOPERATOR_CMP_GREATER:

{

CStringb=operandStack.top();

operandStack.pop();

CStringa=operandStack.top();

operandStack.pop();

CStringoper=operatorStack.top();

operatorStack.pop();

operandStack.push(Calcute(a,oper,b,truths));

break;

}

default:

break;

}

}

if(operandStack.top()==L"@true")

returnMATCH_RESULT_SUCCESSED;

else

returnMATCH_RESULT_FAILED;

}

 

//对比运算符的优先级别

OPERATOR_CMP_RESULTOperatorCmp(CStringa,CStringb)

{

if((a==L"∨"||a==L"∧")&&(b==L"∨"||b==L"∧"||b==L"#"||b==L")"))

returnOPERATOR_CMP_GREATER;

elseif(a==L"("&&b==L")"||a==L"#"&&b==L"#")

returnOPERATOR_CMP_EQUAL;

else

returnOPERATOR_CMP_LESS;

}

//进行逻辑运算

CStringCalcute(CStringa,CStringoper,CStringb,vector&truths)

{

if(oper==L"∧")

return((a==L"@true"||Find(truths,a))&&

(b==L"@true"||Find(truths,b)))?

L"@true":

L"@false";

elseif(oper==L"∨")

return((a==L"@true"||Find(truths,a))||

(b==L"@true"||Find(truths,b)))?

L"@true":

L"@false";

}

 

//在前提中提取下一个元素

voidNextElement(CString&res,CString&str)

{

inti=0;

while(!

IsOperator(str[i]))

i++;

if(i==0)

{

res=str.Mid(0,1);

str=str.Mid

(1);

}

else

{

res=str.Mid(0,i);

str=str.Mid(i);

}

}

 

//检测这字符是否为运算符

boolIsOperator(WCHARoper)

{

returnoper==L'('||oper==L')'||oper==L'∧'||oper==L'∨'||oper==L'='||oper==L'#';

}

 

//在vector中查找v是否存在

boolFind(vector&vec,CStringv)

{

for(inti=0;i

{

intt1=vec[i].GetLength();

intt2=v.GetLength();

if(vec[i].Compare(v)==0)

returntrue;

}

returnfalse;

}

 

//检测字符是否为不可见字符

boolIsEmptyWChar(WCHARch)

{

returnch==L'\r'||ch==L'\n'||ch==L'\0'||ch==0xEF||ch==0xBB||ch==0xBF||ch==65279;

}

 

//在res中提取下一行

voidNextLine(CString&res,CString&str)

{

intt=str.GetLength();

inta=0;

while(IsEmptyWChar(str[a]))

a++;

intb=a+1;

while(!

IsEmptyWChar(str[b]))

b++;

res=str.Mid(a,b-a);

str=str.Mid(b+1);

}

 

//初始化

voidCReasoningDlg:

:

init()

{

mTotalRules.clear();

mCurRules.clear();

mTruths.clear();

mConficts.clear();

}

//选择规则集

voidCReasoningDlg:

:

OnBnClickedChooseRule()

{

init();

CStringstr,path,line;

path=OpenAndReadFile(str);

SetDlgItemText(IDC_RULE_PATH,path);

while(true)

{

if(str.GetLength()<3)

break;

NextLine(line,str);

mTotalRules.push_back(line);

mCurRules.push_back(mTotalRules.size()-1);

}

PrintInt(mCurRules,m_hWnd,IDC_RULE_LIST);

}

 

//查看规则集

voidCReasoningDlg:

:

OnBnClickedCheckRule()

{

CCheckDialog*dlg=newCCheckDialog();

dlg->Create(MAKEINTRESOURCE(IDD_CHECK_DIALOG));

dlg->UpdateTotalRules(mTotalRules);

dlg->ShowWindow(SW_NORMAL);

}

 

//选择事实集

voidCReasoningDlg:

:

OnBnClickedChooseTruth()

{

mTruths.clear();

CStringstr,path,line;

path=OpenAndReadFile(str);

SetDlgItemText(IDC_TRUTH_PATH,path);

while(true)

{

if(str.GetLength()<3)

break;

NextLine(line,str);

mTruths.push_back(line);

}

PrintStr(mTruths,m_hWnd,IDC_TRUTH_LIST);

}

 

//下一步推理

voidCReasoningDlg:

:

OnBnClickedStart()

{

for(vector:

:

iteratoriter=mCurRules.begin();iter!

=mCurRules.end();iter++)

{

CStringleft,right;

SeperateRule(mTotalRules[*iter],left,right);

intresult=Match(left,mTruths);

switch(result)

{

caseMATCH_RESULT_SUCCESSED:

mConficts.push_back(*iter);

mTruths.push_back(right);

mCurRules.erase(iter);

break;

caseMATCH_RESULT_FAILED:

break;

default:

break;

}

if(result==MATCH_RESULT_SUCCESSED)

break;

}

UpdateAllLists();

}

 

//更新所有列表

voidCReasoningDlg:

:

UpdateAllLists()

{

PrintInt(mCurRules,m_hWnd,IDC_RULE_LIST);

PrintStr(mTruths,m_hWnd,IDC_TRUTH_LIST);

PrintInt(mConficts,m_hWnd,IDC_CONFICT_LIST);

}

 

//子对话框更新接口

voidCCheckDialog:

:

UpdateTotalRules(vectorvec)

{

CStringnum;

for(inti=0;i

{

num.Format(L"R%d:

",i);

vec[i]=num+vec[i];

}

PrintStr(vec,m_hWnd,IDC_TOTAL_RULE);

}

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 工程科技 > 电力水利

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2