Проблема в моем рекурсивном алгоритме для поиска всех кратчайших, уникальных путей - PullRequest
0 голосов
/ 28 января 2019

Я работал над рекурсивным алгоритмом, который должен находить все кратчайшие, уникальные возможные пути, чтобы добраться из точки A в точку B в матрице n на m.В настоящее время я дошел до того, что мой алгоритм может найти все возможные пути, начиная с одного направления.Однако когда я возвращаюсь к первому кадру стека, где начинается алгоритм, я застреваю с любыми указаниями, которые были предприняты в предыдущих действиях, выполненных в первом кадре.Я определил, что это связано с тем, что моя функция перемещения использует ссылку на текущее решение, с которым я работаю.Я думаю, что должно произойти, это то, что мне нужно дополнительно локализовать свои параметры, чтобы я, по сути, мог начать заново с нуля.Я просто не уверен, как это сделать, потому что всякий раз, когда я пытаюсь отойти от передачи ссылок на мой алгоритм перемещения, «решения» возвращаются одной буквой.

Любые советы по созданию первогокадр стека более независим от моего алгоритма движения?

{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;
}

1 Ответ

0 голосов
/ 28 января 2019

Чтобы найти кратчайший путь, я бы предложил вам скорее BFS, чем DFS, чтобы вы быстрее достигли своего решения.Это можно сделать с помощью очереди.Начните с начального индекса, добавьте соседей (в вашем случае четырех соседей N, S, E, W) в очередь.

Иметь структуру данных для отслеживания всех посещенных индексов (желательно, набора).Поэтому, как только вы их настроите, повторно выполните следующее -

  1. Извлеките элемент из очереди.
  2. Проверьте, является ли это вашим целевым индексом, если вы нашли ваш самый короткийpath.
  3. Если нет, отметьте этот индекс как посещенный и добавьте его соседей в очередь.

Итеративное решение - очевидный бонус:)

...