< 人工智能 > 实验报告 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 V isited(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;
}
V isited(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; }。