【问题标题】:Find the least and most weighted path in a matrix找出矩阵中权重最小和权重最大的路径
【发布时间】:2023-03-11 11:52:01
【问题描述】:

我尝试使用最高效的方法来找到从 [min(m), min(n)] 到 [max(m), max(n)] 的矩阵中遍历的最小和最大权重路径, when an step is choosen [m,n], the next step should be [m+i, n+j].

+---+----+---+---+---+---+----+
| 1 | 0  | 5 | 2 | 5 | 4 | 10 |
+---+----+---+---+---+---+----+
| 2 | 3  | 2 | 5 | 0 | 0 | 1  |
+---+----+---+---+---+---+----+
| 1 | 3  | 5 | 1 | 4 | 1 | 1  |
+---+----+---+---+---+---+----+
| 0 | 0  | 0 | 1 | 2 | 3 | 5  |
+---+----+---+---+---+---+----+
| 2 | 3  | 4 | 2 | 3 | 1 | 1  |
+---+----+---+---+---+---+----+
| 0 | 10 | 1 | 2 | 2 | 3 | 10 |
+---+----+---+---+---+---+----+

这里是一个生成的矩阵,我应该使用什么算法或关于我应该如何进行的任何建议?提前致谢。

编辑:感谢您的帮助,但是当我在下面的测试用例中抛出时我觉得很奇怪:

+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+
| 0 | 0 | 1 | 0 | 0 |
+---+---+---+---+---+
| 0 | 0 | 1 | 0 | 0 |
+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 |
+---+---+---+---+---+

在上述测试用例中,期望最大权重路径的成本为 1。

由于我很抱歉没有在线程中提及,i和j必须> = 1,因此下一步不应在同一列或同一行上。

【问题讨论】:

  • 对i和j有什么限制吗?矩阵中的条目是否为非负数?
  • 是的,非负矩阵,并且i和j必须为正且>=1
  • 那么权重最小的路径是从起始字段直接一步到结束字段。最大值更有趣。

标签: arrays algorithm matrix dijkstra


【解决方案1】:

可以使用动态规划方法解决问题。 即使在给定的矩阵中有负值​​,也会获得正确的解决方案

定义和注意事项:
数组索引从 0 开始。
A -> 输入矩阵(n 行 m 列)
DP -> 用于存储计算值的矩阵
如果 x ≤ x + a

DP[i][j] 存储从 (0, 0) 开始到 (i, j) 结束的最小成本路径的成本。计算后在DP[n - 1][m - 1]处找到问题的答案。

定义递归关系:

为了避免在计算 DP[i][j] 时出现 O(n2) 循环,我们使用辅助矩阵 MN,其中:

你可以自己证明相等。

代码:

for(int i = 0; i < n; ++i)
    for(int j = 0; j < m; ++j)
    {
        if(i == 0 && j == 0)
            MN[i][j] = DP[i][j] = A[i][j];
        else if(i == 0 && 0 < j)
        {
            DP[i][j] = MN[i][j - 1] + A[i][j];
            MN[i][j] = min(MN[i][j - 1], DP[i][j]);
        }
        else if(0 < i && j == 0)
        {
            DP[i][j] = MN[i - 1][j] + A[i][j];
            MN[i][j] = min(MN[i - 1][j], DP[i][j]);
        }
        else
        {
            DP[i][j] = min(MN[i - 1][j], MN[i][j - 1]) + A[i][j];
            MN[i][j] = min({MN[i - 1][j], MN[i][j - 1], DP[i][j]});
        }
    }

时间复杂度:
有 n*m 个元素,我们对它们中的每一个进行恒定时间操作,那么算法的运行时间是 O(n*m)。

注意: 要解决最大成本路径,只需使用 max 而不是 min 操作。

【讨论】:

    【解决方案2】:

    这可以通过动态规划来解决,因为矩阵上没有负值。

    正如亨利所说,寻找最小值路径没有意义(这将只是通往 max(m)、max(n) 的直接路径)。

    此代码将找到最大值。

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    int main()
    {
        int n, m;
        cin >> n >> m;
        vector<vector<int>> arr;
        arr.resize(n + 1);
        for (int i = 1; i <= n; i++) {
            arr[i].resize(m + 1);
            for (int j = 1; j <= m; j++) {
                cin >> arr[i][j];
            }
        }
    
        for (int i = n; i >= 1; i--) {
            for (int j = m; j >= 1; j--) {
                int maxval;
                if (i == n && j == m) continue;
                else if (i == n) {
                    maxval = arr[i][j + 1];
                }
                else if(j == m) {
                    maxval = arr[i + 1][j];
                }
                else {
                    maxval = arr[i + 1][j] > arr[i][j + 1] ? arr[i + 1][j] : arr[i][j + 1];
                }           
                arr[i][j] += maxval;
            }
        }
    
        cout << arr[1][1];
        
        return 0;
    }
    //test case
    //6 7
    //1 0 5 2 5 4 10 
    //2 3 2 5 0 0 1  
    //1 3 5 1 4 1 1  
    //0 0 0 1 2 3 5 
    //2 3 4 2 3 1 1 
    //0 10 1 2 2 3 10 
    //answer : 45
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-14
      • 1970-01-01
      • 1970-01-01
      • 2021-09-29
      • 1970-01-01
      • 2016-07-13
      • 1970-01-01
      相关资源
      最近更新 更多