A*算法求解八数码问题

一、

问题描述:

A*算法是一种启发式图搜索算法,其特点在于对估价函数的定义上。对于一般的启发式图搜索,总是选择估价函数f值最小的节点作为扩展节点。因此,f是根据需要找到一条最小代价路径的观点来估算节点的,所以,考虑每个节点n的估价函数值为两个分量:f(n)=g(n)+h(n),从起始节点到节点n的实际代价g(n),从节点n到达目标节点的估价代价h(n)(不在点位个数),

八数码问题的求解

八数码问题是在3×3的九宫格棋盘上,摆有8个刻有1~8数码的将牌。棋盘中有一个空格,允许紧邻空格的某一将牌可以移到空格中,这样通过平移将牌可以将某一将牌布局变换为另一布局。给定的一种初始布局,目标状态,问如何移动将牌,实现从初始状态到目标状态的转变。

二、

算法设计:

将起始点加入open表

     当open表不为空时:

       寻找open表中f值最小的点current

       它是终止点,则找到结果,程序结束。

       否则,在Open表中移出current,对current表中的每一个临近点

           若它不可走或在close表中,略过

           若它不在open表中,加入。

           若它在open表中,计算g值,若g值更小,替换其父节点为current,更新

它的g值。

     若open表为空,则路径不存在。

算法流程图:

数据结构:用于记录最佳路径的树,两个链表,open表和close表

三、实现与实例

初始状态:2,8,3,0,6,4,1,7,5

目标状态:1,2,3,8,0,4,7,6,5

运行结果:

第0层的状态:

2 8 3

0 6 4

1 7 5

第1层的状态:

2 8 3

1 6 4

0 7 5

第2层的状态:

2 8 3

1 6 4

7 0 5

第3层的状态:

2 8 3

1 0 4

7 6 5

第4层的状态:

2 0 3

1 8 4

7 6 5

第5层的状态:

0 2 3

1 8 4

7 6 5

第6层的状态:

1 2 3

0 8 4

7 6 5

第7层的状态:

1 2 3

8 0 4

7 6 5

生成节点数目:20

扩展节点数目:10

运行时间:16.000000

代码实现:

#include "iostream"  

#include "stdlib.h"  

#include "conio.h"  

#include <math.h>

#include <windows.h>

using namespace std;

//定义二维数组来存储数据表示某一个特定状态  

typedef int status[3][3];

//定义 状态图中的结点数据结构  

typedef struct Node

{

    status data;//结点所存储的状态 ,一个3*3矩阵

    struct Node* parent;//指向结点的父亲结点  

    struct SpringLink* child;//指向结点的后继结点  

    struct Node* next;//指向open或者closed表中的后一个结点  

    int fvalue;//结点的估价函数值

    int gvalue;//结点的深度

    int hvalue;//结点到目标节点的预估代价值

}NNode, * PNode;

//定义存储指向结点后继结点的指针的地址  

typedef struct SpringLink

{

    struct Node* pointData;//指向结点的指针  

    struct SpringLink* next;//指向兄第结点  

}SPLink, * PSPLink;

PNode open;

PNode closed;

//OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点

//开始状态与目标状态  

int t = 0; //迭代次数,相当于运行时间

int count_extendnode = 0;//扩展结点

int count_sumnode = 0; //生成节点

status startt = { 2,8,3,0,6,4,1,7,5 }; //实验报告

status target = { 1,2,3,8,0,4,7,6,5 };

//初始化空链表  

void initLink(PNode& Head)

{

    Head = (PNode)malloc(sizeof(NNode));

    Head->next = NULL;

}

//判断链表是否为空  

bool isEmpty(PNode Head)

{

    if (Head->next == NULL)

        return true;

    else

        return false;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值