【问题标题】:c++ maze solver (find every solution) stack overflowc ++迷宫求解器(找到每个解决方案)堆栈溢出
【发布时间】:2015-05-31 18:34:44
【问题描述】:

我有一个随机生成迷宫的任务(“奇怪”的迷宫也是有效的),然后我必须找到迷宫的所有解决方案(一个解决方案是找到从第一行或第一列到最后一行的方法或列),也确定最短的一个。我这里有这段代码,但是当我运行它时,有一半时间它给出了一个很好的答案,另一半时间它只是退出而没有任何错误弹出或警告。我猜原因是堆栈溢出。此外,在作业中说我们必须在 20x20 的迷宫中解决这个问题。如果它在 5x5 上溢出,你能想象 20x20 吗?无论如何,任何帮助将不胜感激。请忽略 cmets,拥有匈牙利 cmets 实际上是任务的一部分。

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

struct vector2d {
    int column, row;
};

const int N = 5;        // sorok száma
const int M = 5;        // oszlopok száma
bool ut[N][M];
int count = 0;
int currentLength = 0, minLength = 99999;

void initMaze();         // generál egy labirintust
void printMaze();        // kiiratja a labirintust
int exits();             // kijáratok számát adja vissza
int entrances();         // bejáratok számát adja vissza
bool findPath(int, int); // útkereső eljárás

int main() {
    initMaze();
    printMaze();
    if (exits() > 0 && entrances() > 0) {
        // bactrack
        for (int i = 0; i < M; i++) // vegigjarjuk az elso sor osszes "utjat" es megkeressuk az onnan indulo megoldasokat
            if (ut[0][i])
                if (findPath(0, i)) {
                    count++;
                    if (currentLength < minLength)
                        minLength = currentLength;
                    currentLength = 0;
                }

        for (int i = 1; i < M; i++)
            if (ut[i][0])
                if (findPath(i, 0)) {
                    count++;
                    if (currentLength < minLength)
                        minLength = currentLength;
                    currentLength = 0;
                }
    } else {
        cout << "Maze has no entrances or exits" << endl;
    }

    if (count > 0) {
        cout << count << " solutions for the labyrinth, shortest one is " << minLength << " steps long" << endl;
    } else {
        cout << "Labyrinth has no solution" << endl;
    }

    system("pause");
    return 0;
}

int exits() {
    int count = 0;
    for (int i = 1; i < M - 1; i++)
        if (ut[N - 1][i])
            count++;
    for (int i = 1; i < N - 1; i++)
        if (ut[i][M - 1])
            count++;
    return count;
}

int entrances() {
    int count = 0;
    for (int i = 1; i < M - 1; i++)
        if (ut[0][i])
            count++;
    for (int i = 1; i < N - 1; i++)
        if (ut[i][0])
            count++;
    return count;
}

void initMaze() {
    srand(time(NULL));
    for (int i = 0; i < N; i++)
        for (int j = 0; j < M; j++) {
            if (rand() % 3 == 0) // 3-ból egyszer legyen fal
                ut[i][j] = false;
            else
                ut[i][j] = true;
        }
}

void printMaze() {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (ut[i][j])
                cout << " - ";
            else
                cout << " | ";
        }
        cout << endl;
    }
}

bool findPath(int row, int column) {
    if (column < 0 || column > N - 1 || row < 0 || row > M - 1) return false;
    if ((column == M - 1 || row == N - 1) && ut[row][column])   return true;
    if (!ut[row][column])                                       return false;
    currentLength++;
    if (findPath(column + 1, row))                              return true;
    if (findPath(column, row + 1))                              return true;
    if (findPath(column - 1, row))                              return true;
    if (findPath(column, row - 1))                              return true;
    currentLength--;
    return false;
}

【问题讨论】:

  • 哦,还有,当堆栈溢出时,currentLength 变量的值异常高,65000 左右。

标签: c++ recursion stack overflow maze


【解决方案1】:

你有递归调用

findPath(column + 1, row)

这个函数会在一段时间后进行递归调用

findPath(column - 1, row)

这两个调用的问题是会回到调用它的位置。

例如,如果使用坐标 2,4 调用 findPath,则显示的第一个调用将调用 findPath(3,4),然后调用 findPath(2,4)(当然会调用 findPAth(3,4) 等等)以此类推)。

【讨论】:

  • 哇,感谢您的快速回复。虽然我理解这个问题,但我将如何解决它?
  • @BarnaBruder 最简单的解决方案是传递另一对参数,即上一次调用的坐标,然后添加检查,这样就不会直接返回。这仍然允许无限递归,例如然后共同“左”两个地方然后去“右”两个地方,你仍然有同样的问题。 - 另一种解决方案是使用有向图作为路径,一旦你朝一个方向走,你就不能回去了。如果您阅读一些graph theory,可能有很多解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-01
  • 2017-10-09
  • 2019-08-10
  • 2021-04-06
相关资源
最近更新 更多