数据结构课设——隐式图的搜索问题

隐式图的搜索问题

实验内容:

编写九宫重排问题的启发式搜索(A*算法)求解程序。
在3х3组成的九宫棋盘上,放置数码为1~8的8个棋子,棋盘中留有一个空格,空格周围的棋子可以移动到空格中,从而改变棋盘的布局。根据给定初始布局和目标布局,编程给出一个最优的走法序列。输出每个状态的棋盘
测试数据:初始状态:123456780 目标状态:012345678
在这里插入图片描述

主要功能

启发式搜索算法的描述:
(1)把初始节点S0 放入Open表中,f(S0)=g(S0)+h(S0);
(2)如果Open表为空,则问题无解,失败退出;
(3)把Open表的第一个节点取出放入Closed表,并记该节点为n;
(4)考察节点n是否为目标节点。若是,则找到了问题的解,成功退出;
(5)若节点n不可扩展,则转到第(2)步;
(6)扩展节点n,生成子节点ni(i=1,2,……),计算每一个子节点的估价值f(ni) (i=1,2,……),并为每一个子节点设置指向父节点的指针,然后将这些子节点放入Open表中;
(7)根据各节点的估价函数值,对Open表中的全部节点按从小到大的顺序重新进行排序;
(8)转到第(2)步。

在这里插入图片描述

实验代码

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
struct node
{
    int nine[3][3];//数码状态
    int f;//估价值
    int direct;//空格移动方向
    node *parent;//父节点
    node(int direct) :direct(direct){}
    bool operator ==(node &a)
    {
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                if(a.nine[i][j]!=this->nine[i][j])
                    return false;
        return true;
    }
    node& operator =(node& a)
    {
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                this->nine[i][j]=a.nine[i][j];
        return *this;
    }
};
int pos[9]={4,0,1,2,5,8,7,6,3};
//每一位是某个数字应该在的位置所代表的数,除3和对3取余可以求出行列

void print(node* p)
{
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
            cout<<"    "<<p->nine[i][j]<<' ';
        cout<<endl;
    }
    cout<<endl;
}
vector<node*> open;         //open表
vector<node*> close;        //close表
vector<node*>::iterator up(vector<node*>& v,node* p)
{
    vector<node*>::iterator i=v.begin();
    for(;i<v.end();i++)
        if((*(*i))==*p)
            break;
    return i;
}
int cntH(node* p)
{
    int h=0;
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            if(p->nine[i][j]!=0)
                h+=abs(pos[p->nine[i][j]]/3-i)+abs(pos[p->nine[i][j]]%3-j);
    return h;
}
int f(node* p)
{
    return cntH(p)+p->direct;
}
bool cmp(node* p,node* q)
{
    return f(p)>f(q);
}
int find0(node& p)
{
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            if(p.nine[i][j]==0)
                return i*3+j;
}
node* search(node& s)
{
    int drc=0;
    open.push_back(&s);
    while(!open.empty())
    {
        sort(open.begin(),open.end(),cmp);
        node* p=open.back();
        open.pop_back();
        if(!cntH(p))
            return p;
        drc=p->direct+1;
        int zerop=find0(*p),x=zerop/3,y=zerop%3;
        for(int i=0;i<4;i++)
        {
            int xs=0,ys=0;
            if(i==0) xs=0,ys=1;
            else if(i==1) xs=0,ys=-1;
            else if(i==2) xs=1,ys=0;
            else if(i==3) xs=-1,ys=0;
            if(x+xs<0||x+xs>=3||y+ys<0||y+ys>=3)
                continue;
            node* q=new node(drc);
            q->parent=p;
            *q=*p;
            q->nine[x][y]=q->nine[x+xs][y+ys];
            q->nine[x+xs][y+ys]=0;
            bool skip=0;
            vector<node*>::iterator dup=up(open,q);
            if(dup!=open.end())
            {
                if(f(q)<f(*dup))
                {
                    (*dup)->direct=q->direct;
                    (*dup)->parent=q->parent;
                }
                skip=1;
            }
            dup=up(close,q);
            if(dup!=close.end())
                if(f(q)<f(*dup))
                {
                    close.erase(dup);
                    delete* dup;
                    open.push_back(q);
                    skip=1;
                }
            if(!skip)
                open.push_back(q);
        }
        close.push_back(p);
    }
}
void prints(node* p)
{
    vector<node*> trace;
    while(p)
    {
        trace.push_back(p);
        p=p->parent;
    }
    int coun=0;
    while(!trace.empty())
    {
        cout<<"----------step"<<coun<<"------------"<<endl;
        print(trace.back());
        cout<<"f:"<<f(trace.back())<<"     g:"<<coun<<"      h:"<<cntH(trace.back())<<endl<<endl;
        trace.pop_back();
        coun++;
    }
}
int main()
{
    node p(0);
    p.nine[0][0]=2;
    p.nine[0][1]=8;
    p.nine[0][2]=3;
    p.nine[1][0]=1;
    p.nine[1][1]=6;
    p.nine[1][2]=4;
    p.nine[2][0]=7;
    p.nine[2][1]=0;
    p.nine[2][2]=5;
    p.parent=nullptr;
    node* q;
    q=search(p);
    prints(q);
    return 0;
}

运行截图

在这里插入图片描述

总结

中间有个==写成了=,找了半天bug气死我了,一开始我没有具体实现思路,还是先看了好久别人的代码才大概有思路,写了大概4个小时,调试又花了很多时间,这个实验让我对于A星算法了解程度大大提升,上次人工智能实验老师给了代码,我就偷懒看了一遍,没有自己打一遍,这次算是补上了。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值