您的位置:首页 > 编程语言 > PHP开发

用动态规划优化老鼠走迷宫中的最短路线解法

2012-01-30 11:29 246 查看
#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;

b7db
#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);
}


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