技术,瞎侃,健康,休闲……

mahu@cppblog 人类的全部才能无非是时间和耐心的混合物
posts - 11, comments - 13, trackbacks - 0, articles - 12
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

八数码问题——A*搜索

Posted on 2006-06-26 22:44 mahudu@cppblog 阅读(488) 评论(0)  编辑 收藏 引用 所属分类: Programming

zz from http://blog.csdn.net/tiandejian/archive/2006/06/26/837659.aspx

先把问题简化一下吧:

在控制台显示这样一个矩阵

[1][2][3]
[8]   [4]
[7][6][5]

手动把它打乱,然后让程序将其复原。

和野人传教士问题类似,这也是一个对解空间进行搜索的问题,而且更为简单,这次采用可以缩减扩展节点的规模的A*启发式搜索算法。取节点深度为g(x),错位的数字数为h(x),由于问题很简单,所以与有序搜索算法类似,算法框图:

 评价函数封装在类里,所以没显示在框图中。

显然的,用一个一维数组保存这九个位置的数,evaluate()函数返回当前状态的评价值。

#include <iostream>

#include <conio.h>

#include <windows.h>     // 显示矩阵时需要延时,这里有 Sleep() 函数。

using namespace std;

 

// 接收键盘时使用

const enum Input { UP = 0x048, DOWN = 0x050, LEFT = 0x04b, RIGHT = 0x04d, ENTER = 0xd };

// 扩展时判断方向使用

const int U = 0;

const int D = 1;

const int L = 2;

const int R = 3;

class ElemType {

private :

    int depth;        // 当前节点的深度(就是距离初始节点有多远)

    int numWrong() {  // 有多少错位的数字

       int i, value = 0;

       if (maze[0]!=1) value++;

       if (maze[1]!=2) value++;

       if (maze[2]!=3) value++;

       if (maze[3]!=8) value++;

       if (maze[5]!=4) value++;

       if (maze[6]!=7) value++;

        if (maze[7]!=6) value++;

       if (maze[8]!=5) value++;

       return value;

    }

public :

    int maze[9];      // 保存矩阵用

    ElemType* flag;   // 指向根节点

    ElemType() {      // 创建初始节点

       maze[0]=1; maze[1]=2; maze[2]=3;

       maze[3]=8; maze[4]=0; maze[5]=4;

       maze[6]=7; maze[7]=6; maze[8]=5;

       depth = 0;

       flag = NULL;

    }

    ElemType( int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8) {

       maze[0]=i0; maze[1]=i1; maze[2]=i2;

       maze[3]=i3; maze[4]=i4; maze[5]=i5;

       maze[6]=i6; maze[7]=i7; maze[8]=i8;

       depth = 0;

       flag = NULL;

    }

    bool operator ==(ElemType e) {

       for ( int i = 0; i < 9; i++)

           if ( this ->maze[i]!=e.maze[i])

              return false ;

       return true ;

    }

    void operator =(ElemType e) {

       for ( int i = 0; i < 9; i++)

           this ->maze[i] = e.maze[i];

       this ->depth = e.depth;

       this ->flag = e.flag;

       this ->numWrong();

    }

    ElemType friendoperator >>(ElemType source, int direct) {

// 对于 L R U D 四个方向作出的移动

       ElemType result = source;

       int i = result.locate0();

       switch (direct) {

           case U: if(i < 6){

result.maze[i] = result.maze[i+3];

result.maze[i+3] = 0;

} break;

           case D: if(i > 2){

result.maze[i] = result.maze[i-3];

result.maze[i-3] = 0;

} break;

           case L: if(i%3 != 2) {

result.maze[i] = result.maze[i+1];

result.maze[i+1] = 0;

} break;

           case R: if(i%3 != 0) {

result.maze[i] = result.maze[i-1];

result.maze[i-1] = 0;

}

       }

       result.depth++;

       return result;

    }

 

       for ( int i = 0; i < 9; i++)

           if (maze[i] == 0)

              return i;

       return -1;

    }

    bool isSuccess() {

       return maze[0]==1 && maze[1]==2 && maze[2]==3 &&

               maze[3]==8 && maze[4]==0 && maze[5]==4 &&

              maze[6]==7 && maze[7]==6 && maze[8]==5;

    }

    // 下面是评价函数

    int evaluate() { return depth + numWrong(); }

    void disrupt() {      // 打乱初始矩阵

        clrscr();

        gotoxy(7,3);

        cout << "Disrypt the maze as you wish, press enter to see the AMAZING thing!" ;

        this ->print();

        int input;

        while ((input=_getch()) != ENTER) {

            switch (input) {

                case UP:    * this = * this >> U; this ->print(); break ;

                case DOWN:  * this = * this >> D; this ->print(); break ;

                case LEFT:  * this = * this >> L; this ->print(); break ;

                case RIGHT: * this = * this >> R; this ->print();

            }

        }

    }

    void print() {

        for ( int i = 0; i < 3; i++) {

            for ( int j = 0; j < 3; j++) {

                gotoxy(36+j*3, 8+i);

                if (maze[i*3+j]!=0) cout << '[' << maze[i*3+j] << ']' ;

                else cout << "   " ;

            } cout << endl;

       }

        Sleep(200);

    }

};

 

void print(ElemType &e) { e.print(); }

 

ElemType null(0,0,0,0,0,0,0,0,0); // 每个位置都是 0 ,这是不存在的

 

#include "dso.h"  

typedef ElemType Status;

 

    int locate0() {      // 确定 0 所在的位置,其余方法要调用


Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=837659


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理