人工智能导论实验一 基于图搜索技术的八数码问题求解
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
广州大学学生实验报告
开课学院及实验室:计算机科学与工程实验室 2020年10月14日
(***报告只能为文字和图片,老师评语将添加到此处,学生请勿作答***)
一、实验内容
1. 分别用广度优先搜索策略、深度优先搜索策略和启发式搜索算法(至少两种)求解八数码问题;分析估价函数对启发式搜索算法的影响;探究讨论各个搜索算法的特点。
二、实验设备
1. 实验设备:计算机;
2. 平台:Windows操作系统,Visual C++ 6.0 / Python Anaconda
三、实验步骤
1. 随机生成一个八数码问题分布,设计一个可解的目标状态(要求棋盘9个位置都不同)
2. 分别用广度优先搜索策略、深度优先搜索策略和至少两种启发式搜索算法求解八数码问题
3. 分析估价函数对启发式搜索算法的影响
4. 探究讨论各个搜索算法的特点
四、分析说明(包括核心代码及解释)
广度优先搜索:
首先创建一个结构体node,来记录节点移动方向和扩展的节点。
struct node
{
int ab[3][3];//节点
int direction;//方向
};
struct node sh[102], end;
int count = 1;
然后创建一个init函数来初始化棋盘起始状态和目标状态,使用for语句填写棋盘数字
用loction函数确定0节点的位置,通过for语句和if语句判断sh[num].ab[i / 3][i % 3] == 0,即可得到0节点的位置
Sign函数用来获取棋盘状态,将当前棋盘数字顺序生成一个数,即可得知棋盘状态。
Mobile函数用来移动0节点,先用loction函数获取0节点的位置,再通过if语句来判断0节点位置和所能移动方向,然后进行移动。
Display函数使用for语句来打印当前棋盘。
Search函数使用display函数来打印从初始状态移动到目标状态的中间状态棋盘,在while(1)语句下利用mobile函数移动0节点,直到目标状态找到或者超过寻找次数。
#include
#include
struct node
{
int ab[3][3];//节点
int direction;//方向
};
struct node sh[102], end;
int count = 1;
void init()
{
printf("输入起始棋盘的状态:\n");
int i, j;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
scanf("%d", &sh[0].ab[i][j]);
sh[0].direction = -1;
printf("输入目标棋盘的状态:\n");
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
scanf("%d", &sh[101].ab[i][j]);
sh[101].direction = -1;
printf("中间状态:\n");
}
//找出0的位置
int loction(int num)
{
int i;
for (i = 0; i < 9; i++)
if (sh[num].ab[i / 3][i % 3] == 0) return i;
}
//获取棋盘状态
long long sign(int num)
{
long long sum;
sum = sh[num].ab[0][0] * 100000000 + sh[num].ab[0][1] * 10000000 + sh[num].ab[0][2] * 1000000 + sh[num].ab[1][0] * 100000 + sh[num].ab[1][1] * 10000 + sh[num].ab[1][2] * 1000 + sh[num].ab[2][0] * 100 + sh[num].ab[2][1] * 10 + sh[num].ab[2][2];
return sum;
}
//移动0节点
void mobile(int num)
{
int temp;
int loc;
int up = 1, down = 1, left = 1, right = 1;
loc = loction(num);
int stand = sh[num].direction;
//direction的0 1 2 3分别代表左上右下
if (loc / 3 != 0 && stand != 1)
{
sh[count] = sh[num];
temp = sh[count].ab[loc / 3][loc % 3];
sh[count].ab[loc / 3][loc % 3] = sh[count].ab[loc / 3 - 1][loc % 3];
sh[count].ab[loc / 3 - 1][loc % 3] = temp;
sh[count].direction = 3;
count++;
};
if (loc / 3 != 2 && stand != 3)
{
sh[count] = sh[num];
temp = sh[count].ab[loc / 3][loc % 3];
sh[count].ab[loc / 3][loc % 3] = sh[count].ab[loc / 3 + 1][loc % 3];
sh[count].ab[loc / 3 + 1][loc % 3] = temp;