用動態規劃優化老鼠走迷宮中的最短路線解法

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <dos.h>
#include <time.h>
#ifdef _WIN32
   #include <windows.h>
#endif

#ifndef STRICT
   #define STRICT 1
#endif

/* 宏DYNAMIC-是否開啓動態規劃 */
#define DYNAMIC       1

#define DISOPTI1      1
/* 宏DISPROCEDURE-是否動態演示搜索過程 */
#define DISPROCEDURE  1
/* 宏FULLNULL-是否全空 */
#define FULLNULL1     1
/* 宏_RANDOM_-是否使用隨機數據 */
#define _RANDOM_      1
/* 宏WAITPRESSKEY-等待按鍵 */
#define WAITPRESSKEY1  1

#define MOUSEMAZE1 1
#define MOUSEMAZE2 1

#ifdef MOUSEMAZE1
#define XSIZE1 75
#define YSIZE1 22
#define XSIZE  XSIZE1
#define YSIZE  YSIZE1

#ifdef _WIN32
   void gotoxy(int x, int y);
#else
   void cursor(unsigned int mode);
#endif
void visit(int x, int y);
void disresult(void);

char maze[YSIZE1][XSIZE1] =
 {{2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
  {2,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,0,2,0,2,0,0,2,2,0,2,2,0,2,0,2,0,2,2,2,0,0,2,0,2,2,0,2,0,2,2,0,2},
  {2,0,2,0,2,0,2,0,0,2,0,0,2,2,0,2,2,2,0,2,2,2,0,0,2,0,0,0,2,2,0,2,0,2,2,2,0,2,2,2,0,0,0,0,0,0,2,2,0,0,2,0,0,0,0,0,0,0,2,0,2,0,0,0,2,0,0,0,2,2,0,0,0,2,2},
  {2,0,2,0,0,0,2,0,0,0,0,2,2,2,2,2,2,0,0,0,0,0,0,2,2,0,0,0,0,2,2,2,0,0,0,2,0,2,0,0,0,0,0,2,2,0,0,2,2,2,2,2,2,0,0,2,0,0,0,2,2,0,0,0,0,0,2,2,0,0,0,2,2,0,2},
  {2,0,2,0,2,0,2,0,2,0,2,2,0,0,0,0,0,0,2,2,0,0,0,0,0,0,2,2,0,0,0,0,2,2,0,2,0,0,0,2,0,2,0,0,2,2,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,0,2,0,0,2,2,0,0,0,2,2,2,0,2},
  {2,0,2,0,2,0,2,0,2,0,0,2,2,0,2,2,0,2,2,2,0,2,2,2,0,0,2,0,0,0,2,2,0,0,0,0,2,0,0,0,2,0,2,0,0,0,2,2,0,0,2,2,0,0,2,0,0,0,0,2,2,0,0,2,2,0,2,2,0,0,0,0,0,0,2},
  {2,0,2,0,2,0,2,0,2,0,0,0,0,0,2,2,0,2,0,0,0,0,2,0,2,0,0,2,2,0,2,2,0,2,2,2,0,2,2,0,0,0,2,2,2,0,0,2,2,0,0,2,0,0,0,2,0,0,2,0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,2},
  {2,0,2,0,2,0,0,0,0,0,0,2,2,0,0,0,0,2,2,2,2,0,0,2,0,0,2,0,2,2,0,0,0,0,2,0,0,2,0,2,0,0,0,0,2,2,0,2,2,0,0,0,0,0,2,0,2,0,0,0,0,0,0,2,2,0,2,2,0,2,0,2,2,0,2},
  {2,0,2,0,2,0,2,0,2,0,0,2,2,0,2,2,0,0,0,0,0,2,2,2,0,2,0,2,0,0,2,0,0,2,2,0,2,2,2,2,0,2,2,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,0,2,0,2,0,0,0,0,2,2,0,0,0,2,0,0,2},
  {2,0,2,0,2,0,2,0,2,2,0,2,0,2,0,0,2,0,2,0,2,0,0,0,0,2,0,2,0,0,2,2,0,2,2,0,2,2,0,2,2,0,0,0,0,2,0,0,0,2,0,0,2,0,0,2,2,2,0,0,2,0,2,0,0,2,0,0,0,0,2,0,0,2,2},
  {2,0,0,0,0,0,0,0,0,2,0,2,0,0,2,0,0,0,2,0,2,0,0,0,2,0,2,0,0,0,2,0,2,2,0,0,0,0,0,2,2,2,0,2,2,0,0,2,0,0,0,0,2,0,0,2,2,2,2,0,0,2,0,0,2,0,2,0,2,0,0,2,2,0,2},
  {2,0,2,0,2,0,2,0,2,0,0,2,2,0,2,2,0,2,2,0,2,2,0,0,0,0,0,0,2,0,0,0,2,0,0,0,2,0,2,2,0,0,2,0,2,0,0,2,2,0,0,0,0,0,0,2,2,2,0,2,2,0,2,0,0,0,0,2,0,2,0,2,2,0,2},
  {2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,0,0,2,2,0,2,2,0,2,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,2,2,0,2,2,2,2,0,2,2,2,0,0,0,2,0,0,2,0,0,2,2,0,0,0,2,0,0,2},
  {2,0,0,0,2,0,2,0,2,0,2,0,2,0,2,0,0,0,0,0,2,2,0,0,0,0,2,2,0,0,0,0,0,0,0,2,0,2,0,0,0,0,0,2,0,0,2,0,2,0,2,0,0,0,2,2,0,0,0,0,2,0,0,0,0,0,0,2,0,0,2,0,0,0,2},
  {2,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,2,0,2,0,2,0,2,2,0,2,2,0,2,0,2,0,0,2,0,0,0,2,2,0,0,2,0,2,0,2,0,0,0,0,0,0,0,0,0,2,0,0,2,0,2,2,2,2,2,0,2,0,0,0,2,0,2,2},
  {2,2,2,2,2,0,0,0,2,2,0,2,0,0,2,0,2,0,0,0,2,0,0,0,0,0,0,0,2,0,0,2,2,2,0,0,2,2,0,0,0,0,0,0,2,0,0,2,0,2,0,0,0,2,2,2,0,0,0,2,0,0,2,0,0,2,0,0,2,0,2,0,0,0,2},
  {2,2,0,2,2,0,2,0,0,0,0,2,0,0,2,0,0,0,2,0,0,0,2,0,2,0,2,0,0,0,2,0,2,2,0,0,0,0,2,0,0,2,0,2,0,2,0,0,0,0,2,2,0,2,0,0,0,2,0,0,0,2,0,0,0,2,0,2,0,2,0,2,0,2,2},
  {2,2,0,0,0,0,0,0,2,2,0,2,0,0,0,0,2,0,2,0,2,0,0,2,2,0,2,2,0,2,0,2,2,0,0,2,2,0,0,0,0,0,2,0,0,0,0,2,0,2,0,0,0,0,2,0,0,0,2,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,2},
  {2,0,0,2,2,0,0,0,0,2,0,0,0,0,2,0,0,0,0,2,0,0,2,0,2,0,2,0,0,0,0,0,0,2,0,0,0,2,2,2,2,0,2,2,0,0,2,0,0,2,0,2,0,0,0,2,0,2,0,0,0,0,2,0,2,0,2,0,2,0,2,0,2,0,2},
  {2,0,0,0,2,0,2,0,2,2,0,2,0,0,0,0,0,0,2,0,0,0,2,0,2,0,0,0,2,0,0,0,2,0,2,0,2,2,2,2,0,0,2,0,2,0,2,2,0,2,0,2,0,2,2,0,0,2,0,2,0,2,0,0,0,0,0,2,0,2,0,0,0,0,2},
  {2,0,2,0,0,0,0,0,2,2,0,2,0,0,0,2,0,2,0,2,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,2,0,0,0,0,2,2,0,0,0,0,0,0,0,0,2,0,0,2,0,0,2,0,2,0,2,0,0,2,2,0,0,0,0,0,0,0,0,2},
  {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}};  
#else
#ifdef MOUSEMAZE2
#define XSIZE 20
#define YSIZE 15
char maze[YSIZE][XSIZE] =
 {{2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
  {2,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,2,0,2},
  {2,0,2,0,2,0,0,0,2,2,0,2,0,2,0,0,0,2,0,2},
  {2,0,2,0,0,2,0,2,0,0,0,0,0,2,2,2,0,2,2,2},
  {2,0,2,0,2,0,2,0,0,2,0,0,2,0,2,0,0,0,0,2},
  {2,0,2,0,2,2,0,0,2,0,0,2,0,0,2,2,0,2,0,2},
  {2,0,0,0,2,2,0,0,0,2,2,0,0,0,2,0,2,2,0,2},
  {2,0,0,0,0,2,2,2,0,2,0,2,0,2,0,2,0,2,0,2},
  {2,0,2,0,2,0,2,0,0,0,2,2,2,0,2,0,0,0,0,2},
  {2,0,2,0,0,2,2,2,0,0,0,0,0,2,2,2,0,2,2,2},
  {2,0,2,0,2,0,2,0,2,2,2,2,0,0,0,0,0,2,0,2},
  {2,0,2,0,2,2,0,0,0,0,0,2,0,2,0,2,0,2,0,2},
  {2,0,0,0,2,2,0,0,0,2,0,0,0,0,0,2,0,0,0,2},
  {2,0,2,0,0,0,0,0,2,0,0,0,2,2,2,0,2,0,0,2},
  {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}};
#else
#define XSIZE 9
#define YSIZE 9
char maze[YSIZE][XSIZE] =
 {{2,2,2,2,2,2,2,2,2},
  {2,0,0,0,0,0,0,0,2},
  {2,0,2,0,2,0,2,0,2},
  {2,0,2,0,0,0,2,0,2},
  {2,0,2,0,2,0,2,0,2},
  {2,0,2,0,2,2,2,0,2},
  {2,0,2,0,2,2,2,0,2},
  {2,0,2,0,2,2,2,0,2},
  {2,2,2,2,2,2,2,2,2}};
#endif
#endif

const int top = 2;
const int left = 3;
int startx = 1, starty = 1;              /* 入口 */
int endx = XSIZE - 2, endy = YSIZE - 2;  /* 出口 */
int success = 0;

#ifdef DYNAMIC
  int routearray[YSIZE][XSIZE];
#endif
int minlength = RAND_MAX;
int routelength = 0;
int minroutes[XSIZE * YSIZE][2];
int routes[XSIZE * YSIZE][2];

#ifdef _WIN32
   #define WALLCODE 'X'

   HANDLE hOut;

   void gotoxy(int x, int y)
   {
    COORD pos;
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(hOut, pos); /* 設置光標位置 */
   }
#else
   #define WALLCODE 219

   void cursor(unsigned int mode)
   {
    union REGS r;
    r.h.ah = 0x01;
    if (mode %= 3)
     {
      r.h.cl = 7;
      r.h.ch = mode == 1 ? 6 : 0;
     }
    else
     r.x.cx = 0x2020;
    int86(0x10, &r, &r);
   }
#endif

int main(void)
{
 int i, j, k;

#ifdef _WIN32
   hOut = GetStdHandle(STD_OUTPUT_HANDLE);
#else
   cursor(0);
#endif

 srand((unsigned)time(NULL));
 for (i = 0; i < YSIZE; i++)
  {
   for (j = 0; j < XSIZE; j++)
    {
     #ifdef FULLNULL
       if (i != 0 && j != 0)
        maze[i][j] = 0;
     #else
       #ifdef _RANDOM_
         if (i != 0 && j != 0)
          maze[i][j] = ((rand() % 10) < 3) ? 2 : 0;
       #endif
     #endif
     maze[YSIZE - 1][j] = 2;
     gotoxy(j + left, i + top);
     if (maze[i][j] != 0)
      printf("%c", WALLCODE);
     else
      printf(" ");

     #ifdef DYNAMIC
       routearray[i][j] = RAND_MAX;
     #endif
    }
   maze[i][XSIZE - 1] = 2;
   gotoxy(XSIZE - 1 + left, i + top);
   printf("%c", WALLCODE);
  }
 maze[starty][startx] = 0;
 maze[endy][endx] = 0;
 gotoxy(startx + left, starty + top);
 printf("S");
 gotoxy(endx + left, endy + top);
 printf("E");

 /* 多次搜索標記死角,直到找不到爲止 */
 k = 1;
 while(k)
  {
   k = 0;
   for (i = starty; i <= endy; i++)
    {
     for (j = startx; j <= endx; j++)
      {
       if (maze[i][j] == 0 && (!(j == startx && i == starty)) && (!(j == endx && i == endy)))
        {
         if (maze[i - 1][j] != 0 && maze[i][j + 1] != 0 && maze[i + 1][j] != 0)
          {
           maze[i][j] = 3;
           k = 1;
           #ifdef DISOPTI
             gotoxy(j + left, i + top);
             printf("c");
           #endif
          }
         else if (maze[i][j + 1] != 0 && maze[i + 1][j] != 0 && maze[i][j - 1] != 0)
          {
           maze[i][j] = 3;
           k = 1;
           #ifdef DISOPTI
             gotoxy(j + left, i + top);
             printf("c");
           #endif
          }
         else if (maze[i + 1][j] != 0 && maze[i][j - 1] != 0 && maze[i - 1][j] != 0)
          {
           maze[i][j] = 3;
           k = 1;
           #ifdef DISOPTI
             gotoxy(j + left, i + top);
             printf("c");
           #endif
          }
         else if (maze[i][j - 1] != 0 && maze[i - 1][j] != 0 && maze[i][j + 1] != 0)
          {
           maze[i][j] = 3;
           k = 1;
           #ifdef DISOPTI
             gotoxy(j + left, i + top);
             printf("c");
           #endif
          }
        }
      }
    }
  }

 getch();

 visit(startx, starty);

 if (success)
  disresult();

 getch();

#ifdef _WIN32
   CloseHandle(hOut); 
#endif
}

void visit(int x, int y)
{
 maze[y][x] = 1;

 #ifdef DISPROCEDURE
   gotoxy(x + left, y + top);
   printf("o");
 #endif

 routes[routelength][0] = x;
 routes[routelength++][1] = y;

 #ifdef DYNAMIC
   if (routearray[y][x] <= routelength)
    {
     #ifdef _WIN32
       #ifdef DISPROCEDURE
         gotoxy(x + left, y + top);
         printf(".");
       #endif
     #else
       #ifdef DISPROCEDURE
         gotoxy(x + left, y + top);
         textcolor(7);
         cprintf(".");
       #endif
     #endif

     maze[y][x] = 0;
     routelength--;
     return;
    }
   else
    {
     #ifdef _WIN32
       #ifdef DISPROCEDURE
         gotoxy(x + left, y + top);
         printf("+");
       #endif
     #else
       #ifdef DISPROCEDURE
         textcolor(14);
         gotoxy(x + left, y + top);
         cprintf("+");
       #endif
     #endif
     routearray[y][x] = routelength;
    }
 #endif

 if (y == endy && x == endx)
  {
   success = 1;
   if (kbhit() != 0)
    {
     if (getch() == 27)
      exit(0);
    }

   if (routelength < minlength)
    {
     int i;
     minlength = routelength;

     for (i = 0; i < routelength; i++)
      {
       minroutes[i][0] = routes[i][0];
       minroutes[i][1] = routes[i][1];
      }
    }

   #ifdef DISPROCEDURE
     gotoxy(x + left, y + top);
     printf(" ");
   #endif
   #ifdef WAITPRESSKEY
     getch();
   #endif
   maze[y][x] = 0;
   routelength--;
   return;
  }

 if (maze[y + 1][x] == 0)
  visit(x, y + 1);
 if (maze[y][x + 1] == 0)
  visit(x + 1, y);
 if (maze[y - 1][x] == 0)
  visit(x, y - 1);
 if (maze[y][x - 1] == 0)
  visit(x - 1, y);

 #ifdef DISPROCEDURE
   gotoxy(x + left, y + top);
   printf(" ");
 #endif

 maze[y][x] = 0;
 routelength--;
}

void disresult(void)
{
 int i, j;

 for (i = 0; i < YSIZE; i++)
  {
   for (j = 0; j < XSIZE; j++)
    {
     gotoxy(j + left, i + top);
     if (maze[i][j] == 2)
      printf("%c", WALLCODE);
     else
      printf(" ");
    }
  }

 #ifndef _WIN32
   textcolor(7);
 #endif
 for (i = 0; i < minlength; i++)
  {
   gotoxy(minroutes[i][0] + left, minroutes[i][1] + top);
   #ifdef _WIN32
     printf("o");
   #else
     cprintf("o");
   #endif
  }
 gotoxy(1, 1);
 printf("%d", minlength);
}

 
發佈了29 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章