带 DFS 的迷宫求解器

Maze solver with DFS

我正在尝试使用 DFS 解决迷宫问题 algorithm.ORDER:西-北-南-东 我的输出符合这个逻辑 Labyrinth picture1。点(3,3)之后不应该往上走,因为优先顺序是西。我该怎么办?

#include <stdio.h>

char matrix[8][8];

void File()
{
        int i,j;
  

    FILE *file1;
    file1=fopen("maze1.txt","r");
 
    for(i=0; i<8; i++){
        for(j=0;j<8;j++)
        {
        fscanf (file1, " %c", &matrix[i][j]);
        
        printf("%c ",matrix[i][j]);
       }
    printf("\n");
    }
}
void Print()
{
    int i,j;
    for(i=0;i<8;i++)
    {
        for(j=0;j<8;j++)
        {
            printf("%c ",matrix[i][j]);
            }
    printf("\n");       
    }
}
void stepDFS()
{
    int i,j;
    for(i=0;i<8;i++)
    {
        for(j=0;j<8;j++)
        {
            if(matrix[i][j] == 's')
            {
                
                    DFS(i,j);
                        
               
            
            }
            
        }
    printf("\n");       
    }
    
}
 DFS(int i,int j)
{
    if(matrix[i][j-1] == '-')
    {
        matrix[i][j-1] = '.';
        DFS(i,j-1);
    }
     if(matrix[i-1][j] == '-')
    {
        matrix[i-1][j] = '.';
        DFS(i-1,j);
    }
     if(matrix[i+1][j] == '-')
    {
        matrix[i+1][j] = '.';
        DFS(i+1,j);

    }
     if(matrix[i][j+1] == '-')
    {
        matrix[i][j+1] = '.';
       DFS(i,j+1);

    }
    
    
}
int main()
{
    File();
    Print();
    stepDFS();
    Print();
    return 0;
}

