簡體   English   中英

回溯算法陷入困境

[英]Backtracking algorithm gets stuck

我有一個矩陣問題(地圖),該問題從左上角開始,我想找到到右下角的較不重的路徑。 它的條件是只能向右,向下或從右向下移動。

這是一個示例: 矩陣示例

我需要通過回溯來解決問題,但是我不能確定我是否做得很好。

這段代碼能夠解決最大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)時,它將完成與該階段的第一次遍歷完全相同的工作,因此第三遍歷也將完成。 因此,這些重復的步驟是您耗盡程序和代碼的時間太長而無法執行的地方。 您的代碼不會因為長時間運行而停滯不前。 您可以在此處輕松記住結果以優化時間。

因此,如果您可以將首次到達點(i,j)時發現的值另存為save[i][j] ,則當其他遍歷到達該點(i,j)時,它可以決定不進行遍歷並進一步使用此save[i][j] 這樣,您可以使代碼更快。

這樣,它將變成動態編程而不是回溯,甚至大小為10000X10000的網格也將花費大約幾秒鍾的時間來提供結果。

在此答案中,我僅描述了如何找到通向最小值的路徑的值,如果您想使用相同的DP解決方案也可以找到該路徑。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM