将矩阵分割成小矩阵的块的方法

时间:2012-04-17 22:52:23

标签: c++ algorithm math

我遇到了问题,想知道是否有人能提供理想的解决方案。

基本上(小数据)但是,如果我有这样的矩阵:

     0 1 0 0
     1 1 1 0
     0 0 0 0
     1 1 0 0

然后我需要将此矩阵拆分为与第二个矩阵大小相同的块,在本例中为2x2:

0 1
1 1

我知道它与offsetX / Y值有关,这些根据(小)矩阵的大小而变化,我只是不知道计算这些结果的计算。我将把offsetX / Y传递给一个函数(带向量),这样我就可以计算出特定块的总和。

有人有任何建议吗?

由于

3 个答案:

答案 0 :(得分:3)

import std.stdio : writeln;
void main(string[] args)
{
    int m=4, n=4;
    int[][] matrix = [[0, 1, 0, 0], [1, 1, 1, 0], [0, 0, 0, 0], [1, 1, 0, 0]];
    int mm=2, nn=2;
    int sum;
    for(int x=0; x<m; x+=mm)
      for(int y=0; y<n; y+=nn)
        sum += summation(matrix, x, y, mm, nn);
    writeln(sum);
}    
int summation(int[][] matrix, int offsetx, int offsety, int m, int n)
{
  int sum;
  for(int x=offsetx; x<offsetx+m; x++)
    for(int y=offsety; y<offsety+n; y++)
      sum += matrix[x][y];
  return sum;
}

除非你在找别的东西?在解释你所要求的内容时,你的问题很模糊。

(这在D中编译,因为它是我唯一可以访问atm的东西,使用它作为转换为C ++的指南)

答案 1 :(得分:3)

为了在原位分割矩阵(也就是说,不复制它),你需要一个能够同时处理原始和拆分的表示 - 这样可以更容易地定义递归算法,等等:

template <class elt> class MatRef {
    elt* m_data;
    unsigned m_rows, m_cols;
    unsigned m_step;

    unsigned index(unsigned row, unsigned col)
    {
        assert(row < m_rows && col < m_cols);
        return m_step * row + col;
    }

public: // access
    elt& operator() (unsigned row, unsigned col)
    {
        return m_data[index(row,col)];
    }

public: // constructors
    MatRef(unsigned rows, unsigned cols, elt* backing)  // original matrix
        : m_rows(rows)
        , m_cols(cols)
        , m_step(cols)
        , m_data(backing)
    {}
    MatRef(unsigned start_row, unsigned start_col,
           unsigned rows, unsigned cols, MatRef &orig) // sub-matrix
        : m_rows(rows)
        , m_cols(cols)
        , m_step(orig.m_step)
        , m_data(orig.m_data + orig.index(start_row, start_col))
    {
        assert(start_row+rows <= orig.m_rows && start_col+cols <= orig.m_cols);
    }
};

原始矩阵构造函数假定其backing参数指向一个数据元素数组,其长度至少为rows*cols,用于存储矩阵数据。矩阵的维度由数据成员m_rowsm_cols定义。

数据成员m_step表示从一行的开头到下一行的开头有多少数据元素。对于原始矩阵,这与m_cols相同。注意,子矩阵的m_cols可能小于它所引用的原始矩阵的m_step - 这就是子矩阵“跳过”原始矩阵中不属于子矩阵的元素的方式。为了使其正常工作,m_data必须与原始矩阵中的相同。

无论矩阵是否跳过元素,数据成员assert()始终指向矩阵的第一个元素。子矩阵构造函数中的{{1}}确保每个新子矩阵都适合从其派生的矩阵内部。


我不确定这是否算作“有趣的算法”,但它是一种定义和访问子矩阵的有效方便的方法。

答案 2 :(得分:1)

在数学上,您可以使用曲线分割矩阵,例如z曲线或peano曲线。这样你也会降低尺寸复杂度。 z曲线使用4个四边形来分割平面并类似于四叉树。

编辑:我刚刚得知它是z阶曲线而不是z曲线:http://en.wikipedia.org/wiki/Z-order_curve。 z曲线是bionformatics http://en.wikipedia.org/wiki/Z_curve中的3d值?大声笑!我不是生物信息学家,也不是维基百科,但听起来像胡说八道。 z有序曲线也可以覆盖3d区域。也许维基百科想说这个?以下是三维z次序曲线http://en.wikipedia.org/wiki/File:Lebesgue-3d-step3.png的大图。它甚至在维基百科上的文章?????