简体   繁体   English

迷宫般的回溯

[英]Maze-like backtracking

So, I'm trying to make a maze solver with given (X, Y) coordinates of start and end positions, but I have a condition: everytime it goes from one point to another it should check if the new position is lower than the previous (a[x][y] <= some_height_variabile). 因此,我试图使用给定的(X,Y)起始和结束位置坐标来制作迷宫求解器,但是我有一个条件:每次从一个点到另一个点时,都应检查新位置是否低于该位置。前一个(a [x] [y] <= some_height_variabile)。 Here is my code so far: 到目前为止,这是我的代码:

#include <stdio.h>

#define N 4

int a[N][N] = 
{
    {35, 75, 80, 12}, 
    {13, 12, 11, 3}, 
    {32, 9, 10, 8}, 
    {12, 2, 85, 1}
};

int sol[N][N];

int h, k, count;
int end_x = -1, end_y = -1;
int start_x = -1, start_y = -1;

void print()
{
    int i, j;

    for (i = 0; i < N; i++)
    {
        for (j = 0; j < N; j++)
        {
            if (sol[i][j] > 0)
                printf("%d ", sol[i][j]);

            else
                printf("_ ");
        }
        printf("\n");
    }

    printf("\n");
}

int solution(int x, int y)
{
    return (x == end_x && y == end_y);
}

int valid(int x, int y)
{
    return (x >= 0 && x < N && y >= 0 && y < N && a[x][y] <= h && !sol[x][y]);
}

void back(int x, int y)
{
    if (valid(x, y))
    {
        k ++;
        sol[x][y] = k;
        h = a[x][y]; // right here I'm updating the variabile

        if (solution(x, y))
        {
            count ++;
            print();
        }
        else
        {
            back(x + 1, y);
            back(x, y + 1);
            back(x - 1, y);
            back(x, y - 1);
        }

        sol[x][y] = 0;
        h = a[x][y]; // I actually don't know where to put this
        k --;
    }
}

int main(void)
{
    int i, j;

    for (i = 0; i < N; i++)
    {
        for (j = 0; j < N; j++)
            printf("%d ", a[i][j]);

        printf("\n");
    }

    while (start_x >= N || start_x < 0 || start_y >= N || start_y < 0)
    {
        printf(">> Start X: "); scanf("%d", &start_x);
        printf(">> Start Y: "); scanf("%d", &start_y);
    }

    h = a[start_x][start_y];

    while (end_x >= N || end_x < 0 || end_y >= N || end_y < 0)
    {
        printf(">> End X: "); scanf("%d", &end_x);
        printf(">> End Y: "); scanf("%d", &end_y);
    }

    printf("Generated solutions:\n");
    back(start_x, start_y);

    if (!count)
        printf("No path was found!\n");

    return 0;
}

So, for start_x = 0, start_y = 0, end_x = 1, end_y = 3 it should bring the 35 -> 13 -> 12 -> 11 -> 3 and the 35 -> 13 -> 12-> 11 -> 10 -> 8 -> 3 solutions. 因此,对于start_x = 0, start_y = 0, end_x = 1, end_y = 3,它应该带来35-> 13-> 12-> 11-> 3和35-> 13-> 12-> 11-> 10 -> 8-> 3个解决方案。

Without that condition the algorithm is working fine, it's just that I don't know where to update the h variable. 没有这种条件,该算法将无法正常工作,只是我不知道在哪里更新h变量。

I think you are on the right track. 我认为您在正确的轨道上。 However the variable h seems redundant. 但是变量h似乎是多余的。 Instead you need two more things: 相反,您还需要两件事:

1) Have you visited a particular cell before or not. 1)您是否曾经去过一个特定的牢房。

2) The value of your previous move, so when as you move to the next cell or consider moving to the next cell you verify if its a valid move. 2)您先前移动的值,因此当您移动到下一个单元格或考虑移动到下一个单元格时,请验证其是否为有效移动。

Your modified code is as follows: 您修改的代码如下:

#include <stdio.h>

#define N 4

int a[N][N] =
{
    {35, 75, 80, 12},
    {13, 12, 11, 3},
    {32, 9, 10, 8},
    {12, 2, 85, 1}
};

int sol[N][N];
int visited[N][N];

int h, k, count;
int end_x = -1, end_y = -1;
int start_x = -1, start_y = -1;

void print()
{
    int i, j;

    for (i = 0; i < N; i++)
    {
        for (j = 0; j < N; j++)
        {
            if (sol[i][j] > 0)
                printf("%d ", sol[i][j]);

            else
                printf("_ ");
        }
        printf("\n");
    }

    printf("\n");
}

int solution(int x, int y)
{
    return (x == end_x && y == end_y);
}

int valid(int x, int y, int currentCellValue)
{
    return (x >= 0 && x < N && y >= 0 && y < N && a[x][y] <= currentCellValue && !sol[x][y] && !visited[x][y]);
}

void back(int x, int y, int curr)
{
    if (valid(x, y, curr))
    {
        k ++;
        sol[x][y] = k;
        visited[x][y] = 1;

        if (solution(x, y))
        {
            count ++;
            print();
        }
        else
        {
            back(x + 1, y, a[x][y]);
            back(x, y + 1, a[x][y]);
            back(x - 1, y, a[x][y]);
            back(x, y - 1, a[x][y]);
        }

        sol[x][y] = 0;
        visited[x][y] = 0;
        k --;
    }
}

int main(void)
{
    int i, j;

    for (i = 0; i < N; i++)
    {
        for (j = 0; j < N; j++)
            printf("%d ", a[i][j]);

        printf("\n");
    }

    while (start_x >= N || start_x < 0 || start_y >= N || start_y < 0)
    {
        printf(">> Start X: "); scanf("%d", &start_x);
        printf(">> Start Y: "); scanf("%d", &start_y);
    }

    h = a[start_x][start_y];

    while (end_x >= N || end_x < 0 || end_y >= N || end_y < 0)
    {
        printf(">> End X: "); scanf("%d", &end_x);
        printf(">> End Y: "); scanf("%d", &end_y);
    }

    printf("Generated solutions:\n");
    back(start_x, start_y, a[start_x][start_y]);

    if (!count)
        printf("No path was found!\n");

    return 0;
}

During the call to back notice how I pass the value of the current cell, which is passed to the isValid function to make sure if the move is valid or not. back叫期间,请注意我如何传递当前单元格的值,该值传递给isValid函数以确保移动是否有效。

int visited[N][N]; ensures that you dont visit the same cell over and over again. 确保您不会一次又一次地访问同一单元。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM