在C ++中,我必须在RAM中保存一个非常大的方阵,该矩阵由零的约90%(零的真实频率取决于用户输入)组成。为所有这些零分配内存将浪费RAM。
怎么可以创建一个使用少量RAM的类,并且方便地将equals(Set<T> s)
之类的元素放到这个大矩阵中?
答案 0 :(得分:2)
有很多方法可以去。但首先要考虑的是,在执行此操作时,您将获得良好的性能,因为访问元素将变得更加复杂。其次,你将无法使用像LAPACK这样的着名库,因为据我所知,它们没有为这种复杂的数据结构提供任何接口。所以,每次你想做一些数学运算时,你必须要解压缩你的矩阵并将其展平,否则你将不得不重新开发执行你想做的操作的代码,这不是一件容易的事情。去做。做LAPACK的人多年来一直在研究这个问题。
我所说的是:在此之前考虑后果。
现在提到后果后,我可以提出一个方法。
那么有很多方法可以实现,每种方法都有不同的计算复杂性,这取决于你的应用程序,让我提一些方法:
您可以使用linked list,其中每个元素都可以是std::pair
,包含当前矩阵元素的值,以及下一个可用元素的索引。
您可以使用链接列表,您可以使用某些压缩软件的工作方式,并计算每个元素之前有多少个零,并将其存储在每个元素的容器中。
< / 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;
}