分治算法:求矩阵的最小值

Divide and conquer algorithm: find the minimum of a matrix

本文关键字:最小值 分治算法      更新时间:2023-10-16

我开始学习如何实现分治算法,但是我在这个练习中遇到了一些严重的问题。我写了一个算法,该算法使用分治法在给定向量中找到最小值:

int minimum (int v[], int inf, int sup)
{
int med, m1, m2;
if (inf == sup)
return v[inf];
med = (inf+sup)/2;
m1 = minimum (v, inf, med);
m2 = minimum (v, med+1, sup);
if (m1 < m2)
return m1;
else
return m2;
}

它起作用了。现在,我要在矩阵上做同样的练习,但是我迷路了。具体来说,我被告知要做以下事情:设n = 2^k。考虑一个nxn的方阵。使用递归函数

计算其最小值
double (minmatrix(Matrix M))
return minmatrix2(M, 0, 0, M.row);

(给出了矩阵类型,可以想象M.row给出了矩阵的行数和列数)。使用辅助函数

double  minmatrix2(Matrix M, int i, int j, int m) 

这必须使用递归分治算法来完成。所以. .我想不出做这件事的办法。我被建议每次将矩阵分成4部分(从(I,j)到(I +m/2,j+m/2),从(I +m/2,j)到(I +m/2,j+m/2),从(I,j+m/2)到(I +m/2,j+m),从(I +m/2,j+m/2)到(I +m,j+m)),并尝试实现一个代码以类似的方式工作,我为数组写的代码。但我似乎做不到。有什么建议吗?即使你不想张贴一个完整的答案,只是给我一些提示。我真的很想了解这个。

编辑:好吧,我已经做到了。我把我用过的代码贴出来,以防别人也有同样的疑问。
double minmatrix2(Matrix M, int i, int j, int m)
{   
    int a1, a2, a3, a4;
    if (m == 1)
    return M[i][j];
    else
    a1 = minmatrix2(M, i, j, m/2);
    a2 = minmatrix2(M, i+(m/2), j, m/2);
    a3 = minmatrix2(M, i, j+(m/2), m/2);
    a4 = minmatrix2(M, i+(m/2), j+(m/2), m/2);
    if (min (a1, a2) < min (a3, a4))
    return min (a1, a2);
    else
    return min (a3, a4);
}

(function min定义)

考虑C或c++中的2D矩阵通常作为访问器函数实现在1D数组之上。您已经知道如何为1D数组执行此操作,因此唯一的区别是如何处理单元。如果您这样做,您的性能将本质上是最优的,因为您将同时处理相邻的单元。

或者,考虑一个二维矩阵有两个维度N和m,只要沿着较大的维度重复将其分成两半,直到较大的维度小于X,一个合理的值,停止并依次进行实际的计算。这并不是完全最优的,因为在寻址内存时,您将不得不"跳过"矩阵的某些部分。

最后一个想法是先除以大维,再除以小维。在C语言中,这意味着按行除,直到得到单行,然后对每一行运行1D数组算法。这将产生大致最佳的性能。