maze1.txt (#wall - null.step)

# # # # # # # #  
# g - - # - - #       
# # # - - - # # 
# - # # - - - # 
# - - # - - - #
# - - - - # # # 
# - - # - - s #
# # # # # # # #

输出

# # # # # # # #
# g . . # . . #
# # # . . . # #
# . # # . . . #
# . . # . . . #
# . . . . # # #
# . . # . . s #
# # # # # # # #

我不知道这是否应该是输出

# # # # # # # #  
# g . . # - - #       
# # # . . - # # 
# . # # . - - # 
# . . # . - - #
# . . . . # # # 
# - - # . . s #
# # # # # # # #

-------------更新------------- 一步一步

#include <stdio.h>

char matrix[8][8];

void ReadFile()
{
    printf("\n\n\n                START MAZE    ");
    int x,y;
    FILE *file1;
    file1=fopen("myMaze.txt","r");
 
    for(x=0; x<8; x++){
        for(y=0;y<8;y++)
        {
        fscanf (file1, " %c", &matrix[x][y]);
        
      
       }
    printf("\n");
    }
}



void PrintMaze()
{ 
    int x,y;
    for(x=0;x<8;x++)
    {
        printf("                ");
        for(y=0;y<8;y++)
        {
             
            printf(" %c ",matrix[x][y]);
        }
     
    printf("\n");       
    }
    printf("\n\n\n\n");
}
  
  
int DFS(int x,int y){
 

 
    if(matrix[x][y]=='g') // goal
    {
        return 1;
    }
      if(matrix[x][y-1] == '-' ){ //WEST
           

        
        matrix[x][y-1] = '.';
        PrintMaze();
        
        
        if(DFS(x,y-1)){
            
            matrix[x][y-1] ='.'; 
            PrintMaze();
            
            return 1;
        }
        else{
            DFS(x,y-1);
            return 0;
        
         }
         DFS(x,y-1);
      

     }
      if(matrix[x-1][y] == '-'){  //NORTH
       
   
        matrix[x-1][y] = '.';
        PrintMaze();
        
        if(DFS(x-1,y)){
            
            matrix[x-1][y] = '.';
            PrintMaze();
            
            return 1;
        }
        else{
            DFS(x-1,y);
            return 0;
        }
     
         DFS(x-1,y);
    

     }
    
    
 
    
    
    
       if(matrix[x+1][y] == '-'){ //SOUTH
             
     
        matrix[x+1][y] = '.';
        PrintMaze();
        
        if(DFS(x+1,y)){
            
           matrix[x+1][y] ='.'; 
           PrintMaze();
            
            return 1;
            
        }
        else{
          DFS(x+1,y);
            return 0;
        }
        
        DFS(x+1,y);
 
    }  
  
    
           if(matrix[x][y+1] == '-'){     //EAST
          

        matrix[x][y+1] = '.';
       
        if(DFS(x,y+1)){
            
        matrix[x][y+1] = '.'; 
        PrintMaze();
          
            return 1;
        }
        else{
            DFS(x,y+1);
            return 0;
        }
        
        DFS(x,y+1);
    
    }
    
 

    return 0;


}


void StartSearch()
{ 
    printf("                  STEP BY STEP");

    int x,y;

 
    for(x=0;x<8;x++)
    {
        for(y=0;y<8;y++)
        {
            if(matrix[x][y] == 's')//start
            {
              DFS(x,y);
 
             }
        }
        
    printf("\n");  
         
    }
 
}
 
int main()
{
    ReadFile();
    
    PrintMaze();
    
    StartSearch();
    
    PrintMaze();
    
    return 0;
}

myMaze.txt

# # # # # # # #  
# g - - # - - #       
# # # - - - # # 
# - # # - - - # 
# - - # - - - #
# - - - - # # # 
# - - # - - s #
# # # # # # # #

DFS 确定方向时首先考虑 function.Other 方向内的条件。

首先,启用并注意编译器的警告! (对于 gcc,我使用 -Wall -Wextra -pedantic)。你已经被告知了这一点。当编译器可以为您解答您的问题时,为什么还要来 SO!

DFS(int i,int j) 表示 int DFS(int i,int j),但您打算使用 void DFS(int i,int j)。 (不过,这不是您所需要的。您已经拥有了您所需要的。)


接下来,让我们确定预期的输出,因为您不确定。这个迷宫有五个解决方案(忽略无意义地访问一个单元格两次的解决方案)。

Length = 9
# # # # # # # #
# g . . # - - #
# # # . . - # #
# - # # . - - #
# - - # . - - #
# - - - . # # #
# - - # . . s #
# # # # # # # #

Length = 11
# # # # # # # #        # # # # # # # #
# g . . # - - #        # g . . # - - #
# # # . . - # #        # # # . . . # #
# - # # . . - #        # - # # - . - #
# - - # . . - #        # - - # . . - #
# - - - . # # #        # - - - . # # #
# - - # . . s #        # - - # . . s #
# # # # # # # #        # # # # # # # #

Length = 13
# # # # # # # #        # # # # # # # #
# g . . # - - #        # g . . # - - #
# # # . . - # #        # # # . . . # #
# - # # . . . #        # - # # - . . #
# - - # . . . #        # - - # . . . #
# - - - . # # #        # - - - . # # #
# - - # . . s #        # - - # . . s #
# # # # # # # #        # # # # # # # #

其中任何一个都是有效的输出。显然,第一条路径比其他两条路径短,但 DFS 不会(必然)找到最短路径。 (你需要一个 BFS。)


关于问题。

你有两个问题:

  • 您正在标记您访问过的每个单元格,无论它是否是路径的一部分。
  • 您永远不会停止搜索,因此您最终会访问每个可到达的单元格。

为了解决这两个问题,需要做一个重要的改变。 DFS 需要 return 由其参数标识的单元格是否是路径的一部分。

如果单元格是路径的一部分,

DFS 应该 return 1,如果不是,则 0

那么你怎么知道单元格是否是路径的一部分?

  • 如果当前单元格是 g,则当前单元格是路径的一部分。
  • 如果北方的单元格是路径的一部分(即如果 DFS(y-1,x) return 为真值),则当前单元格是路径的一部分。
  • 如果南边的单元格是路径的一部分(即,如果 DFS(y+1,x) return 为真值),则当前单元格是路径的一部分。
  • 如果西边的单元格是路径的一部分(即如果 DFS(y,x-1) return 为真值),则当前单元格是路径的一部分。
  • 如果东边的单元格是路径的一部分(即如果 DFS(y,x+1) return 为真值),则当前单元格是路径的一部分。
  • 否则,单元格不是路径的一部分。

问题 #2:找到解决方案后您继续搜索。

只要您知道单元格是路径的一部分,DFS 就应该 return。立即地。如果北边的单元格是路径的一部分,请不要继续检查南边的节点!


问题 #1:您正在标记您访问过的每个单元格

当您输入 DFS 时,您通过将单元格设置为 . 将其标记为路径的一部分。这很好,因为它可以防止无限循环。

但它可能最终不会成为路径的一部分。 ,如果发现它不是路径的一部分,则需要将其值恢复为-