< 人工智能 > 实 验 报 告 3
一、实验目的: 掌握汉诺塔的深度有界搜索求解算法的基本思想。
二、实验要求:
用C语言实现汉诺塔的深度有界搜索求解
三、实验语言环境:
C语言
四、设计思路:
含有深度界限的深度优先搜索算法如下:
(1) 把起始节点S放到未扩展节点OPEN表中。如果此节点为一目标节点,则得到一个解。
(2) 如果OPEN为一空表,则失败退出。
(3) 把第一个节点(节点n)从OPEN表移到CLOSED表。
(4) 如果节点n的深度等于最大深度,则转向(2)。
(5) 扩展节点n,产生其全部后裔,并把它们放入OPEN表的前头。如果没有后裔,则转向(2)。
(6) 如果后继节点中有任一个为目标节点,则求得一个解,成功退出;否则,转向(2)。
五、实验代码:
#include <stdio.h>
#include <string.h>
typedef struct node {
long map;
long floor; //记录第几层
} node;
node queue[362880 / 2 + 1]; //奇偶各一半
long tail, head;
long hash[362880 / 32 + 1];
int main()
{
void Solve();
while (scanf("%ld", &queue[0].map) && queue[0].map) { memset(hash, 0, sizeof(hash));
queue[0].floor = 1; //(根节点)第一层
tail = head = 0;
Solve();
printf("max_floor == %d\n", queue[head].floor); printf("total node == %d\n", head + 1);
printf("total node in theory [%d]\n", 362880 / 2); }
return 0;
}
void Solve()
{
node e;
long i, map[9], space;
long Compress(long *);
int Visited(long *);
void swap(long &, long &);
while (tail <= head) {
e = queue[tail++];
for (i=8; i>=0; i--) {
map[i] = e.map % 10;
if (map[i] == 0) { space = i; }
e.map /= 10;
}
Visited(map); //根节点要置为访问过
if (space >= 3) { //can up
swap(map[space - 3], map[space]);
if (!Visited(map)) {
queue[++head].map = Compress(map);
queue[head].floor = queue[tail - 1].floor + 1;
}
swap(map[space - 3], map[space]);
}
if (space <= 5) { //can down
swap(map[space + 3], map[space]);
if (!Visited(map)) {
queue[++head].map = Compress(map);
queue[head].floor = queue[tail - 1].floor + 1; }
swap(map[space + 3], map[space]);
}
if (space % 3 != 0) { //can left
swap(map[space - 1], map[space]);
if (!Visited(map)) {
queue[++head].map = Compress(map);
queue[head].floor = queue[tail - 1].floor + 1; }
swap(map[space - 1], map[space]);
}
if (space % 3 != 2) { //can right
swap(map[space + 1], map[space]);
if (!Visited(map)) {
queue[++head].map = Compress(map);
queue[head].floor = queue[tail - 1].floor + 1; }
swap(map[space + 1], map[space]);
}
}
}
void swap(long &x, long &y)
{
x ^= y;
y ^= x;
x ^= y;
}
long Compress(long *map)
{
long t = 0, i;
for (i=0; i<9; i++) {
t = t * 10 + map[i];
}
return t;
}
int Visited(long *map)
{
long Hash(long *);
long n = Hash(map);
long a = n / 32;
long b = 1 << (n % 32);
if (hash[a] & b) {
return 1;
}
else {
hash[a] |= b;
return 0;
}
}
long Hash(long *map)
{
static long t, i, j;
static long formula[9] =
{ 1, 1, 2, 6, 24, 120, 720, 5040, 40320 }; static long temp[9];
for (i=0; i<9; i++) {
temp[i] = map[i];
}
t = 0;
for (i=0; i<9; i++) {
t += temp[i] * formula[8 - i]; for (j=i+1; j<9; j++) {
if (temp[j] > temp[i]) temp[j]--; } } return t; }
实验二:用状态空间搜索法解决二阶汉诺塔问题
一、实验目的:
解决汉诺塔问题;
掌握状态空间搜索法;
二、实验原理
我们可以用状态空间图表示法来求解问题。状态空间图是由节点以及节点间的连线所构成的图。节点对应问题的解决状态;连线对应状态转换操作,即算符。在二阶汉诺塔问题求解过程中,我们用Sk=(SK0,SK1)表示问题的状态,SK0表示盘A所在的柱号,SK1表示盘B所在的柱号。全部可能的状态有以下9种:
s0=(1,1) s1=(1,2) s2=(1,3)
s3=(2,1) s4=(2,2) s5=(2,3)
s6=(3,1) s7=(3,2) s8=(3,3)
问题的初始状态集合为s={s0},目标状态集合为G={s4,s8}。算符分别用A(I,j)以及B(I,j)表示。A(I,j)表示把盘A从柱i移到柱j上。一用有12个算符,分别是:
A(1,2), A(1,3), A(2,1), A(2,3), A(3,1), A(3,2)
B(1,2), B(1,3), B(2,1), B(2,3), B(3,1), B(3,2)
根据9中可能的状态和12中可能的算符,画出下列的状态空间图.
三、实验过程
根据实验原理,在纸上完成二阶汉诺塔的求解过程。并总结用状态图求解的一般思路。
四、主意事项
二阶的是最简单的,在移动的时候主意思维要清晰,不要盲目,以养成好习惯。
人工智能九宫格重移搜索成员赵春杰20xx210665羊森20xx210653黄鑫20xx210周成兵20xx210664王素娟20…
人工智能课程实验指导书实验内容实验一产生式系统实验实验二移动机器人的路径规划与行为决策实验实验三梵塔问题实验实验四A算法实验实验五…
华北电力大学实验报告实验名称课程名称人工智能及应用专业班级学生姓名号成绩指导教师李继荣实验日期20xx5学华北电力大学实验报告华北…
人工智能第二次实验报告一实验题目遗传算法的设计与实现二实验目的通过人工智能课程的学习熟悉遗传算法的简单应用三实验内容用遗传算法求解…
人工智能技术实验报告实验名称人工智能实验1姓名班级指导教师完成时间20xx04301读程序指出运行结果domainsssymbol…
课程设20xx年12月21计日目录2实验目的错误未定义书签3问题分析24实验步骤错误未定义书签5流程图36程序代码47程序调试与测…
1实验目的通过本实验掌握复杂性问题的分析方法了解汉诺塔游戏的时间复杂性和空间复杂性2问题描述汉诺塔问题来自一个古老的传说在世界刚被…
课程设计报告课程名称高级语言课程设计课程代码07300561设计内容汉诺塔演示系统专业计算机科学与技术20xx年12月16日1目录…
计算机学院实验报告课程名称数据结构实验名称汉诺塔学生姓名朱孝彬学生学号20xx0511001实验日期20xx1一实验目的1理解数据…
一算法程序includeltiostreamgtusingnamespacestd圆盘的个数最多为64constintMAX64用…