您的位置:首页 > 其它

利用图的宽度优先搜索(层次遍历)实现查找从迷宫左上

2013-08-21 21:28 381 查看
  

  // 查找从迷宫左上角到右下角的最优路径(路径最短)

  // 利用图的宽度优先搜索(层次遍历)实现

  int SearchMaze(int *A, int m, int n, vector &path)

  {

   // 迷宫位置类型

   typedef pair Position;

  

   // 移动操作类型

   typedef unsigned char MoveType;

   const MoveType UNVISITED = 'N'; // 未访问

   const MoveType START = 'S'; // 起点

   const MoveType UP = 'U'; // 向上

   const MoveType RIGHT = 'R'; // 向右

   const MoveType DOWN = 'D'; // 向下

   const MoveType LEFT = 'L'; // 向左

  

   // 用于暂存位置的队列

   queue posQueue;

  

   // 标记,用于区分层次遍历的各层,以便计算路径长度

   Position tag(-1, -1);

   // 目标位置

   Position target(m - 1, n - 1);

  

   // 状态数组,用于记录迷宫的每个位置是否已经访问

   vector state(m * n, UNVISITED);

  

   // 标记能否到达目标位置

   bool succeed = false;

  

   // 把起始位置压入队列,开始搜索

   posQueue.push(make_pair(0, 0));

   posQueue.push(tag);

   int pathLength = 1;

   state[0] = START;

  

   // 搜索目标位置

   while (!posQueue.empty()) {

   Position cur = posQueue.front();

   posQueue.pop();

  

   if (cur == target) {

   // 找到目标位置

   succeed = true;

   break;

   }

  

   if (cur == tag) {

   // 本层遍历结束,进入下一层

   if (!posQueue.empty()) {

   ++pathLength;

   posQueue.push(tag);

   }

   continue;

   }

  

   // 从当前位置向上、下、左、右搜索

   int i = cur.first;

   int j = cur.second;

   int index;

  

   // 向上

   index = (i - 1) * n + j;

   if (i > 0 && A[index] == 0 && state[index] == UNVISITED) {

   posQueue.push(Position(i - 1, j));

   state[index] = UP;

   }

  

   // 向右

   index = i * n + j + 1;

   if (j < n - 1 && A[index] == 0 && state[index] == UNVISITED) {

   posQueue.push(Position(i, j + 1));

   state[index] = RIGHT;

   }

  

   // 向下

   index = (i + 1) * n + j;

   if (i < m - 1 && A[index] == 0 && state[index] == UNVISITED) {

   posQueue.push(Position(i + 1, j));

   state[index] = DOWN;

   }

  

   // 向左

   index = i * n + j - 1;

   if (j > 0 && A[index] == 0 && state[index] == UNVISITED) {

   posQueue.push(Position(i, j - 1));

   state[index] = LEFT;

   }

   }

  

   if (succeed) {

   // 能够到达目标位置,输出移动操作序列

   path.clear();

   path.reserve(pathLength);

  

   int i = m - 1;

   int j = n - 1;

   int index = i * n + j;

   for (; state[index] != START; index = i * n + j) {

   assert(state[index] != UNVISITED && "不可能是未访问位置!");

   path.push_back(state[index]);

   switch (state[index])

   {

   case UP:

   ++i;

   break;

  

   case RIGHT:

   --j;

   break;

  

   case DOWN:

   --i;

   break;

  

   case LEFT:

   ++j;

   break;

   }

   }

   reverse(path.begin(), path.end());

  

   return pathLength;

   }

  

   return -1;

  }

  

  int main()

  {

   const int m = 8;

   const int n = 8;

   int A[m * n] = {

   0, 0, 0, 0, 1, 0, 0, 0,

   1, 0, 1, 0, 0, 0, 1, 0,

   0, 0, 1, 0, 1, 0, 1, 0,

   0, 1, 1, 0, 0, 0, 1, 0,

   0, 0, 0, 0, 1, 1, 0, 0,

   0, 1, 1, 0, 0, 0, 0, 1,

   0, 0, 0, 0, 1, 0, 1, 1,

   1, 0, 0, 0, 1, 0, 0, 0,

   };

  

   vector path;

  

   int length = SearchMaze(A, 8, 8, path);

  

   if (length > 0) {

   cout << "Shortest path length: " << length << endl;

   cout << "The Path: ";

   copy(path.begin(), path.end(), ostream_iterator(cout));

   cout << endl;

   } else {

   cout << "Can't reach the destination!" << endl;

   }

  

  }

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