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

来源:互联网 发布:淘宝买家提高好评率 编辑:程序博客网 时间:2024/04/28 00:31

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

原创粉丝点击