在c++中压缩对称矩阵
Compressing a symmetrical matrix in c++
假设我们有一个对称矩阵。
A=
1 2 3
2 6 4
3 4 5
现在,因为它是对称的,我们不需要存储记忆里面所有的数字。让我们假设在左下三角形的单元格中设置0。
B =
1 2 3
0 6 4
0 0 5
如果我想访问B的0元素的内容,我所需要做的就是反转感兴趣的单元格的行和col:
if(i>j) val += L[j][i] // ex: B[1][0] is stored in B[0][1]
(假设目标是对所有未记忆的元素求和)
此时,我们只使用了右上角的三角形,但实际上并没有节省内存,因为未使用的元素仍然以0值分配。 节省内存的一种方法是使用vector of vector:vector<vector<int>> C;
,并相应地调整每行的大小。
C=
1 2 3
6 4
5
通过这样做,我们不能再使用交换技巧了,因为你可能会注意到空元素现在在矩阵的右下角三角形中。
则未分配的值为:
D=
x x x
x x 2
x 3 4
在这种情况下,我们感兴趣的元素可以通过if条件找到:
if(j >= size - i)
现在的问题是确定0个元素的正确内容。换句话说:
if(j >= size - i) ans += L[?][?]
例如,如果我在i=1 j=2我不应该访问元素[1][2]而是[0][2]=2(以此类推[2][1]-> [0][2]= 3,[2][2]-> [1][1]= 4)
如何实现?
您的问题可以通过存储左下方的三角形并丢弃右上方的三角形来解决:
1
2 6
3 4 5
索引操作可以实现为:
int operator()(int r, int c) const { return r >= c ? L[r][c] : L[c][r]; }
如果你真的想以移位的方式存储矩阵的右上角三角形(见C),那么你可以这样访问矩阵元素:
int operator()(int r, int c) const { return c >= r ? L[r][c-r] : L[c][r-c]; }
然而,如果你真的想从你的压缩中获得一些利益,我建议把整个三角形打包成一个单一的一维向量。使用向量的向量会增加相当大的开销…
要将这样的三角形数组存储在压缩的线性向量中,我使用以下类。
#define ogf_array_check(index, data_size) assert(index < data_size)
#define ogf_assert(b) assert(b)
/**
* A 2d array of values aij where only the cells such
* that j <= i are represented.
*/
template <class T> class TriangularArray {
public:
typedef TriangularArray<T> thisclass ;
TriangularArray(int size) : size_(size), data_size_(size * (size + 1) / 2) {
data_ = new T[data_size_] ;
}
~TriangularArray() { delete[] data_; data_ = nil ; }
int size() const { return size_ ; }
int data_size() const { return data_size_ ; }
/**
* index0 denotes the line, and index1 the column,
* note that index1 should be less-than or equal to
* index0.
*/
T& operator()(int index0, int index1) {
ogf_array_check(index0, size_) ;
ogf_array_check(index1, size_) ;
#ifdef OGF_ARRAY_BOUND_CHECK
ogf_assert(index1 <= index0) ;
#endif
int offset = index0 * (index0 + 1) / 2 ;
return data_[offset + index1] ;
}
/**
* index0 denotes the line, and index1 the column,
* note that index1 should be lerr or equal to
* index0.
*/
const T& operator()(int index0, int index1) const {
ogf_array_check(index0, size_) ;
ogf_array_check(index1, size_) ;
#ifdef OGF_ARRAY_BOUND_CHECK
ogf_assert(index1 <= index0) ;
#endif
int offset = index0 * (index0 + 1) / 2 ;
return data_[offset + index1] ;
}
void set_all(const T& value) {
for(int i=0; i<data_size_; i++) {
data_[i] = value ;
}
}
T& from_linear_index(int index) {
ogf_array_check(index, data_size_) ;
return data_[index] ;
}
const T& from_linear_index(int index) const {
ogf_array_check(index, data_size_) ;
return data_[index] ;
}
T* data() const { return data_ ; }
private:
T* data_ ;
int size_ ;
int data_size_ ;
private:
TriangularArray(const thisclass& rhs) ;
thisclass& operator=(const thisclass& rhs) ;
} ;
相关文章:
- C++中高效的大型稀疏块压缩线性方程
- 嵌入方指针压缩已禁用
- C++使用整数的压缩数组初始化对象
- 在C++中将函数压缩为两种方式
- 在C++中使用LZ4压缩目录
- 使用C++进行运行长度解压缩
- 为什么大多数 pair 实现默认不使用压缩(空基优化)?
- 捕获标准输出以压缩并使用 CTRL-C 中断会给出损坏的 zip 文件
- C++ 如何将数组值解压缩为函数参数
- struct.error:解压缩 C++ 结构时,解包需要 288 字节的缓冲区
- 在 Qt(C++) 中使用 QProcess 解压缩 - 提取目录问题
- 浏览压缩文件与游览解压缩它们
- 直接 2D 呈现到命令列表和打印:图片压缩
- 如何在 OpenCV c++ 中压缩 TIFF 格式的图像?
- 如何在C++向量中解压缩多个值
- 解压缩 C 样式数组以及C++中的参数包
- 用于 progmem 的C++和头文件压缩的 Web 文件字节数组
- 如何在 cpp 中解压缩数字,如果它们是使用 struct.pack(fmt, v1, v2, ..) 打包在 pyth
- 两个数字的对称配对功能
- 在c++中压缩对称矩阵