读书人

求八数码中遇到的有关问题

发布时间: 2012-10-17 10:25:46 作者: rapoo

求八数码中遇到的问题
我的代码在vs2010下编译通过后,运行,输入数组后程序崩了,提示deque iterator not dereferencable
我没有发现我的代码的错误,求高人帮助,我采用的是全局择优搜索解八数码下面是我的代码

C/C++ code
#include<iostream>#include<deque>#include<vector>#include<string.h>using namespace std;int go_l[3][3]={0};   //目标节点class QNode{public:    int depth;   //节点的深度    int diff;     //与父亲节点不同位置的数字个数    int fs;      //估价函数值 fs=depth+diff    int arry[3][3];        //八数码数组    QNode()               //空构造函数    {        depth=0;        diff=0;        fs=0;        memset(arry,0,sizeof(arry));    }    QNode(const QNode &ha)                 //复制构造函数    {        this->depth=ha.depth;        this->diff=ha.diff;        this->fs=ha.fs;        for(int i=0;i!=3;i++)            for(int j=0;j!=3;j++)                this->arry[i][j]=ha.arry[i][j];    }    QNode(int dep,int dif,int (&aa)[3][3])         //赋值构造函数2    {        this->depth=dep;        this->diff=dif;        this->fs=this->depth+this->diff;        for(int i=0;i!=3;i++)            for(int j=0;j!=3;j++)                this->arry[i][j]=aa[i][j];    }    void Display()                   //打印    {        cout<<"深度为"<<this->depth<<endl;        //cout<<"与父亲节点位置不同的数字个数为"<<diff<<endl;        for(int i=0;i!=3;i++)        {            for(int j=0;j!=3;j++)                cout<<this->arry[i][j]<<' ';            cout<<endl;        }    }    bool Equal(QNode &a)             //判断是否相等    {        for(int i=0;i!=3;i++)        {            for(int j=0;j!=3;j++)            {                if(this->arry[i][j]!=a.arry[i][j])                    return false;                continue;            }        }            return true;    }    void Exchange(QNode &p)             //交换节点数值    {        int r=0,s=0,t=0;        r=this->depth;        this->depth=p.depth;        p.depth=r;   //交换depth        s=this->diff;        this->diff=p.diff;        p.diff=s;          //交换diff值        this->fs=depth+diff;            //交换估价函数值        p.fs=p.depth+p.diff;        for(int i=0;i!=3;i++)                  //交换二维数组arry的值        {            for(int j=0;j!=3;j++)            {                t=this->arry[i][j];                this->arry[i][j]=p.arry[i][j];                p.arry[i][j]=t;            }        }    }};deque<QNode> open;               //open表vector<QNode> whole; //记录已经扩展过得节点//vector<QNode> opens;      //用于排序,然后插入open表vector<QNode> closed;      //closed表int Check_cal(int (&a)[3][3])                   //计算与父亲节点位置不同的数字个数{    int hi=1,count=0;    while(hi<9)    {        int flag=0;        for(int i=0;i!=3;i++)        {            for(int j=0;j!=3;j++)            {                if(a[i][j]==hi&&go_l[i][j]!=hi)                    flag=1;                else                    continue;            }        }        if(flag==1)            count++;        hi++;    }    return count;}bool Check_equ(QNode &a){    for(int i=0;i!=3;i++)    {        for(int j=0;j!=3;j++)        {            if(a.arry[i][j]!=go_l[i][j])                return false;            continue;        }    }    return true;}bool Check_can(QNode &a,vector<QNode> &whole)          //检验是否可以扩展(即与已经扩展过得节点是否相同),相同则返回false{      if(whole.size()==1&&whole[0].Equal(a))        return true;    else    {        for(vector<QNode>::size_type i=0;i!=whole.size();i++)            if(a.Equal(whole[i]))                return false;        return true;    }}void Sort(deque<QNode> &open)            //递增冒泡排序{    for(int it=0;it!=open.size()-1;it++)    {        for(deque<QNode>::iterator jt=open.begin();jt!=open.end()-it-1;jt++)        {            if(jt->fs>(jt+1)->fs)                jt->Exchange(*(jt+1));        }    }}void Extend(QNode &a,vector<QNode> &whole)      //扩展父亲节点,插入open表并排序{    int l=0,r=0,flag,m,n;    QNode q1,q2,q3,q4;    for(int i=0;i!=3;i++)    {        for(int j=0;j!=3;j++)        {            if(a.arry[i][j]==0)            {                l=i;                r=j;            }            continue;        }    }    if(l==1&&r==1)        flag=4;    if((l==0&&r==0)||(l==2&&r==0)||(l==0&&r==2)||(l==2&&r==2))        flag=2;    if((l==1&&r==0)||(l==2&&r==1)||(l==1&&r==2)||(l==0&&r==1))        flag=3;    switch(flag)    {    case 4:        q1.depth=a.depth+1;q2.depth=a.depth+1;q3.depth=a.depth+1;q4.depth=a.depth+1; //子节点的深度为父节点深度加1        for(m=0;m!=3;m++)         //修改相应的八数码二维数组        {            for(n=0;n!=3;n++)            {                q1.arry[m][n]=a.arry[m][n];                q2.arry[m][n]=a.arry[m][n];                q3.arry[m][n]=a.arry[m][n];                q4.arry[m][n]=a.arry[m][n];            }        }        m=0;n=0;        q1.arry[1][1]=q1.arry[1][0];        q1.arry[1][0]=0;        q2.arry[1][1]=q2.arry[2][1];        q2.arry[2][1]=0;        q3.arry[1][1]=q3.arry[1][2];        q3.arry[1][2]=0;        q4.arry[1][1]=q4.arry[0][1];        q4.arry[0][1]=0;        q1.diff=Check_cal(q1.arry);q2.diff=Check_cal(q2.arry);q3.diff=Check_cal(q3.arry);q4.diff=Check_cal(q4.arry);    //获得diff        q1.fs=q1.depth+q1.diff;q2.fs=q2.depth+q2.diff;q3.fs=q3.depth+q3.diff;q4.fs=q4.depth+q4.diff;    //获得估价函数值        whole.push_back(q1);whole.push_back(q2);whole.push_back(q3);whole.push_back(q4);        open.push_back(q1);open.push_back(q2);open.push_back(q3);open.push_back(q4);        Sort(open);        break;     case 3:        q1.depth=a.depth+1;q2.depth=a.depth+1;q3.depth=a.depth+1;           //深度加1        for(m=0;m!=3;m++)         //修改相应的八数码二维数组        {            for(n=0;n!=3;n++)            {                q1.arry[m][n]=a.arry[m][n];                q2.arry[m][n]=a.arry[m][n];                q3.arry[m][n]=a.arry[m][n];            }        }        for(m=0;m!=3;m++)        {            for(n=0;n!=3;n++)            {                if(a.arry[m][n]==0)                {                     l=m;r=n;                    break;                }            }        }        if(l==1&&r==0)        {            q1.arry[l][r]=q1.arry[0][0];q1.arry[0][0]=0;            q1.diff=Check_cal(q1.arry);q1.fs=q1.depth+q1.diff;            q2.arry[l][r]=q2.arry[2][0];q2.arry[2][0]=0;            q2.diff=Check_cal(q2.arry);q2.fs=q2.depth+q2.diff;            q3.arry[l][r]=q3.arry[1][1];q3.arry[1][1]=0;            q3.diff=Check_cal(q3.arry);q3.fs=q3.depth+q3.diff;            whole.push_back(q1);whole.push_back(q2);whole.push_back(q3);            open.push_back(q1);open.push_back(q2);open.push_back(q3);            Sort(open);        }        if(l==2&&r==1)        {            q1.arry[l][r]=q1.arry[2][0];q1.arry[2][0]=0;            q1.diff=Check_cal(q1.arry);q1.fs=q1.depth+q1.diff;            q2.arry[l][r]=q2.arry[1][1];q2.arry[1][1]=0;            q2.diff=Check_cal(q2.arry);q2.fs=q2.depth+q2.diff;            q3.arry[l][r]=q3.arry[2][2];q3.arry[2][2]=0;            q3.diff=Check_cal(q3.arry);q3.fs=q3.depth+q3.diff;            whole.push_back(q1);whole.push_back(q2);whole.push_back(q3);            open.push_back(q1);open.push_back(q2);open.push_back(q3);            Sort(open);        }        if(l==1&&r==2)        {            q1.arry[l][r]=q1.arry[2][2];q1.arry[2][2]=0;            q1.diff=Check_cal(q1.arry);q1.fs=q1.depth+q1.diff;            q2.arry[l][r]=q2.arry[1][1];q2.arry[1][1]=0;            q2.diff=Check_cal(q2.arry);q2.fs=q2.depth+q2.diff;            q3.arry[l][r]=q3.arry[0][2];q3.arry[0][2]=0;            q3.diff=Check_cal(q3.arry);q3.fs=q3.depth+q3.diff;            whole.push_back(q1);whole.push_back(q2);whole.push_back(q3);            open.push_back(q1);open.push_back(q2);open.push_back(q3);            Sort(open);        }        if(l==0&&r==1)        {            q1.arry[l][r]=q1.arry[0][0];q1.arry[0][0]=0;            q1.diff=Check_cal(q1.arry);q1.fs=q1.depth+q1.diff;            q2.arry[l][r]=q2.arry[1][1];q2.arry[1][1]=0;            q2.diff=Check_cal(q2.arry);q2.fs=q2.depth+q2.diff;            q3.arry[l][r]=q3.arry[0][2];q3.arry[0][2]=0;            q3.diff=Check_cal(q3.arry);q3.fs=q3.depth+q3.diff;            whole.push_back(q1);whole.push_back(q2);whole.push_back(q3);            open.push_back(q1);open.push_back(q2);open.push_back(q3);            Sort(open);        }        break;     case 2:         q1.depth=a.depth+1;q2.depth=a.depth+1;              //子节点深度为父节点加1         for(m=0;m!=3;m++)         //修改相应的八数码二维数组        {            for(n=0;n!=3;n++)            {                q1.arry[m][n]=a.arry[m][n];                q2.arry[m][n]=a.arry[m][n];            }        }        for(m=0;m!=3;m++)        {            for(n=0;n!=3;n++)            {                if(a.arry[m][n]==0)                {                     l=m;r=n;                    break;                }            }        }        if(l==0&&r==0)        {            q1.arry[l][r]=q1.arry[1][0];q1.arry[1][0]=0;            q1.diff=Check_cal(q1.arry);q1.fs=q1.depth+q1.diff;            q2.arry[l][r]=q2.arry[0][1];q2.arry[0][1]=0;            q2.diff=Check_cal(q2.arry);q2.fs=q2.depth+q2.diff;            whole.push_back(q1);whole.push_back(q2);            open.push_back(q1);open.push_back(q2);            Sort(open);        }        if(l==2&&r==0)        {            q1.arry[l][r]=q1.arry[1][0];q1.arry[1][0]=0;            q1.diff=Check_cal(q1.arry);q1.fs=q1.depth+q1.diff;            q2.arry[l][r]=q2.arry[2][1];q2.arry[2][1]=0;            q2.diff=Check_cal(q2.arry);q2.fs=q2.depth+q2.diff;            whole.push_back(q1);whole.push_back(q2);            open.push_back(q1);open.push_back(q2);            Sort(open);        }        if(l==2&&r==2)        {            q1.arry[l][r]=q1.arry[2][1];q1.arry[2][1]=0;            q1.diff=Check_cal(q1.arry);q1.fs=q1.depth+q1.diff;            q2.arry[l][r]=q2.arry[1][2];q2.arry[1][2]=0;            q2.diff=Check_cal(q2.arry);q2.fs=q2.depth+q2.diff;            whole.push_back(q1);whole.push_back(q2);            open.push_back(q1);open.push_back(q2);            Sort(open);        }        if(l==0&&r==2)        {            q1.arry[l][r]=q1.arry[0][1];q1.arry[0][1]=0;            q1.diff=Check_cal(q1.arry);q1.fs=q1.depth+q1.diff;            q2.arry[l][r]=q2.arry[1][2];q2.arry[1][2]=0;            q2.diff=Check_cal(q2.arry);q2.fs=q2.depth+q2.diff;            whole.push_back(q1);whole.push_back(q2);            open.push_back(q1);open.push_back(q2);            Sort(open);        }        break;     default:cout<<"出错了!亲!"<<endl;    }}int main(void){    int num=0,i,j,t=0;    int arr[3][3]={0};    cout<<"请输入您的八数码,空格处用0代替,亲!"<<endl;    for(i=0;i!=3;i++)        for(j=0;j!=3;j++)            cin>>arr[i][j];    cout<<"请输入您的目标八数码,空格处用0代替,亲!"<<endl;    for(i=0;i!=3;i++)        for(j=0;j!=3;j++)            cin>>go_l[i][j];    num=Check_cal(arr);    QNode q(t,num,arr);    open.push_back(q);    whole.push_back(q);    if(open.empty())    {        cout<<"问题无解,失败了,亲"<<endl;        return 0;    }    while(!open.empty())    {        begin:        closed.push_back(open.front());             //取open表头结点入closed表,并删除open表的头结点        open.pop_front();        if(Check_equ(closed.back()))        {            cout<<"恭喜亲,找到目标节点,任务完成"<<endl;            /*return 0;*/            break;        }        else        {            if(!Check_can(closed.back(),whole))                goto begin;            Extend(closed.back(),whole);        }        }    cout<<"出结果了亲!"<<endl;    cout<<"你输入的起始节点到目标节点需要经过一下步骤"<<endl;    for(vector<QNode>::iterator iter=closed.begin();iter!=closed.end();iter++)        iter->Display();    return 0;} 



[解决办法]
同求高人啊,我调试了一下你的代码,发现错误就是出现在输出路径的循环里,我用全0做输入,发现还是崩了.
[解决办法]
亲,目测一下,你这个是课程设计
[解决办法]
建议用A*吧,网上有资料,主要看下估值函数怎么算就行了,你的程序可能是双向列表使用有错。
双向列表的操作很容易让迭代器失效。

void Sort(deque<QNode> &open) //递增冒泡排序
{
for(int it=0;it!=open.size()-1;it++)
{
for(deque<QNode>::iterator jt=open.begin();jt!=open.end()-it-1;jt++)
{
if(jt->fs>(jt+1)->fs)
jt->Exchange(*(jt+1));
}
}
}
[解决办法]
以前做acm的时候有关于八数码的问题,太长了,看不了
[解决办法]
探讨

你的程序编得太长了,可以想……

[解决办法]
哈哈,我们搞机械的,看了这个就眼花头晕!
[解决办法]
你这个8数码写的也太复杂了。。
建议你用“康拓展开”来记录状态。
然后双向BFS搜索。。在搜索之前还要判断是否有解。

读书人网 >软件架构设计

热点推荐