• 迷宫寻径--试探回溯法


    空间区域限定为由n* n个方格组成的迷宫,除了四周的围墙,还有分布其间的若干障碍物;只能水平或垂直移动。我们的任务是,在任意指定的起始格点与目标格点之间,找出一条通路(如果的确存在)。

     1 #pragma once
     2 #define LABY_MAX 24 //最大迷宫尺寸
     3 typedef enum
     4 {
     5     AVAILABLE, //原始可用
     6     ROUTE, //当前路径上的
     7     BACKTRACKED, //所有方向均尝试失败后回溯过的
     8     WALL //
     9 }Status; //迷宫单元格状态
    10 typedef enum
    11 {
    12     UNKNOWN,
    13     EAST,
    14     SOUTH,
    15     WEST,
    16     NORTH,
    17     NO_WAY
    18 }ESWN;
    19 
    20 struct Cell
    21 {
    22     int x;
    23     int y;
    24     Status status;
    25     ESWN incoming, outgoing; //进入走出方向
    26 };
    27 
    28 inline ESWN nextESWN(ESWN eswn) { return ESWN(eswn + 1); } //依次转至下一邻接方向
    29 
    30 inline Cell* neighbor(Cell* cell) { //查询当前位置的相邻格点
    31     switch (cell->outgoing) {
    32     case EAST: return cell + LABY_MAX; //向东
    33     case SOUTH: return cell + 1;        //向南
    34     case WEST: return cell - LABY_MAX; //向西
    35     case NORTH: return cell - 1;        //向北
    36     }
    37 }
    38 
    39 inline Cell* advance(Cell* cell) //从当前位置转入相邻格点
    40 { 
    41     Cell* next;
    42     switch (cell->outgoing) 
    43     {
    44         case EAST:  next = cell + LABY_MAX; next->incoming = WEST;  break; //向东
    45         case SOUTH: next = cell + 1;        next->incoming = NORTH; break; //向南
    46         case WEST:  next = cell - LABY_MAX; next->incoming = EAST;  break; //向西
    47         case NORTH: next = cell - 1;        next->incoming = SOUTH; break; //向北
    48         default:
    49             next = nullptr;
    50     }
    51     return next;
    52 }
      1 #include <random>
      2 #include <stack>
      3 #include "Cell.h"
      4 using namespace std;
      5 
      6 
      7 
      8 int labySize;
      9 Cell* startCell;
     10 Cell* goalCell;
     11 Cell laby[LABY_MAX][LABY_MAX]; //迷宫
     12 
     13 void randLaby();
     14 void displayLaby();
     15 void printLabyCell(Cell* elem);
     16 bool labyrinth(Cell Laby[LABY_MAX][LABY_MAX], Cell* s, Cell* t);
     17 
     18 int main()
     19 {
     20     randLaby();
     21     labyrinth(laby, startCell, goalCell) ? //启动算法
     22         printf("
    Route founda
    ") :
     23         printf("
    No route founda
    ");
     24     getchar();
     25     return 0;
     26 }
     27 
     28 bool labyrinth(Cell Laby[LABY_MAX][LABY_MAX], Cell* s, Cell* t)//迷宫寻径算法,在起点s和终点t之间寻找一条通路
     29 {
     30     if ((s->status != AVAILABLE) || (t->status != AVAILABLE)) return false;
     31     stack<Cell*> path; //使用栈记录通路
     32     s->incoming = UNKNOWN; s->status = ROUTE;
     33     path.push(s);
     34     do  //从起点出发不断试探、回溯,直到抵达终点,或者穷尽所有可能
     35     {
     36         displayLaby();
     37         getchar();
     38         Cell* c = path.top();
     39         if (c == t) return true; //抵达终点
     40         while (NO_WAY>(c->outgoing= nextESWN(c->outgoing)))
     41         {
     42             Cell* neighborCell = neighbor(c);
     43             if (neighborCell->status == AVAILABLE) break;;
     44         }
     45         if (c->outgoing >= NO_WAY)
     46         {
     47             c->status = BACKTRACKED;
     48             c = path.top(); path.pop(); //回溯一步
     49         }
     50         else //向前试探一步
     51         {
     52             c = advance(c);
     53             path.push(c);
     54             c->outgoing = UNKNOWN;
     55             c->status = ROUTE;
     56         }
     57     } while (!path.empty());
     58     return false;
     59 }
     60 void randLaby() { //生成随机的迷宫
     61     labySize = LABY_MAX / 2 + rand() % (LABY_MAX / 2); /*DSA*/printf("Using a laby of size %d ...
    ", labySize); getchar();
     62     for (int i = 0; i < labySize; i++)
     63         for (int j = 0; j < labySize; j++) {
     64             laby[i][j].x = i;
     65             laby[i][j].y = j;
     66             laby[i][j].incoming =
     67                 laby[i][j].outgoing = UNKNOWN;
     68             laby[i][j].status = WALL; //边界格点必须是墙
     69         }
     70     for (int i = 1; i < labySize - 1; i++)
     71         for (int j = 1; j < labySize - 1; j++)
     72             if (rand() % 4) laby[i][j].status = AVAILABLE; //75%的格点为空可用
     73     startCell = &laby[rand() % (labySize - 2) + 1][rand() % (labySize - 2) + 1];
     74     goalCell = &laby[rand() % (labySize - 2) + 1][rand() % (labySize - 2) + 1];
     75     startCell->status = goalCell->status = AVAILABLE; //起始格点必须可用
     76 }
     77 /******************************************************************************************
     78 *   输出某一迷宫格的信息
     79 ******************************************************************************************/
     80 void printLabyCell(Cell* elem) {
     81     printf("%d -> (%d, %d) -> %d
    ",
     82         ((Cell*)elem)->incoming,
     83         ((Cell*)elem)->x,
     84         ((Cell*)elem)->y,
     85         ((Cell*)elem)->outgoing);
     86 }
     87 
     88 /******************************************************************************************
     89 * 显示迷宫
     90 ******************************************************************************************/
     91 void displayLaby() { //┘└┐┌│─
     92     static char*   pattern[5][5] = {
     93         "", "", "", "", "",
     94         "", "  ", "", "", "",
     95         "", "", "  ", "", "",
     96         "", "", "", "  ", "",
     97         "", "", "", "", "  "
     98     };
     99     system("cls");
    100     printf("  ");
    101     for (int j = 0; j < labySize; j++)
    102         (j < 10) ? printf("%2X", j) : printf(" %c", 'A' - 10 + j);
    103     printf("
    ");
    104     for (int j = 0; j < labySize; j++) {
    105         (j < 10) ? printf("%2X", j) : printf(" %c", 'A' - 10 + j);
    106         for (int i = 0; i < labySize; i++)
    107             if (goalCell == &laby[i][j])
    108                 printf("");
    109             else
    110                 switch (laby[i][j].status) {
    111                 case WALL:  printf("");   break;
    112                 case BACKTRACKED: printf("");   break;
    113                 case AVAILABLE: printf("  ");   break;
    114                 default: printf("%s", pattern[laby[i][j].outgoing][laby[i][j].incoming]);   break;
    115                 }
    116         printf("
    ");
    117     }//for
    118 }//displayLaby

     

  • 相关阅读:
    (转)ASP.NET(C#)FileUpload实现上传限定类型和大小的文件到服务器
    JavaWeb多文件上传及zip打包下载
    使用NeatUpload控件实现ASP.NET大文件上传
    jq+download+文件夹下载
    php大文件下载支持断点续传
    大文件断点上传 js+php
    JavaWeb实现文件上传下载功能实例解析
    【Java】Java批量文件打包下载zip
    Java实现FTP批量大文件上传下载篇1
    PHP之路——大文件上传
  • 原文地址:https://www.cnblogs.com/larry-xia/p/10391673.html
Copyright © 2020-2023  润新知