1、中南民族大学人工智能导论实验报告院 系: 计算机科学学院 专 业: xxx 年 级: xxx级 课程名称: 人工智能导论 学 号: xxx 姓 名: xxx 指导教师: 2013年 12月1 日年级 xxx级 xxx学号 xxx专业 xxx姓名 xxx实验名称水壶问题实验类型设计型综合型创新型实验目的或要求给定 A,B两个个水壶,一个最终状态 C ,其中水壶A的容量为V_A, 水壶B的容量为 V_B,求是否可以通过水壶A和B,使得最终A或B中水的体积为C实验原理(算法流程)约定有 6 中操作,并分别记为操作号1,2, 3, 4, 5, 61. FILL(A) 将A壶装满2. FILL(B) 将
2、B壶装满3. Empty(A) 将A壶中的水倒空4. Empty(B) 将B壶中的水倒空5. Pour(A, B) 将水从A壶倒到B壶6. Pour(B, A) 将水从B壶倒到A壶A, B壶的初始状态为空,显然这是一颗六叉树,并且这不是一颗完整的六叉树,因为有一些节点并不符合,对于不合法的节点,将它剪掉(剪枝操作)广度优先搜索(BFS):(1) 将首节点(0,0)入队(2) 队列不为空循环2.1 队首节点出队,判断A,B壶中是否至少有一个达到C状态2.2 对于6种操作,每个父节点产生6个新的节点,将合法的节点入队,不和法的节点剪掉 (3) 如果有可行解,打印可行解组内分工(可选) 实验结果分析
3、及心得体会运行结果截图:成绩评定教师签名: 2013年 月 日备注:源代码附后,源代码要求有注释说明代码:#include #include #include #include #include #define M 1000int visM+5M+5;int aNum, bNum, cNum;struct Node /* 状态节点 */ int x; int y; int step;struct parent /* 记忆表 */ int px; int py;prevM+5M+5;void dfs(int x, int y) if (prevxy.px+prevxy.py != 0) dfs(
4、prevxy.px, prevxy.py); /* End of If */ int prex = prevxy.px; int prey = prevxy.py; /* Fill(A) */ if (prex!=aNum & x=aNum & y=prey) printf(Fill(A)n); return ; /* Fill(B) */ if (prey!=bNum & y=bNum & x=prex) printf(Fill(B)n); return ; /* Empty(A) */ if (prex!=0 & x=0 & y=prey) printf(Empty(A)n); retur
5、n ; /* Empty(B) */ if (prey!=0 & y=0 & x=prex) printf(Empty(B)n); return ; /* Pour(A,B) or Pour(B,A) */ if (prex+prey = x+y) /* 倒水前后总水量不变 */ if (x=0 | y=bNum) printf(Pour(A, B)n); else printf(Pour(B, A)n); return ; /* dfs */void BFS() int IsSolve = 0; /* 问题求解标志,初始时问题未被求解 */ int rear = -1; /* 队列尾指针 *
6、/ int front = -1; /* 队首指针 */ Node cur, next; Node queueM+10=0; cur.x = 0; /* 当前水壶 A 状态 */ cur.y = 0; /* 当前水壶 B 状态 */ cur.step = 0; /* 记录当前步数 */ queue+rear = cur; /* 初始状态入队 */ vis00 = 1; /* 初始状态设为已被访问 */ while (front != rear) /* 队列不为空时循环 */ cur = queue+front; if (cur.x=cNum | cur.y=cNum) IsSolve = 1;
7、 printf(Total Step : %dn, cur.step); dfs(cur.x, cur.y); /* dfs 回溯打印可行方案 */ break; /* End of If */ /* operation step add one */ next.step = cur.step + 1; /* OP 1: Fill(A) */ next.x = aNum; next.y = cur.y; if (!visnext.xnext.y) visnext.xnext.y = 1; prevnext.xnext.y.px = cur.x; /* 记忆表的实现 */ prevnext.xn
8、ext.y.py = cur.y; queue+rear = next; /* OP 2: Fill(B) */ next.x = cur.x; next.y = bNum; if (!visnext.xnext.y) visnext.xnext.y = 1; prevnext.xnext.y.px = cur.x; prevnext.xnext.y.py = cur.y; queue+rear = next; /* OP 3: Empty(A) */ next.x = 0; next.y = cur.y; if (!visnext.xnext.y) visnext.xnext.y = 1;
9、prevnext.xnext.y.px = cur.x; prevnext.xnext.y.py = cur.y; queue+rear = next; /* OP 4: Empty(B) */ next.x = cur.x; next.y = 0; if (!visnext.xnext.y) visnext.xnext.y = 1; prevnext.xnext.y.px = cur.x; prevnext.xnext.y.py = cur.y; queue+rear = next; /* OP 5: Pour(A, B) */ next.y = (cur.x+cur.y)bNum ? (c
10、ur.x+cur.y) : bNum; next.x = cur.x - (next.y - cur.y); if (!visnext.xnext.y) visnext.xnext.y = 1; prevnext.xnext.y.px = cur.x; prevnext.xnext.y.py = cur.y; queue+rear = next; /* OP 6: Pour(B, A) */ next.x = (cur.x+cur.y)aNum ? (cur.x+cur.y) : aNum; next.y = cur.y - (next.x - cur.x); if (!visnext.xne
11、xt.y) visnext.xnext.y = 1; prevnext.xnext.y.px = cur.x; prevnext.xnext.y.py = cur.y; queue+rear = next; /* End of While */ if (!IsSolve) printf(No Solution.n); /* BFS */int main() while (scanf(%d %d %d, &aNum, &bNum, &cNum) /* Reset the array */ memset(vis, 0, sizeof(vis); memset(prev, 0, sizeof(pre
12、v); BFS(); /* 利用广度优先搜索找出所有可能解 */ /* End of While */ return 0;年级 xxx级 xxx学号 xxx专业 xxx姓名 xxx实验名称传教士过河问题实验类型设计型综合型创新型实验目的或要求有N个传教士,M个野人,现在有一条可以载K个人的船(KN),要求在任何时刻,河的两岸以及船上的野人树不多于传教士人数,否则传教 士就会被野人吃掉,要求求出可行的运输方案实验原理(算法流程)约定 0 表示船在左岸,1 表示船在右岸,初始状态为野人,船和传教士都在左岸,那么可以构造一颗广度优先树,野人,船和传教士的状态就是相对应的一个节点,显然有些节点是不符合
13、的,同样也需要剪枝,具体的方法是根据船的位置,对左岸或右岸进行广度优先搜索 广度优先搜索:(1) 初始节点入队(2) 队列不为空循环1 队首节点出队,判断是否已经到达目的状态2 根据船的位置对左岸或右岸进行枚举,检查枚举过程的节点是否合法,如果合法则入队,否则剪掉 (3) 输出可行的方案数组内分工(可选) 实验结果分析及心得体会结果截图:成绩评定教师签名: 2013年 月 日备注:源代码附后,源代码要求有注释说明源代码:#include #include #include #include #define N 1000#define M 1000/#define localjudgeint h
14、ashN+5M+52;/* hash判重 */ int nNum, mNum, kNum; /* N 个传教士,M 个野人,船一次能载 K 人 */ struct Node int leftMiss; /* 左岸的传教士人数 */ int leftSava; /* 左岸的野人数 */ int step; /* 记录移动步数 */ int boat; /* 表示船的位置,0代表左岸,1代表右岸 */ queueN*M+5;struct parent int px; int py; int boat;prevN+5M+52; /* 记录移动路径 */int IsLegal(int leftMiss
15、, int leftSava, int boatMiss, int boatSava, int rightMiss, int rightSava) if (leftMiss0 | leftSavanNum | leftSavamNum) return 0; if (rightMiss0 | rightSavanNum | rightSavamNum) return 0; if (leftMiss & leftMissleftSava) | (boatMiss & boatMissboatSava) | (rightMiss & rightMissrightSava) return 0; ret
16、urn 1;/* IsInBound */void dfs(int leftMiss, int leftSava, int boat) if (prevleftMissleftSavaboat.px != nNum & prevleftMissleftSavaboat.py != mNum & prevleftMissleftSavaboat.boat) dfs(prevleftMissleftSavaboat.px, prevleftMissleftSavaboat.py, prevleftMissleftSavaboat.boat); /* End of If */ printf(%d %
17、d | %d %dn, leftMiss, leftSava, nNum-leftMiss, mNum-leftSava); return ;/* dfs */void bfs() int IsSolve = 0; /* 描述问题求解的状态 */ int rear = -1; int front = -1; int i, j, rightMiss, rightSava; struct Node cur = 0, next = 0; cur.leftMiss = nNum; /* 左岸传教士初始为 N 人 */ cur.leftSava = mNum; /* 左岸野人初始为 M 人 */ cur
18、.step = cur.boat = 0; /* 初始移动步数为 0,船在左岸 */ queue+rear = cur; /* 初始状态入队 */ hashcur.leftMisscur.leftSavacur.boat = 1; /* 初始状态设为已被访问 */ while (front rear) cur = queue+front; /* 获得队首状态节点 */ if (cur.leftMiss=0 & cur.leftSava=0 & cur.boat=1) IsSolve = 1; /* 问题已被求解 */ printf(Step : %dn, cur.step); /printf(
19、%d %d | 0 0n, nNum, mNum); /dfs(cur.leftMiss, cur.leftSava, cur.boat); break; /* End of If */ rightMiss = nNum - cur.leftMiss; rightSava = mNum - cur.leftSava; if (cur.boat = 0) /* 船在左岸 */ for (i=0; i=cur.leftMiss & i=kNum; +i) for (j=0; j=cur.leftSava & i+j=kNum; +j) if (i+j = 0) continue; next.lef
20、tMiss = cur.leftMiss - i; /* 左岸教士减少 i 人*/ next.leftSava = cur.leftSava - j; /* 左岸野人减少 j 人 */ next.boat = 1 - cur.boat; /* 改变船的状态 */ if (!hashnext.leftMissnext.leftSavanext.boat & IsLegal(next.leftMiss, next.leftSava, i, j, rightMiss+i, rightSava+j) /* 移动步数增加一 */ next.step = cur.step + 1; /* 设为已被访问 *
21、/ hashnext.leftMissnext.leftSavanext.boat = 1; /* 记录父节点左岸教士数 */ prevnext.leftMissnext.leftSavanext.boat.px = cur.leftMiss; /* 记录父节点左岸野人数 */ prevnext.leftMissnext.leftSavanext.boat.py = cur.leftSava; /* 记录父节点船的状态 */ prevnext.leftMissnext.leftSavanext.boat.boat = cur.boat; queue+rear = next; /* 当前可行的运
22、输方案入队 */ /* End of for */ /* End of For */ /* End of If */ else /* 船在右岸 */ for (i=0; i=rightMiss & i=kNum; +i) for (j=0; j=rightSava & i+j=kNum; +j) if (i+j = 0) continue; next.leftMiss = cur.leftMiss + i; /* 左岸教士增加 i 人 */ next.leftSava = cur.leftSava + j; /* 左岸野人增加 j 人 */ next.boat = 1 - cur.boat;
23、/* 改变船的状态 */ if (!hashnext.leftMissnext.leftSavanext.boat & IsLegal(next.leftMiss, next.leftSava, i, j, rightMiss-i, rightSava-j) /* 移动步数增加一 */ next.step = cur.step + 1; /* 设为已被访问 */ hashnext.leftMissnext.leftSavanext.boat = 1; /* 记录父节点左岸教士数 */ prevnext.leftMissnext.leftSavanext.boat.px = cur.leftMi
24、ss; /* 记录父节点左岸野人数 */ prevnext.leftMissnext.leftSavanext.boat.py = cur.leftSava; /* 记录父节点船的状态 */ prevnext.leftMissnext.leftSavanext.boat.boat = cur.boat; queue+rear = next; /* 当前可行的运输方案入队 */ /* End of for */ /* End of For */ /* End of Else */ /* End of While */ if (!IsSolve) printf(No Solution.n); /*
25、 bfs */int main()#ifdef localjudge freopen(E:Miss_Sava.txt, r, stdin); freopen(E:Miss_Sava(result).txt, w, stdout);#endif while (scanf(%d %d %d, &nNum, &mNum, &kNum) /* Empty the array */ memset(hash, 0, sizeof(hash); memset(prev, 0, sizeof(prev); memset(queue, 0, sizeof(queue); bfs(); /* End of Whi
26、le */ return 0;年级 xxx级 xxx 学号 xxx专业 xxx姓名 xxx实验名称演化算法实验类型设计型综合型创新型实验目的或要求给定方程 y=10*sin(5*x)+7*cos(4*x) ,求方程在 1, 20 的最大值,以及取得最大值的 x 值实验原理(算法流程)演化算法(遗传算法):(1) 初始化种群的范围是 1, 20,对于每个个体 x ,求出 y(2) 在 1, 20 中任意选择两个 x 坐标,做仿射变换得到一个新的 x 坐标,记为 x1(3) 将通过仿射变换得到的 x1 代入方程y=10*sin(5*x)+7*cos(4*x) 求出一个y1(4) 比较 y1 和 y 的值,筛选掉值少的一个,y 保存更接近最优解的一个值算法的思想是动态逼近法,通过枚举 x 坐标,作仿射变换得到 x1,求出 y1 值,然后用y1与y比较,筛选掉值小者,每次枚举都得到一个接近最优解的 x,y坐标,迭代的次数大概在 250 1000 就基本可以确定最优解组内分工(可选)
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1