【问题标题】:Can't find path in Minimum Cost Path using Dynamic Programming使用动态编程在最小成本路径中找不到路径
【发布时间】:2018-12-10 17:29:19
【问题描述】:
  • 该算法应该在作为输入的 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

而且根本没有路径,因为它以无限循环结束。

【问题讨论】:

  • 欢迎来到 Stack Overflow。请查看我们的intro section,特别注意minimal complete examples 上的页面。这对于第一个问题来说非常好,但可以改进:您没有说明实际输出,输入没有硬编码,示例看起来不是最小的(代码在 4x4 数组上是否正常工作?),并且您已将其留给我们对您的算法进行逆向工程(这对于不起作用的代码可能很困难)。您会得到答案,但不会尽快。
  • 我投票决定将此问题作为离题结束,因为它是关于一个错误的错误。它不太可能对未来的读者有所帮助。

标签: c++ dynamic-programming


【解决方案1】:

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

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

您希望此循环继续直到 w = N-1 和 k=0,它确实如此,但循环不会在那里终止,它只是在原地运行。 (您可以通过将 cout &lt;&lt; w &lt;&lt; " " &lt;&lt; k &lt;&lt; endl; 添加到循环中来自己看到这一点。)我认为您想要的条件是:

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

【讨论】:

  • 非常感谢,经过编辑和cout终于可以正常使用了。
猜你喜欢
  • 1970-01-01
  • 2020-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-19
  • 2015-07-21
  • 1970-01-01
  • 2016-07-20
相关资源
最近更新 更多