(课程内容存档)
实验一:产生式系统——水壶问题
一、实验题目
水壶问题:
一个10升的桶里有10升水,现有3升和4升两个空桶,如何得到5升的水?
二、实验方法
产生式系统的基本结构:
工作存储器(数据集、综合数据库):直接使用当前状态
规则库(产生式规则集):建立8条规则的规则库
推理机(控制系统、解释程序):随机选择规则,并应用
搜索法:在不知道直接方法的情况下,可以采用搜索法。它是人工智能的一个框架,是智能问题求解的基础和核心。原因是:人工智能系统需要解决的问题都比较复杂,常常没有直接方法可以用。对问题进行形式化描述,便于计算机处理,描叙方法对搜索效率有很大的影响。
一般用状态空间来表示待求解的问题。
用状态空间表示法描叙问题时,要定义状态空间,表示问题的全部可能状态和相互关系。
初始状态:要定义一个或多个状态,用于描叙问题求解过程开始时的可能状态,这些状态被称为初始状态。
规则:要规定一个或一组规则,用于描叙问题从一个状态转变到另一个状态时可以采取的操作(算子operator)。
目标状态:规定一个或多个状态,用以描述问题求解过程最终应当达到的状态(即问题的解),称为目标状态;或者规定一个判断是否目标状态(解)的方法。
搜索:应用相应的规则和控制策略去遍历这个状态空间,直到找到一条从初始状态到目标状态的路径。
问题的求解过程就是一个对状态空间搜索的过程。
三、实验思路
1.定义初始状态:
定义三个变量,分别代表三个水壶h3,h4,h10,并置初始值有:h3=0,h4=0,h10=10。
2.定义规则集void Rules(),该规则集共有八条规则:
//规则 0:从 10 升桶往 4 升桶倒水,使得 4 升桶满
case 0: if (h4<4) {h10 -= 4-h4; h4=4;}break;
//规则 1:从 10 升桶往 3 升桶倒水,使得 3 升桶满
case 1: if(h3 <3) {h10-=3-h3;h3 =3;}break;
//规则 2:从 4 升桶往 10 升桶倒水,使得 4 升桶清空
case 2: if (h4>0){h10+=h4;h4=0;}break;
//规则 3:从 3 升桶往 10 升桶倒水,使得 3 升桶清空
case 3: if (h3>0){h10+=h3;h3=0;}break;
//规则 4:将 3 升桶和 4 升桶的水倒入 4 升桶,使得 4 升桶为满,3 升桶保留剩余的水
case 4: if ((h3 + h4) >=4 ){h3 = h3+h4 -4; h4=4;}break;
//规则 5:将 3 升桶和 4 升桶的水倒入 3 升桶,使得 3 升桶为满,4 升桶保留剩余的水
case 5: if ((h3 + h4) >=3 ){h4 = h3+h4 -3; h3=3;}break;
0 0 10
0 4 6
3 1 6
3 4 3 //0 1 9
3 0 7 //1 0 9
0 3 7 //1 4 5
3 3 4 //
2 4 4
2 0 8
0 2 8
//3 2 5
//规则 6:将 3 升桶和 4 升桶的水倒入 4 升桶,使得 4 升桶为满,3 升桶清空
case 6: if ((h3 + h4) <=4 ){h4=h3+h4;h3 = 0; }break;
// 规则 7:将 3 升桶和 4 升桶的水倒入 3 升桶,使得 3 升桶为满,4 升桶清空
case 7: if ((h3 + h4) <=3 ){h3 = h3+h4;h4=0;}break;
3.定义目标状态(一个冲突解决机制):
while (h10!=5)
{
Rules();
printf("RST: %d, %d, %d\n",h3,h4,h10);
}
四、实验完整代码(C语言):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// 全局变量,表示三个水桶的水量
int h3, h4, h10;
// 规则函数,根据规则编号 i 进行相应的水桶操作
void Rules(int i) {
switch (i) {
case 0:
// 规则 0:从 10 升桶往 4 升桶倒水,使得 4 升桶满
h10 -= 4 - h4;
h4 = 4;
break;
case 1:
// 规则 1:从 10 升桶往 3 升桶倒水,使得 3 升桶满
h10 -= 3 - h3;
h3 = 3;
break;
case 2:
// 规则 2:从 4 升桶往 10 升桶倒水,使得 4 升桶清空
h10 += h4;
h4 = 0;
break;
case 3:
// 规则 3:从 3 升桶往 10 升桶倒水,使得 3 升桶清空
h10 += h3;
h3 = 0;
break;
case 4:
// 规则 4:将 3 升桶和 4 升桶的水倒入 4 升桶,使得 4 升桶为满,3 升桶保留剩余的水
if ((h3 + h4) >= 4) {
h3 = h3 + h4 - 4;
h4 = 4;
}
break;
case 5:
// 规则 5:将 3 升桶和 4 升桶的水倒入 3 升桶,使得 3 升桶为满,4 升桶保留剩余的水
if ((h3 + h4) >= 3) {
h4 = h3 + h4 - 3;
h3 = 3;
}
break;
case 6:
// 规则 6:将 3 升桶和 4 升桶的水倒入 4 升桶,使得 4 升桶为满,3 升桶清空
if ((h3 + h4) <= 4) {
h4 = h3 + h4;
h3 = 0;
}
break;
case 7:
// 规则 7:将 3 升桶和 4 升桶的水倒入 3 升桶,使得 3 升桶为满,4 升桶清空
if ((h3 + h4) <= 3) {
h3 = h3 + h4;
h4 = 0;
}
break;
}
}
int main() {
// 初始化随机数生成器
srand(time(NULL));
// 初始值
h3 = 0;
h4 = 0;
h10 = 10;
// 输出初始值
printf("初始值: h3 = %d,h4 = %d,h10 = %d\n", h3, h4, h10);
// 当 h10 不等于 5
while (h10 != 5) {
// 生成随机规则编号
int i = rand() % 8;
// 调用规则函数
Rules(i);
// 输出状态更新信息
printf("状态更新: h3 = %d, h4 = %d, h10 = %d,规则: %d\n", h3, h4, h10, i);
}
// 判断最终游戏结果
if(h10 = 5){
printf("游戏结束。h10 达到5!\n");
}
return 0;
}
五、运行结果及分析(以下为部分搜索结果)

结果分析:
循环条件(h10!=5)意味着程序将一直寻找h10 = 5升水的结果
规则函数Rules()设置了8种规则,每种规则都会根据当前情况更新h3、h4和h10中所装水的数量,使得状态发生转变。
随机:用srand(time(NULL)),以便随机选取规则。
输出结果:最终h10=5,屏幕上显示了h10取到5的过程,完成题目。
六、总结
在人工智能中,产生式系统由规则库、综合数据库、推理机三部分组成,而搜索是一种重要的问题解决方法,旨在找到问题的解决方案。搜索算法通过系统地探索问题空间,从初始状态开始,逐步尝试不同的操作或状态转换,直至找到目标状态或最优解。这过程涉及状态表示、操作规则、评估函数等关键概念。
此代码模拟了一个水壶问题,使用了随机选择规则的方法进行搜索。规则函数定义了八种可能的操作,通过随机选择规则编号进行水桶的相应操作,直到其中一个水桶的水量达到5升为止。在整个搜索过程中,采用了随机性,增加了程序的灵活性和变化性。
本实验的重点是找到合适的规则集,而这主要是通过模拟状态转移的过程,进而进行归纳得到的。

被折叠的 条评论
为什么被折叠?



