【问题标题】:Shortest path to any point in a maze到迷宫中任意一点的最短路径
【发布时间】:2020-01-21 14:31:33
【问题描述】:

所以我必须扫描迷宫般的行数和列数来查找文件,我明白了那部分。

文件有这样的格式

3
4
....
.#.#
....

第一个数字是行数,第二个是列数。字符“#”是一堵墙,我不能去那里,但我可以穿过“。” 现在我必须使用结构和指针找到通往迷宫中任意点的最短路径。示例结构在我的代码(单元格)中。

我不知道该怎么做。我创建了一个“已访问”数组来跟踪我去过的单元格并检查一个点是否有效。

不知何故,我必须指向北、西、东、南方向的其他点。

#include "stdafx.h"
#include "stdlib.h"

//Starting point
#define START_X 0
#define START_Y 0

//example structure I have to use
struct Cell
{
    struct Cell *north;
    struct Cell *east;
    struct Cell *south;
    struct Cell *west;
    char value;
    int distance;
};

//function that prints a maze
void printMap(char **charMaze, int row, int col)
{

    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {
            printf_s("%c", charMaze[i][j]);
        }
        printf_s("\n");
    }

}

// functions that check if a point is valid
bool isValid(int x, int y, int row, int col)
{
    if (x < row && y < col && x >= 0 && y >= 0)
        return true;

    return false;
}

bool isSafe(char **charMaze, int **visited, int x, int y)
{
    if (charMaze[x][y] == '#' || visited[x][y]==true)
        return false;

    return true;
}

//My attempt at solving this
int BFS(char **maze,int END_X, int END_Y,int row, int col, bool **visited)
{
    isValid(END_X, END_Y, row, col);    
}

int main()
{

    FILE *map;
    int row, col;

    // I open a file with a maze
    fopen_s(&map, "test1.txt", "r");
    // I scan a row number and column number
    fscanf_s(map, "%d", &row);
    fscanf_s(map, "\n%d\n", &col);

    char** charMaze;
    charMaze = (char**)malloc(row * sizeof(char*));

    for (int i = 0; i < row; i++)
        charMaze[i] =(char*)malloc(col * sizeof(char));

    bool** visited;
    visited = (bool**)malloc(row * sizeof(bool*));

    for (int i = 0; i < row; i++)
        visited[i] = (bool*)malloc(col * sizeof(bool));
    //set staring point as true and other points as false
    visited[START_X][START_Y] = true;
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {
            visited[i][j] = false;
        }
    }
    // I scan a maze and I put it in a array
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {
            fscanf_s(map, "%c", &charMaze[i][j],1);
        }
        fscanf_s(map, "\n");
    }

    fclose(map);
    //printMap(charMaze, row, col);

    return 0;

}

