static void Test_FindMAxSubmatrix() { int[,] inMtrx = new int[6, 6] { { 2, -1, 2, -1, 4, -5 }, { 2, 8, 2, -1, 4, -5 }, { 2, -1, 2, -1, 4, -5 }, { 2, -1, 2, -1, 4, -5 }, { 2, -1, 2, -1, 4, -5 }, { -2, -1, -2, -1, 4, -5 } }; MaxSubmatrix.PrintMatrix(inMtrx); MaxSumMatrix mxMatrix = MaxSubmatrix.FindMaxSumSubmatrix(inMtrx); Console.WriteLine("Max sum = {0}", mxMatrix.sum); MaxSubmatrix.PrintMatrix(inMtrx, mxMatrix.rowStart, mxMatrix.rowEnd, mxMatrix.colStart, mxMatrix.colEnd); // case 2 inMtrx = new int[, ] { { -1, -2, -3, -4 }, { -5, -6, -7, -8 }, { -9, -10, -11, -12 }, { -13, -14, -15, -16 } }; MaxSubmatrix.PrintMatrix(inMtrx); mxMatrix = MaxSubmatrix.FindMaxSumSubmatrix(inMtrx); Console.WriteLine("Max sum = {0}", mxMatrix.sum); MaxSubmatrix.PrintMatrix(inMtrx, mxMatrix.rowStart, mxMatrix.rowEnd, mxMatrix.colStart, mxMatrix.colEnd); // case 3 inMtrx = new int[, ] { { 1, -61, 5126, 612, 6 }, { 41, 6, 7, 2, -71 }, { 73, -62, 678, 1, 7 }, { -616136, 61, -83, 724, -151 }, { 6247, 872, 2517, 8135, 1 } }; MaxSubmatrix.PrintMatrix(inMtrx); mxMatrix = MaxSubmatrix.FindMaxSumSubmatrix(inMtrx); Console.WriteLine("Max sum = {0}", mxMatrix.sum); MaxSubmatrix.PrintMatrix(inMtrx, mxMatrix.rowStart, mxMatrix.rowEnd, mxMatrix.colStart, mxMatrix.colEnd); // case 4 inMtrx = new int[, ] { { 0, -2, -7, 0 }, { 9, 2, -6, 2 }, { -4, 1, -4, 1 }, { -1, 8, 0, -2 } }; MaxSubmatrix.PrintMatrix(inMtrx); mxMatrix = MaxSubmatrix.FindMaxSumSubmatrix(inMtrx); Console.WriteLine("Max sum = {0}", mxMatrix.sum); MaxSubmatrix.PrintMatrix(inMtrx, mxMatrix.rowStart, mxMatrix.rowEnd, mxMatrix.colStart, mxMatrix.colEnd); }
public static MaxSumMatrix FindMaxSumSubmatrix(int[,] inMtrx) { MaxSumMatrix maxSumMtrx = new MaxSumMatrix(); // Step 1. Create SumMatrix - do the cumulative columnar summation // S[i,j] = S[i-1,j]+ inMtrx[i-1,j]; int m = inMtrx.GetUpperBound(0) + 2; int n = inMtrx.GetUpperBound(1) + 1; int[,] sumMatrix = new int[m, n]; for (int i = 1; i < m; i++) { for (int j = 0; j < n; j++) { sumMatrix[i, j] = sumMatrix[i - 1, j] + inMtrx[i - 1, j]; } } PrintMatrix(sumMatrix); // Step 2. Create rowSpans starting each rowIdx. For these row spans, create a 1-D array r_ij for (int x = 0; x < n; x++) { for (int y = x; y < n; y++) { int[] r_ij = new int[n]; for (int k = 0; k < n; k++) { r_ij[k] = sumMatrix[y + 1, k] - sumMatrix[x, k]; } // Step 3. Find MaxSubarray of this r_ij. If the sum is greater than the last recorded sum => // capture Sum, colStartIdx, ColEndIdx. // capture current x as rowTopIdx, y as rowBottomIdx. MaxSum currMaxSum = KadanesAlgo.FindMaxSumSubarray(r_ij); if (currMaxSum.maxSum > maxSumMtrx.sum) { maxSumMtrx.sum = currMaxSum.maxSum; maxSumMtrx.colStart = currMaxSum.maxStartIdx; maxSumMtrx.colEnd = currMaxSum.maxEndIdx; maxSumMtrx.rowStart = x; maxSumMtrx.rowEnd = y; } } } return(maxSumMtrx); }