迷宫中任意点的最短路径

时间:2020-01-21 14:31:33

标签: c file pointers structure maze

所以我必须扫描迷宫中的行和列数来寻找文件,一点点我都知道了。

文件的格式如下

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

}

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

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

我不得不以其他方式指向北,西,东,南方向。

    [Authorize]
    [HttpGet]
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    [Route("api/Infra/GetEmpresas/{system}")]
    public HttpResponseMessage GetCompanies(string system)
    {
        logger.Debug("Start GetCompanies");
        HttpResponseMessage response = new HttpResponseMessage();
        try
        {
            if (!String.IsNullOrEmpty(system))
            {
                Companies comps = new Companies();
                var result = comps.GetCompanies(system);

                if (result != string.Empty)
                {
                    if (result.ToLower().StartsWith("error"))
                    {
                        response.StatusCode = HttpStatusCode.NotFound;
                        response.Content = new StringContent(
                            "{\"error\":\"" + result + "\"}", System.Text.Encoding.UTF8, "application/json");
                    }
                    else
                    {
                        response.Content = new StringContent(
                        result, System.Text.Encoding.UTF8, "application/json");
                    }
                }
                else
                {
                    response.StatusCode = HttpStatusCode.NotFound;
                    response.Content = new StringContent(
                        "{\"error\":\"Company not found\"}", System.Text.Encoding.UTF8, "application/json");
                }
            }
            else
            {
                response.StatusCode = HttpStatusCode.NotFound;
                response.Content = new StringContent(
                    "{\"error\":\"System was not provided\"}", System.Text.Encoding.UTF8, "application/json");
            }
        }
        catch (Exception exx)
        {
            logger.Error("Error on GetCompanies");
            logger.Error(exx);
            response.StatusCode = HttpStatusCode.InternalServerError;
            response.Content = new StringContent(
                "{\"error\":\"Error on GetCompanies\"}", System.Text.Encoding.UTF8, "application/json");
        }
        return response;
    }

2 个答案:

答案 0 :(得分:0)

您可以使用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结构的矩阵中。每个单元格在朝向(iStartjStart)的路径中具有前任的坐标。单元格(iStartjStart)在路径中将具有(-1,-1)作为前身。墙将具有(-2,-2)作为前身。

答案 1 :(得分:0)

好的,我做了这样的事情。但这由于某些原因无法正常工作。

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

}