【问题标题】:Issue in my recursive algorithm for finding all shortest, unique paths我的递归算法中的问题,用于查找所有最短的唯一路径
【发布时间】:2019-01-28 01:39:04
【问题描述】:

我一直在研究一种递归算法,该算法应该在 n × m 矩阵中找到从 A 点到 B 点的所有最短、唯一的可能路径。目前,我的算法可以找到从单个方向开始的所有可能路径。然而,当我回到算法开始的第一个堆栈帧时,我被第一帧中先前采取的行动所采取的任何方向所困。我已经确定这是因为我的移动函数引用了我正在使用的当前解决方案。我认为需要发生的是,我需要进一步本地化我的参数,以便我本质上可以从一开始就重新开始。我只是不知道该怎么做,因为任何时候我试图摆脱对我的运动算法的引用,“解决方案”都会以一个字母的形式返回。

关于使第一个堆栈帧更独立于我的移动算法的任何提示?

{void Robot::findTreasureHelper(Board whichBoard, int x, int y, std::string solution)

    ++callCount;

    if (x == TREASURE_X && y == TREASURE_Y)
    {
        ++numSolutions;
        return;
    }

    if (move(whichBoard, 'N', x, y, solution))
        findTreasureHelper(whichBoard, x, y, solution);
    if (move(whichBoard, 'E', x, y, solution))
        findTreasureHelper(whichBoard, x, y, solution);
    if (move(whichBoard, 'S', x, y, solution))
        findTreasureHelper(whichBoard, x, y, solution);
    if (move(whichBoard, 'W', x, y, solution))
        findTreasureHelper(whichBoard, x, y, solution);

    {bool Robot::move(Board& whichBoard, const char& whichDir, int& x, int& y, std::string& solution)

    bool didMove = false;

    int direction = 1;
    if (whichDir == 'S' || whichDir == 'E')
        direction = -1;
    int  *coordinate = &x;
    if (whichDir == 'N' || whichDir == 'S')
        coordinate = &y;

    //check bounds, consecutive movements, and whether robot has been here on this solution
    if (x == TREASURE_X && y == TREASURE_Y)
        *coordinate += direction;
    else if (*coordinate - direction >= 0 && *coordinate - direction < whichBoard.board.size() 
        && *coordinate - direction < whichBoard.board[y].size() && moveCount < CONSECUTIVE_MOVES)
    {
        *coordinate -= direction;
        //check blocks and previously been here
        if (whichBoard.board[y][x] == -1 || whichBoard.board[y][x] == currentSolutionIndex)
            *coordinate += direction;
        else if (x == TREASURE_X && y == TREASURE_Y)
        {
            switch (whichDir)
            {
            case 'N':
            case 'S':
                //check consecutive moves
                solution.back() == 'N' || solution.back() == 'S' ? ++moveCount : moveCount = 0;
                //add correct character to solution
                direction == 1 ? solution += 'N' : solution += 'S';
                break;
            case 'E':
            case 'W':
                //check consecutive moves
                solution.back() == 'E' || solution.back() == 'W' ? ++moveCount : moveCount = 0;
                //add correct character to solution
                direction == 1 ? solution += 'W' : solution += 'E';
                break;
            }
            //*coordinate += direction;
            this->solutions.push_back(solution);
            didMove = true;
        }
        else // complete the move randomly
        {
            switch (whichDir)
            {
            case 'N':
            case 'S':
                //check consecutive moves
                solution.back() == 'N' || solution.back() == 'S' ? ++moveCount : moveCount = 0;
                //add correct character to solution
                direction == 1 ? solution += 'N' : solution += 'S';
                break;
            case 'E':
            case 'W':
                //check consecutive moves
                solution.back() == 'E' || solution.back() == 'W' ? ++moveCount : moveCount = 0;
                //add correct character to solution
                direction == 1 ? solution += 'W' : solution += 'E';
                break;
            }
            didMove = true;
            whichBoard.board[y][x] = currentSolutionIndex;
        }

    }
    return didMove;
}

【问题讨论】:

    标签: c++ c++11 recursion c++14 path-finding


    【解决方案1】:

    要找到最短路径,我建议您使用 BFS 而不是 DFS,以便您更快地找到解决方案。这可以在队列的帮助下完成。从您的起始索引开始,将邻居(在您的情况下,您的四个邻居 N、S、E、W)附加到队列中。

    有一个数据结构来跟踪所有访问过的索引(最好是一组)。因此,一旦您完成了这些设置,请重复执行以下操作 -

    1. 从队列中弹出元素。
    2. 检查这是否是您的目标索引,如果是,则您已找到最短路径。
    3. 如果没有,则将此索引标记为已访问并将其邻居添加到队列中。

    迭代解决方案 - 一个明显的好处:)

    【讨论】:

    • 不幸的是,我应该使用递归来解决这个问题。据我了解,BFS 并不是真正的递归搜索类型。如果我错了,请纠正我。从技术上讲,我是 EE 专业的,并且不必深入研究计算机科学,所以请原谅我可能有的任何无知,哈哈。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-18
    • 1970-01-01
    相关资源
    最近更新 更多