您的位置:首页 > 其它

一个带拐点搜索的迷宫算法

2008-08-27 16:28 274 查看
#include "stdio.h"
#define maxi 15
#define maxj 15

/*一个普通的迷宫*/
int I_maze[maxi][maxj]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,0,0,0,0,0,1,1,1,0,
0,1,0,0,0,1,1,0,0,0,0,1,0,1,0,
0,1,0,0,0,0,1,1,1,0,0,1,0,1,0,
0,0,0,1,1,1,1,0,0,1,1,1,0,1,0,
0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,
0,1,1,1,1,1,0,0,0,0,0,1,0,1,0,
0,0,0,0,0,1,1,1,1,1,1,1,0,1,0,
0,0,0,0,0,0,1,0,0,0,0,1,0,1,0,
0,0,0,1,1,1,1,0,0,1,1,1,0,1,0,
0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,
0,1,1,1,1,1,0,0,1,1,1,1,1,1,0,
0,1,0,0,0,1,1,0,0,0,0,1,0,0,0,
0,1,0,0,0,0,1,1,1,1,1,1,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,1,0,0,0};

int I_record[maxi][maxj]; /*一个辅助空间,用于记录走过的点*/

int n=0; /*记录能找到出口的能有几条路*/

int lasti[3] = {0,0,0};
int lastj[3] = {0,0,0};

typedef struct Point
{
int x;
int y;
} CPoint;

int Index = 0;
CPoint I_Posrecord[maxi * maxj];

//读取迷宫路径
void findPath(int x, int y)
{
if (x==14 && y==11)
{

I_Posrecord[Index].x = x;
I_Posrecord[Index].y = y;
Index ++;
}
for(int i = 0; i < Index; i++)
{
//该点被访问过;
if(x == I_Posrecord[i].x && y == I_Posrecord[i].y)
return;
}
if(I_record[x][y] == 1)
{
I_Posrecord[Index].x = x;
I_Posrecord[Index].y = y;
Index ++;

findPath(x, y+1);
findPath(x-1, y);
findPath(x+1, y);
findPath(x, y-1);
}
}

//在路径中搜索拐点
int findInflexion(int x, int y)
{
for(int i = 0; i < maxi * maxj; i++)
{
I_Posrecord[i].x = 0;
I_Posrecord[i].y = 0;
}
findPath(x,y);
int iInflexion = 0;
if(Index < 3)
return iInflexion;

for(i = 0; i < Index-2; i++)
{
if(I_Posrecord[i].x != I_Posrecord[i+2].x && I_Posrecord[i].y != I_Posrecord[i+2].y)
{
iInflexion++;
//printf("%d %d/n",I_Posrecord[i+1].x,I_Posrecord[i+1].y);

}

}
Index = 0;
return iInflexion;
}

void Suanfa(int i,int j) /*求解函数*/
{
static int i1,j1;
if (I_maze[i][j]!=0 && I_record[i][j]!=1)
{
I_record[i][j]=1;
if (i==14 && j==11) /*如果找到出口就记录(14,11为出口),并输出*/
{
n++;
for (i1=0;i1 <maxi;i1++)
{
for (j1=0;j1 <maxj;j1++)
{
printf("%d,",I_record[i1][j1]);
}
printf("/n");
}
printf("/n");
int iInflexion = findInflexion(1,0);
printf("拐点数为:%d",iInflexion); //输出拐点数
printf("/n");
}
//find inflexion
//int nCount = findInflexion(i,j);

Suanfa(i,j+1);
//I_record[i][j]=0;
//I_record[i][j]=1;
Suanfa(i+1,j);
//I_record[i][j]=0;
//I_record[i][j]=1;
Suanfa(i-1,j);
//I_record[i][j]=0;
//I_record[i][j]=1;
Suanfa(i,j-1);
I_record[i][j]=0; //回溯
}
}

int main()
{
int i,j;
for (i=0;i <maxi;i++)
for (j=0;j <maxj;j++)
I_record[i][j]=0;
Suanfa(1,0); /*输入起点*/
printf("%d",n);

return 0;
}

基于效率的考虑,我对算法进行了优化:

#include "stdio.h"
#define maxi 15
#define maxj 15

/*一个普通的迷宫*/
int I_maze[maxi][maxj]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,0,0,0,0,0,1,1,1,0,
0,1,0,0,0,1,1,0,0,0,0,1,0,1,0,
0,1,0,0,0,0,1,1,1,0,0,1,0,1,0,
0,0,0,1,1,1,1,0,0,1,1,1,0,1,0,
0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,
0,1,1,1,1,1,0,0,0,0,0,1,0,1,0,
0,0,0,0,0,1,1,1,1,1,1,1,0,1,0,
0,0,0,0,0,0,1,0,0,0,0,1,0,1,0,
0,0,0,1,1,1,1,0,0,1,1,1,0,1,0,
0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,
0,1,1,1,1,1,0,0,1,1,1,1,1,1,0,
0,1,0,0,0,1,1,0,0,0,0,1,0,0,0,
0,1,0,0,0,0,1,1,1,1,1,1,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,1,0,0,0};

int I_record[maxi][maxj]; /*一个辅助空间,用于记录走过的点*/
int n=0; /*记录能找到出口的能有几条路*/

typedef struct Point
{
int x;
int y;
} CPoint;

int Index = 0;
CPoint I_Posrecord[maxi * maxj];

//在路径中搜索拐点
int findInflexion(int x, int y, int Mode)
{
I_Posrecord[Index].x = x;
I_Posrecord[Index].y = y;
Index +=Mode;

if(Mode == -1)
return 0;

int iInflexion = 0;
if(Index < 3)
return iInflexion;

for(int i = 0; i < Index-2; i++)
{
if(I_Posrecord[i].x != I_Posrecord[i+2].x && I_Posrecord[i].y != I_Posrecord[i+2].y)
{
iInflexion++;
//printf("%d %d/n",I_Posrecord[i+1].x,I_Posrecord[i+1].y);
}
}
return iInflexion;
}

void Suanfa(int i,int j) /*求解函数*/
{
static int i1,j1;
if (I_maze[i][j]!=0 && I_record[i][j]!=1)
{
I_record[i][j]=1;
int iInflexion = findInflexion(i,j,1);
if(iInflexion > 13) // 如果大于设定的拐点数,停止搜索
{
I_record[i][j]=0;

findInflexion(0,0,-1);//返回上一个点
return;
}

if (i==14 && j==11) /*如果找到出口就记录(14,11为出口),并输出*/
{
n++;
for (i1=0;i1 <maxi;i1++)
{
for (j1=0;j1 <maxj;j1++)
{
printf("%d,",I_record[i1][j1]);
}
printf("/n");
}

printf("/n");
//int iInflexion = findInflexion(1,0);
printf("拐点数为:%d",iInflexion); //输出拐点数
printf("/n");
}
Suanfa(i,j+1);
//I_record[i][j]=0;
//I_record[i][j]=1;
Suanfa(i+1,j);
//I_record[i][j]=0;
//I_record[i][j]=1;
Suanfa(i-1,j);
//I_record[i][j]=0;
//I_record[i][j]=1;
Suanfa(i,j-1);
I_record[i][j]=0; //回溯
findInflexion(0,0,-1);//返回上一个点
}
}

int main()
{
int i,j;
for (i=0;i <maxi;i++)
for (j=0;j <maxj;j++)
I_record[i][j]=0;
Suanfa(1,0); /*输入起点*/
printf("%d",n);

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