【问题讨论】:

    标签: c file pointers structure maze


    【解决方案1】:

    您可以使用Dijkstra algorithm 来查找最短路径。

    因此,假设您必须返回从起点到迷宫中每个点的路径。

    您有here Dijkstra 算法的实现。

    您需要根据迷宫地图对其进行调整。

    您可以使用结构矩阵,其中每个结构包含前一个节点的 x,y 坐标、到起始节点的距离以及完成的标志。

    编辑

    事实上,你甚至不需要实现 Dijkstra 算法。一个简单的泛洪算法就可以了,因为图的所有顶点的权重都是 1。

    我会这样做。

    #include <stdbool.h>
    #include <stdlib.h>
    
    
    enum State { Wall, Unvisited, WaveBorder, NewWaveBorder, Done };
    
    // define the structure holding coordinates of previous cell in path and state
    typedef struct Cell {
        int i,j; // coordinates of predecessor in path
        enum State state;
    } Cell; 
    
    // visit cell (vi,vj) from neighbor cell (i,j)
    void visitCell(Cell **m, int vi, int vj, int i, int j) {
        if m[vi][vj].state == Unvisited {
            m[vi][vj].state = NewWaveBorder;
            m[vi][vj].i = i;  
            m[vi][vj].j = j;
        }
    }
    
    Cell** findShortestPath(char **maze, int row, int col, int iStart, int jStart) {
        Cell **m = malloc(sizeof(Cell*)*row);
        for (int i = 0; i < row; i++)
            m[i] = malloc(sizeof(Cell)*col);
        for (int i = 0; i < row; i++)
            for (int j = 0; j < col; j++)
                if (maze[i][j] == '.') {
                    m[i][j].state = Unvisited;
                    m[i][j].i = m[i][j].j = -1;
                } else {
                    m[i][j].state = Wall;
                    m[i][j].i = m[i][j].j = -2;
                }
    
        m[iStart][jStart].state = WaveBorder;
        bool done = false;
        while (!done) {
            for (int i = 0; i < row; i++)
                for (int j = 0; j < col; j++) {
                    if (m[i][j].state != waveBorder)
                        continue;
                    if (i > 0)
                        visitCell(m, i-1, j, i, j);
                    if (j > 0)
                        visitCell(m, i, j-1, i, j);
                    if (i < row)
                        visitCell(m, i+1, j, i, j);
                    if (j < col)
                        visitCell(m, i, j+1, i, j);
                    m[i][j].state = Done;
                }
            done = true;
            for (int i = 0; i < row; i++)
                for (int j = 0; j < col; j++)
                    if (m[i][j].state == Unvisited)
                        done = false;
                    else if (m[i][j].state == NewWaveBorder)
                        m[i][j].state == WaveBorder;
        }
        return m;
    }
    

    来自单元格 (i,j) 的路径存储在Cell 结构的矩阵中。每个单元格在通往 (iStart, jStart) 的路径中都有前一个单元格的坐标。单元格 (iStart,jStart) 将 (-1,-1) 作为路径中的前任。墙将有 (-2,-2) 作为前辈。

    【讨论】:

    • 哦,我想我会试试的。但我不知道这个结构会是什么样子。我怎样才能使我的迷宫适应 dijkstra 算法?
    • 没有必要调整你的迷宫。您只需要第二个矩阵来跟踪路径、距离和已完成的单元格。距离只是到一个相邻的小区,是一。
    • @Glitterfrost 我提供了一个建议的解决方案来构建最短路径矩阵。我没测试,但应该没问题。
    • @chmike malloc() 是否需要 free() 才能从函数返回?
    • @EsmaeelE 不,free 不需要,因为函数返回结构矩阵。
    【解决方案2】:

    好的,我做了这样的事情。但是由于某种原因它不起作用。

    #include "stdafx.h"
    #include "stdlib.h"
    
    //Starting point
    #define START_X 0
    #define START_Y 0
    #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
    
    //example structure I have to use
    struct Cell
    {
        struct Cell *north;
        struct Cell *east;
        struct Cell *south;
        struct Cell *west;
        char value;
        int distance;
    
    
    };
    
    
    //function that prints a maze
    void printMap(char **charMaze, int row, int col)
    {
    
        for (int i = 0; i < row; i++)
        {
    
            for (int j = 0; j < col; j++)
            {
                printf_s("%c", charMaze[i][j]);
            }
            printf_s("\n");
        }
    
    }
    
    void printMap2(int **intMaze, int row, int col)
    {
    
        for (int i = 0; i < row; i++)
        {
    
            for (int j = 0; j < col; j++)
            {
                printf_s("%d", intMaze[i][j]);
            }
            printf_s("\n");
        }
    
    }
    
    // functions that check if a point is valid
    bool isValid(int x, int y, int row, int col)
    {
        if (x < row && y < col && x >= 0 && y >= 0)
        {
    
            printf("Dobry punkt");
            return true;
        }
        else
        {
            printf("Nieprawidlowy");
        }
    
        return false;
    }
    
    bool isSafe(char **charMaze, int **visited, int x, int y)
    {
        //char wall = '#';
        //char character = charMaze[x][y];
        if (charMaze[x][y] =='#' || visited[x][y])
        {
    
            printf("unsafe");
            return false;
        }
        else
        {
            printf("safe");
        }
    
        return true;
    }
    
    bool canGo(Cell *cell, int d)
    {
        if (cell == NULL)
        {
            return 0;
        }
        if (cell->value == '#')
            return 0;
        if (cell->value == '.')
            return 1;
        if (cell->distance > d)
            return 1;
    
            return 0;
    }
    
    void findShortestPath(char **maze, int start_X, int start__Y, int i, int j, int row, int col, int **visited, int minDist, int dist)
    {
        if (j = start__Y && i == start_X)
        {
            minDist = MIN(dist, minDist);
            return;
        }
        visited[start_X][start__Y] = 1;
    
        //bottom
        if (isValid(start_X + 1, start__Y, row, col) && isSafe(maze, visited, start_X + 1, start__Y))
            findShortestPath(maze, start_X + 1, start__Y, i, j, row, col, visited, minDist, dist + 1);
        //right
        if (isValid(start_X, start__Y + 1, row, col) && isSafe(maze, visited, start_X, start__Y + 1))
            findShortestPath(maze, start_X, start__Y + 1, i, j, row, col, visited, minDist, dist + 1);
        //top
        if (isValid(start_X - 1, start__Y, row, col) && isSafe(maze, visited, start_X + 1, start__Y))
            findShortestPath(maze, start_X + 1, start__Y, i, j, row, col, visited, minDist, dist + 1);
        //left
        if (isValid(start_X, start__Y - 1, row, col) && isSafe(maze, visited, start_X, start__Y - 1))
            findShortestPath(maze, start_X, start__Y - 1, i, j, row, col, visited, minDist, dist + 1);
        visited[start_X, start__Y] = 0;
    
    }
    
    int main()
    {
        FILE *map;
        int start_X = 0;
        int start_Y = 0;
        int row, col;
        struct Cell cell;
        // I open a file with a maze
        fopen_s(&map, "test1.txt", "r");
        // I scan a row number and column number
        fscanf_s(map, "%d", &row);
        fscanf_s(map, "\n%d\n", &col);
    
    
        char** charMaze;
        charMaze = (char**)malloc(row * sizeof(char*));
    
        for (int i = 0; i < row; i++)
            charMaze[i] = (char*)malloc(col * sizeof(char));
    
        int** visited;
        visited = (int**)malloc(row * sizeof(int*));
    
        for (int i = 0; i < row; i++)
            visited[i] = (int*)malloc(col * sizeof(int));
    
        memset(visited, 0, sizeof visited);
        int minDist = INT_MAX;
    
        // I scan a maze and I put it in a array
        for (int i = 0; i < row; i++)
        {
    
            for (int j = 0; j < col; j++)
            {
                fscanf_s(map, "%c", &charMaze[i][j], 1);
            }
            fscanf_s(map, "\n");
        }
    
        findShortestPath(charMaze, start_X, start_Y, 2, 3, row, col, visited, minDist, 0);
    
        if (minDist != INT_MAX)
        {
            printf("Najkrotsza droga z poczatku do konca to %d", minDist);
    
        }
        else
        {
            printf("Can't get to the point");
        }
    
    
        printMap(charMaze, row, col);
    
        fclose(map);
    
    return 0;
    
    }
    

    【讨论】:

      猜你喜欢
      • 2018-03-24
      • 1970-01-01
      • 1970-01-01
      • 2012-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-27
      相关资源
      最近更新 更多