首页 > 技术文章 > 关于8数码的搜索问题

gambler 2018-05-08 19:38 原文

在这里就不给什么解释了,看代码,代码里有很多提示

目前只写了基于广度优先搜索的算法程序,其他优先以及启发式搜索,等有空再补上

#include<bits/stdc++.h>
using namespace std;

struct dp{
char matrix[3][3];//初始矩阵
int  markzerox,markzeroy;//记录空白位置
int  movefn;//记录来自哪个矩阵
char  movefd;//记录来自哪个方向,避免重复
};
dp d[100];

int num=1;//记录第几个矩阵
bool flag=false;//表示是否为可接受状态

void getInit(void){//初始化输入矩阵
    freopen("input.txt","r",stdin);
    for(int i=0;i<3;i++){
        for(int j=0;j<3;j++){
            cin>>d[1].matrix[i][j];
        if(d[1].matrix[i][j]=='0'){//从初始矩阵记录当前空白位置
            d[1].markzerox=i;
            d[1].markzeroy=j;
        }
        }
    }
    d[1].movefd='0';
    d[1].movefn=0;
}

void showMatrix(){
    for(int n=1;n<=num;n++){
        cout<<"当前矩阵为:"<<n<<endl;
        for(int i=0;i<3;i++){
            for(int j=0;j<3;j++){
                cout<<d[n].matrix[i][j]<<" ";
            }
            cout<<endl;
        }
    }
}

bool judgeCondition(char matrix[3][3]){//判断当前矩阵是否是可接受状态
    if(matrix[0][0]=='1' && matrix[0][1]=='2' && matrix[0][2]=='3' && matrix[1][2]=='4' && matrix[2][2]=='5'
       &&matrix[2][1]=='6' && matrix[2][0]=='7' && matrix[1][0]=='8')
        return true;
    else
        return false;
}
//
//void exchange(char a,char b){//进行交换
//    char temp=a;
//    a=b;
//    b=temp;
//}

bool judgerepeat(dp dd){//判断是否有重复
//    cout<<"jnum= "<<num<<endl;
     for(int cm=1;cm<num;cm++){
        int recount = 0;
        for(int i=0;i<3;i++){
            for(int j=0;j<3;j++){
                if(dd.matrix[i][j]==d[cm].matrix[i][j]){
                  recount++;
                }
            }
        }

        if(recount==9){
            return true;
        }

     }
     return false;
}

dp move(dp ddd,char direction){//移动规则
//    cout<<"mark!!!"<<endl;
//    cout<<"unum= "<<num<<endl;
    int n=num;
    num++;//序号+1
    int tmarkzerox = ddd.markzerox;
    int tmarkzeroy = ddd.markzeroy;
    d[num] = ddd;//对结构体进行复制
    if(direction=='l'){
        swap(d[num].matrix[tmarkzerox][tmarkzeroy],d[num].matrix[tmarkzerox][tmarkzeroy-1]);
        d[num].markzeroy-=1;
    }
    if(direction=='r'){
        swap(d[num].matrix[tmarkzerox][tmarkzeroy],d[num].matrix[tmarkzerox][tmarkzeroy+1]);
       d[num].markzeroy+=1;
    }
    if(direction=='u'){
        swap(d[num].matrix[tmarkzerox][tmarkzeroy],d[num].matrix[tmarkzerox-1][tmarkzeroy]);
        d[num].markzerox-=1;
    }
    if(direction=='d'){
        swap(d[num].matrix[tmarkzerox][tmarkzeroy],d[num].matrix[tmarkzerox+1][tmarkzeroy]);
        d[num].markzerox+=1;
    }
    d[num].movefd=direction;//记录来自上一个矩阵的方向
    d[num].movefn=n;//记录上一个矩阵的序号
//    cout<<"dnum= "<<num<<endl;
    if(judgerepeat(d[num])){//如果出现与之前相同的状态则去掉该状态
        num--;    }

    return d[num];
}



//广度搜索
void BFS(){//记住,序号1未进行检测
    int cn=num;
    while(!flag&&cn<=num&&cn<15){//检测是否是可接受状态以及是否有重复状态出现
//        cout<<"d[cn].markzerox= "<<d[cn].markzerox<<" d[cn].markzeroy="<<d[cn].markzeroy<<endl;
//        cout<<"d[cn].movefd= "<<d[cn].movefd<<endl;
        if(d[cn].markzerox > 0&&d[cn].movefd!='d'){//检测空白点四周可移动路径,以及是否回到上一次状态
                if(judgeCondition(move(d[cn],'u').matrix)){//检测该状态是否被接受
                        flag = true;
                        break;
                }
        }
        if(d[cn].markzerox < 2&&d[cn].movefd!='u'){
            if(judgeCondition(move(d[cn],'d').matrix)){
                flag = true;
                break;
            }
        }
        if(d[cn].markzeroy > 0&&d[cn].movefd!='r'){
            if(judgeCondition(move(d[cn],'l').matrix)){
                flag = true;
                break;
            }
        }
        if(d[num].markzeroy < 2&&d[cn].movefd!='l'){
            if(judgeCondition(move(d[cn],'r').matrix)){
                flag = true;
                break;
            }
        }

        cn=cn+1;//每次向前走一个状态
//        cout<<" num= "<<num<<" cn="<<cn;
    }
}

void myshow(){

    if(flag){
        cout<<"在第"<<num<<"个状态被接受!!!"<<endl;
    }else{
        cout<<"发生错误!!!当前在:"<<num<<endl;
    }
}



int main(){
    getInit();
    BFS();
 showMatrix();
    myshow();
    return 0;

}

 

推荐阅读