通过矩阵获得最低金额,仅从左到右,从上到下

时间:2015-11-07 15:01:26

标签: c# matrix

我遇到了一个大学项目,我想知道你是否可以帮我提一下如何做到这一点,我必须在c#上做。

使用80x80矩阵我必须从左到右,从上到下经过 ,所以我可以找到从左上角总结所有值时给出最小数字的路径角落到右下角。

作为这种情况的一个例子,应该拿起的数字是:

Matrix sample

131,201,96,342,746,422,121,37,331 = 2427 最低数

向右或向下移动的次数并不重要,但重要的是获得最低的数字。

4 个答案:

答案 0 :(得分:0)

您需要做的是将每个单元格视为图形中的节点并实现最短路径算法。

Dijkstra算法就是其中之一。您可以在https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm

找到更多信息

答案 1 :(得分:0)

这是一个有趣的项目,它说明了一种称为dynamic programming的重要技术:通过简单的计算步骤,可以从一个较小的子问题的解决方案构建整个问题的解决方案。

从递归解决方案开始,该解决方案不适用于大型矩阵

 // m is the matrix
 // R (uppercase) is the number of rows; C is the number of columns
 // r (lowercase) and c are starting row/column
 int minSum(int[,] m, int R, int C, int r, int c) {
     int res;
     if (r == R-1 && c == C-1) {
         // Bottom-right corner - one answer
         res = m[r,c];
     } else if (r == R-1) {
         // Bottom row - go right
         res = m[r,c] + minSum(m, R, C, r, c+1);
     } else if (c == C-1) {
         // Rightmost column - go down
         res = m[r,c] + minSum(m, R, C, r+1, c);
     } else {
         // In the middle - try going right, then try going down
         int goRight = m[r,c] + minSum(m, R, C, r, c+1);
         int goDown = m[r,c] + minSum(m, R, C, r+1, c);
         res = Math.Min(goRight, goDown);
     }
     return res;
 }

这适用于10×10矩阵,但80×80矩阵需要太长时间。但是,它为工作解决方案提供了一个模板:如果您在之前的步骤中添加了单独的结果矩阵,则可以将其转换为更快的解决方案:

 // m is the matrix
 // R (uppercase) is the number of rows; C is the number of columns
 // known is the matrix of solutions you already know
 // r (lowercase) and c are starting row/column
 int minSum(int[,] m, int R, int C, int?[,] known, int r, int c) {
     if (known[r,c].HasValue) {
         return known[r,c];
     }
     int res;
     ... // Computation of the result goes here
     known[r,c] = res;
     return res;
 }

这种实现动态编程解决方案的特殊技术称为memoization

答案 2 :(得分:0)

这很简单,因为您可以将问题分解为已解决和未解决的部分,并将项目从未解决的问题逐个移动到已解决的问题中。从左上角开始,然后浏览所有" /"对角线朝右下方。

 int size = 5;
    int[,] matrix = new int[,] {
        {131,673,234,103,18},
        {201,96,342,965,150},
        {630,803,746,422,111},
        {537,699,497,121,956},
        {805,732,524,37,331}
    };

    //Random rand = new Random();
    //for (int y = 0; y < size; ++y)
    //{
    //    for (int x = 0; x < size; ++x)
    //    {
    //        matrix[y, x] = rand.Next(10);
    //    }
    //}

    int[,] distance = new int[size, size];
    distance[0, 0] = matrix[0, 0];

    for (int i = 1; i < size * 2 - 1; ++i)
    {
        int y = Math.Min(i, size - 1);
        int x = i - y;
        while (x < size && y >= 0)
        {
            distance[y, x] = Math.Min(
                x > 0 ? distance[y, x - 1] + matrix[y, x] : int.MaxValue,
                y > 0 ? distance[y - 1, x] + matrix[y, x] : int.MaxValue);
            x++;
            y--;
        }
    }

    for (int y = 0; y < size; ++y)
    {
        for (int x = 0; x < size; ++x)
        {
            Console.Write(matrix[y, x].ToString().PadLeft(5, ' '));
        }
        Console.WriteLine();
    }
    Console.WriteLine();

    for (int y = 0; y < size; ++y)
    {
        for (int x = 0; x < size; ++x)
        {
            Console.Write(distance[y, x].ToString().PadLeft(5, ' '));
        }
        Console.WriteLine();
    }
    Console.WriteLine();

答案 3 :(得分:0)

第一步始终是分析,特别是试图找出问题的规模。

好的,假设你只能下降或向右,你将有79步,向右79步。总共158个步骤形式011100101001(1 =向右移动,0 =向下移动)等。请注意,解决方案空间不是2 ^ 158,因为并非所有二进制数都是可能的...您必须具有正好79个并且79权利。从组合学来看,这限制了158!/ 79!79!的可能正确答案的数量,这仍然是一个非常大的数字,例如10 ^ 46。

你应该意识到,对于暴力来说这是非常大的,如果项目没有明确地规定它,那么这种方法肯定应该是你的考虑因素,因为它总是使算法更简单(例如通过简单地迭代所有解决方案的可能性)。我想这个问题是按照这种方式设计的,以便要求你使用一种不会强制正确答案的算法。

在不迭代整个解空间的情况下解决这个问题的方法是要意识到右下角的最佳路径是直接到左边的两个最佳路径的更好 ,及以上,右下角,最佳路径是到下一个对角线的最佳路径(图中的数字524,121,111),依此类推。