回溯算法卡住了

Backtracking algorithm gets stuck

本文关键字:回溯算法      更新时间:2023-10-16

我有一个矩阵(map)的问题,从左上角开始,我想找到到右下角的较轻的路径。它的条件是它只能向右、向下或向右向下移动。

这是一个示例: 矩阵示例

我需要通过回溯解决问题,但我无法判断我是否做得好。

这段代码能够解决高达 10x10 的矩阵大小,但是当我尝试 20x20 矩阵时,它卡住了(或者至少我在几个小时后是这么想的)。

/*
* i, j -> matrix iterators.
* n, m -> matrix height and width
* map  -> matrix
* actualPath, bestPath -> vectors for representing the path later
* actual -> actual path weight
* best -> best path weight
*/
int backtracking(int i, int j, const int &n, const int &m, 
const vector<vector<int>> &map,
vector<vector<int>> &actualPath,
vector<vector<int>> &bestPath,
int best) {
recursiveCalls++;
int actual = 0;
//Bottom-right corner
if(i == (n-1) && j == (m-1)) {
return map[i][j];
}
//Last row, only right
else if(i == (n-1)) {
actual = map[i][j] +
backtracking(i, (j+1), n, m, map, actualPath, bestPath, best, profundidad);
}
//Last column, only down
else if(j == (m-1)) {
actual = map[i][j] +
backtracking((i+1), j, n, m, map, actualPath, bestPath, best, profundidad);
}
else {
int downRight = backtracking((i+1), (j+1), n, m, map, actualPath, bestPath, best, profundidad);
int right = backtracking(i, (j+1), n, m, map, actualPath, bestPath, best, profundidad);
int down = backtracking((i+1), j, n, m, map, actualPath, bestPath, best, profundidad);
actual = map[i][j] + minimo(downRight, right, down);
}
if(actual < best) {
best = actual;
bestPath = actualPath;
}
return best;
}

是否有可能因为我不使用边界而卡住?还是实施不力? 我不知道我做错了什么。我想我理解这个算法,但我想我不知道如何实现它来解决这个问题......

虽然回溯会在这里给你正确的答案。在这种情况下,这不是最快的解决方案。

你在这里做了很多重复的工作,这是不必要的。在这种情况下,直接回溯没有用。让我们看一下这个例子,

假设网格大小为10X10

one of the trees of the backtrackting stared from (0,0) -> (0,1) 
another started from (0,0) -> (1,0)
and another started from (0,0) -> (1,1)

当第一次遍历到达点 (5,5) 时,它将继续寻找所有可能的方法到达 (9,9)。现在,当达到 (5,5) 时,第 2 遍历将执行与此阶段的第一次遍历完全相同的工作,第 3 遍历也是如此。因此,这些重复的步骤是您耗尽程序并且代码执行时间过长的地方。您的代码不会卡住,只是运行很长时间。您可以轻松记住结果以优化此处的时间。

因此,如果您可以将第一次到达点 (i,j) 时找到的值保存为save[i][j],那么当其他遍历到达同一点 (i,j) 时,它可以决定不再遍历并将此save[i][j]用于自己的。这样,您可以使代码更快。

这样,它将更多地成为动态编程而不是回溯,即使是大小为 10000X10000 的网格也需要大约几秒钟才能为您提供结果。

在这个答案中,我只描述了如何找到接近最小值的路径值,如果你想找到使用相同的DP解决方案也可以的路径。