使用动态编程无法在“最小成本路径”中找到路径

时间:2018-12-10 17:29:20

标签: c++ dynamic-programming

  • 该算法应在作为输入的NxN矩阵中找到最小成本路径。起始单元格始终位于左下角,目标位置始终位于右上角。
  • 矩阵的每个单元格代表遍历该单元格的成本。
  • 您只能左右移动。

我设法找到了成本,但是,我仍然很难追回原路。

我尝试从右上角的单元格开始,并使用贪婪算法查找我的“返回路径”,但是输出完全错误或跳过了随机的列/行。我还尝试通过创建其他矩阵来跟踪自己所做的决策,但最终总是陷入循环。

那我怎么找到路径?

这是运行良好的代码(计算成本就可以了)

    #include <iostream>

using namespace std;


int main()
{
    int tab[101][101], N, cost[101][101], backtrack[101][101];
    cout << "N (size of NxN matrix) :" << endl;
    cin >> N;

    for(int i = 0; i < N; i++)
    {
        for(int j = 0; j < N; j++)
        {
            cin >> tab[i][j];
            cost[i][j] = 0;
            backtrack[i][j] = 0;
        }
    }

    cost[N-1][0] = tab[N-1][0];
    int a = N-1;

     for(int i = N-2; i >= 0; i--)  // column 0 can be chosen only in 1 way
    {
        cost[i][0] = cost[i+1][0] + tab[i][0];
        backtrack[i][0] = 4; // came from down

    }
    for(int j = 1; j < N; j++)  // row N-1 can be chosen only in 1 way
    {
        cost[a][j] = cost[a][j-1] + tab[a][j];
        backtrack[a][j] = 3; // came from right
    }


 for(int i = N-2; i >= 0; i--)
        {
            for(int j = 1; j < N; j++)
            {
                if(cost[i][j-1] <= cost[i+1][j])
                {
                    cost[i][j] = tab[i][j] + cost[i][j-1];
                    backtrack[i][j] = 3;
                }

                else
                {
                    cost[i][j] = tab[i][j]+cost[i+1][j];
                    backtrack[i][j] = 4;
                }
            }
        }

   cout << "Cost: " << cost[0][a] << endl;


    return 0;
}

现在,这是带有有缺陷的附加矩阵的函数,应该为我提供路径,但最终陷入无限循环: (先前代码中的矩阵 backtrack 在此处指定为 track

 void path(int track[101][101], int N)
    {
        int help[101][101];
        for(int i = 0; i < N; i++)
        {
            for(int j = 0; j < N; j++)
                help[i][j] = 0;
        }

        int w = 0, k = N-1;

        help[w][k] = 1; // top right argument is included in the output

        while(w < N || k >= 0)
        {
            if(track[w][k] == 3)
            {
                help[w][k-1] = 1; // 3 means I came from the previous column k-1
                k--;
            }
            else if(track[w][k] == 4) 
            {
                help[w+1][k] = 1; //4 means I came from the previous row w+1
                w++;
            }

        }

        for(int i = 0; i < N; i++)
        {
            for(int j = 0; j < N; j++)
            {
                if(help[i][j] != 0)
                cout << i << " " << j << endl;
            }
        }

    }

示例输入:

    5
    2 3 4 2 5
    5 2 1 2 2
    2 4 2 2 3
    1 2 2 4 3
    3 2 1 2 3

预期输出:

Cost: 20
4 0
4 1
4 2
3 2
2 2
1 2
1 3
0 3
0 4

实际输出

Cost: 20

没有任何路径,因为它以无限循环结束。

1 个答案:

答案 0 :(得分:0)

您在while中错误地编写了path()循环:

while(w < N || k >= 0)
  ...

您希望此循环继续进行,直到w = N-1并且k = 0为止,但是它并没有在那里终止,只是在原地运行。 (您可以在循环中添加cout << w << " " << k << endl;来自己查看。)我认为您想要的条件是:

while(w < N-1 || k > 0)