包含许多零的矩阵的数据结构?

时间:2016-10-16 21:30:02

标签: c++ performance memory matrix data-structures

在C ++中,我必须在RAM中保存一个非常大的方阵,该矩阵由零的约90%(零的真实频率取决于用户输入)组成。为所有这些零分配内存将浪费RAM。

怎么可以创建一个使用少量RAM的类,并且方便地将equals(Set<T> s)之类的元素放到这个大矩阵中?

4 个答案:

答案 0 :(得分:2)

有很多方法可以去。但首先要考虑的是,在执行此操作时,您将获得良好的性能,因为访问元素将变得更加复杂。其次,你将无法使用像LAPACK这样的着名库,因为据我所知,它们没有为这种复杂的数据结构提供任何接口。所以,每次你想做一些数学运算时,你必须要解压缩你的矩阵并将其展平,否则你将不得不重新开发执行你想做的操作的代码,这不是一件容易的事情。去做。做LAPACK的人多年来一直在研究这个问题。

我所说的是:在此之前考虑后果。

现在提到后果后,我可以提出一个方法。

  1. 将你的矩阵想象成一个扁平数组,在column major中排序(因此在内存中的列后面),在内存中是连续的。
  2. 现在这个矩阵是一个有很多零的列表。你的问题是:我们如何消除这些零?
  3. 那么有很多方法可以实现,每种方法都有不同的计算复杂性,这取决于你的应用程序,让我提一些方法:

    • 您可以使用linked list,其中每个元素都可以是std::pair,包含当前矩阵元素的值,以及下一个可用元素的索引。

      < / LI>
    • 您可以使用链接列表,您可以使用某些压缩软件的工作方式,并计算每个元素之前有多少个零,并将其存储在每个元素的容器中。

      < / LI>

    你知道,有很多方法可以去......我可以思考并猜测另外几个。但问问自己:你正在寻找的计算复杂性是什么?

    希望这有帮助。

答案 1 :(得分:0)

您可以使用特征库进行稀疏矩阵操作。这是链接:https://eigen.tuxfamily.org/dox/group__TutorialSparse.html

Eigen是一个高性能的线性代数库。稀疏矩阵存储为2D链表(或者我应该说是网络)。每个非零条目都有两个指针,一个指向同一行的下一个非零条目,另一个指向同一列的下一个非零条目。基于迭代地将稀疏矩阵乘以矢量的矩阵乘积和许多其他线性albegra操作可以在2D链表表示中有效地完成。

答案 2 :(得分:0)

如果您不需要动态修改矩阵,则可以使用CRS格式(压缩行存储),参见[1]。它比其他答案中建议的链表更紧凑,需要额外的空间来存储指针。它在许多软件库中实现,例如另一个答案中引用的SuiteSparse [2]和Eigen [3],以及我自己的OpenNL库[4]。如果需要在矩阵中动态插入元素,那么它就更复杂了。我经常使用一组动态分配的行(每个I一个)。每行存储J值对。这种结构也在OpenNL [4]中实现。

[1] https://en.wikipedia.org/wiki/Sparse_matrix

[2] http://faculty.cse.tamu.edu/davis/suitesparse.html

[3] http://eigen.tuxfamily.org/

[4] http://alice.loria.fr/software/geogram/doc/html/nl_8h.html

答案 3 :(得分:-3)

猜猜你可以创建一个保存地图中所有内容的课程。因此,如果您请求一个非现有元素,则返回0,否则返回元素

#include <map>

using namespace std;

#define ROW_LENGTH 10;

map<int, int> entries = map<int, int>();

int getElement(int row, int column) {
  int key = column * ROW_LENGTH + row;

  if (entries.find(key) == entries.end()) {
    return 0;
  } else {
    return entries[key];
  }
}
void setElement(int row, int column, int value) {
  int key = column * ROW_LENGTH + row;

  entries[key] = value;
}