Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 如何高效地存储具有高度冗余值的矩阵_Algorithm_Data Structures_Sparse Matrix_Matrix Multiplication - Fatal编程技术网

Algorithm 如何高效地存储具有高度冗余值的矩阵

Algorithm 如何高效地存储具有高度冗余值的矩阵,algorithm,data-structures,sparse-matrix,matrix-multiplication,Algorithm,Data Structures,Sparse Matrix,Matrix Multiplication,我有一个非常大的矩阵(100M行乘以100M列),它有很多重复的值,它们紧挨着彼此。例如: 8 8 8 8 8 8 8 8 8 8 8 8 8 8 4 8 8 1 1 1 1 1 8 8 8 8 8 4 8 8 1 1 1 1 1 8 8 8 8 8 4 8 8 1 1 1 1 1 8 8 8 8 8 4 8 8 1 1 1 1 1 8 8 8 8 8 4 8 8 1 1 1 1 1 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 3 3 3 3 3 3 3 3 3

我有一个非常大的矩阵(100M行乘以100M列),它有很多重复的值,它们紧挨着彼此。例如:

8 8 8 8 8 8 8 8 8 8 8 8 8
8 4 8 8 1 1 1 1 1 8 8 8 8
8 4 8 8 1 1 1 1 1 8 8 8 8
8 4 8 8 1 1 1 1 1 8 8 8 8
8 4 8 8 1 1 1 1 1 8 8 8 8
8 4 8 8 1 1 1 1 1 8 8 8 8
8 8 8 8 8 8 8 8 8 8 8 8 8
8 8 3 3 3 3 3 3 3 3 3 3 3
我想要一个数据结构/算法来尽可能紧凑地存储这样的矩阵。例如,上面的矩阵应该只占用O(1)空间(即使矩阵被任意拉伸),因为只有固定数量的矩形区域,其中每个区域只有一个值

重复在行和列之间都会发生,因此逐行压缩矩阵的简单方法不够好。(这将需要最少的O(num_行)空间来存储任何矩阵。)


矩阵的表示也需要逐行访问,以便我可以对列向量执行矩阵乘法。

您可以将矩阵存储为包含单个值的叶子。可以把这看作是一个二维的“运行”值。

如果您的数据确实是规则的,那么以结构化格式存储数据可能会使您受益匪浅;e、 g.示例矩阵可能存储为以下“填充矩形”说明列表:

(0,0)-(13,7) = 8
(4,1)-(8,5)  = 1

(然后,要查找特定单元格的值,您需要在列表中向后迭代,直到找到包含该单元格的矩形)

对于您显示的矩阵,我没有具体的答案。在有限元分析(FEA)中,矩阵包含冗余数据。在我的UnderGrad项目中实现FEA包时,我使用了skyline存储方法

一些链接:


最简单的方法是在一个维度上使用游程编码,而不用担心另一个维度

(如果数据集不是那么巨大,那么将其解释为图像并使用标准的无损图像压缩方法也会非常简单——但由于您必须致力于使算法在稀疏矩阵上工作,因此不会那么简单。)

另一个简单的方法是尝试矩形泛光填充——从右上角的像素开始,将其增大到最大的矩形(宽度优先);然后将所有这些像素标记为“完成”,并取右上角剩余的像素,重复操作直到完成。(您可能希望将这些矩形存储在某种BSP或四叉树中。)


一种高效的技术——虽然不是最优的,但可能已经足够好了——是使用一个二进制空间分区树,其中“空间”不是通过空间来衡量的,而是通过变化的数量来衡量的。您可以递归地进行剪切,以便在左侧和右侧(或顶部和底部——可能您希望保持正方形)有相同数量的更改,并且随着尺寸变小,您可以剪切尽可能多的更改。最终,你会把两个长方形分开,每个长方形都有相同的数字;然后停下来。(通过RLE在x和y中编码将快速告诉您更改点在哪里。)

首先要尝试的始终是现有的库和解决方案。让自定义格式与最终需要的所有操作一起工作是一项艰巨的工作。稀疏矩阵是一个老问题,所以一定要阅读现有的东西

假设您没有找到合适的格式,我建议使用基于行的格式。不要对超紧凑表示法太过花哨,代码中的每一个小操作和bug都需要大量处理。相反,尝试分别压缩每一行。你知道你将不得不扫描每一行的矩阵向量乘法,让生活变得简单


我将从运行长度编码开始,首先看看它是如何工作的。一旦成功,尝试添加一些技巧,如对前一行的节的引用。所以一行可以被编码为:126个零,8个1,1000个直接从上面的行复制的条目,32个零。对于您给出的示例,这似乎非常有效。

以上许多解决方案都很好

如果您正在处理文件,请考虑面向文件 压缩工具,如compress、bzip、zip、bzip2和friends。 它们工作得非常好,尤其是当数据包含冗余数据时 ASCII字符。使用外部压缩工具可以消除 代码中的问题和挑战,并将压缩 二进制和ASCII数据

在您的示例中,显示的是一个字符的数字。 数字0-9可以用较小的四位表示 编码模式。您可以在中使用附加位 一个字节作为计数。四位给了你额外的代码 逃到临时演员。。。但有一点值得注意 回到使用两个字符的旧千年虫 一年。来自ofset的字节编码将给出 255年,相同的两个字节将跨越所有已写入的
历史,然后是一些。

您可能想看看它的压缩算法。把你的矩阵想象成一个位图…

你对100M x 100M大小矩阵的O(1)空间的描述令人困惑。当你有一个有限的矩阵,那么你的大小是一个常数(除非生成矩阵的程序没有改变它)。因此,存储所需的空间量也是一个常数,即使将其与标量相乘。当然,读取和写入矩阵的时间不会是O(1)

稀疏矩阵是我可以想到的,它可以减少存储这样一个矩阵所需的空间量。您可以将此稀疏矩阵写入文件并将其存储为tar.gz,这将进一步压缩数据


我有一个问题,100米的米代表什么?它是指兆字节/百万吗?如果是,此矩阵大小将为100 x 10^6 x 100 x 10^6字节=10^16/10^6 MB=10^10/10^6 TB=10^4 TB!!!你在用什么样的机器?

你知道。。。。间隔树

区间树是一种高效存储区间并查询它们的方法。一个泛化就是广告,它可以是广告
0,0-n,n --> 8
4,4-7,7 --> 1
8,8-8,n --> 3
A
| w0 w1 w2 |
| x0 x1 x2 |
| y0 y1 y2 |
| z0 z1 z2 |
A’
| w0 w1 w2 x0 x1 x2 y0 y1 y2 z0 z1 z2 |
0 | 8 8 8 8 8 8 8 8 8 8 8 8 8 |
1 | 8 4 8 8 1 1 1 1 1 8 8 8 8 |
2 | 8 4 8 8 1 1 1 1 1 8 8 8 8 |
3 | 8 4 8 8 1 1 1 1 1 8 8 8 8 |
4 | 8 4 8 8 1 1 1 1 1 8 8 8 8 |
5 | 8 4 8 8 1 1 1 1 1 8 8 8 8 |
6 | 8 8 8 8 8 8 8 8 8 8 8 8 8 |
7 | 8 8 3 3 3 3 3 3 3 3 3 3 3 |
0 | 8{13}                    |
1 | 8{1} 4{1} 8{2} 1{5} 8{4} |
2 | 8{1} 4{1} 8{2} 1{5} 8{4} |
3 | 8{1} 4{1} 8{2} 1{5} 8{4} |
4 | 8{1} 4{1} 8{2} 1{5} 8{4} |
5 | 8{1} 4{1} 8{2} 1{5} 8{4} |
6 | 8{13}                    |
7 | 8{2} 3{11}               |
A: 5 (1-5) | 8{1} 4{1} 8{2} 1{5} 8{4} |
B: 2 (0,6) | 8{13}                    |
C: 1    7  | 8{2} 3{11}               |
    0|1
   /   \
  A    0|1
      /   \
     B     C
    0   1   2   3   4   5   6   7
  =================================
0 | 3   3   3   3   3   3   3   3 |
  |-------+               +-------|
1 | 4   4 | 3   3   3   3 | 4   4 |
  |       +-----------+---+       |
2 | 4   4 | 5   5   5 | 1 | 4   4 |
  |       |           |   |       |
3 | 4   4 | 5   5   5 | 1 | 4   4 |
  |---+---|           |   |       |
4 | 5 | 0 | 5   5   5 | 1 | 4   4 |
  |   |   +---+-------+---+-------|
5 | 5 | 0   0 | 2   2   2   2   2 |
  |   |       |                   |
6 | 5 | 0   0 | 2   2   2   2   2 |
  |   |       +-------------------|
7 | 5 | 0   0   0   0   0   0   0 |
  =================================
    0   1   2   3   4   5   6   7
  =================================
0 | 3 | 3 |       |       | 3 | 3 |
  |---+---|   3   |   3   |---+---|
1 | 4 | 4 |       |       | 4 | 4 |
  |-------+-------|-------+-------|
2 |       |       | 5 | 1 |       |
  |   4   |   5   |---+---|   4   |
3 |       |       | 5 | 1 |       |
  |---------------+---------------|
4 | 5 | 0 | 5 | 5 | 5 | 1 | 4 | 4 |
  |---+---|---+---|---+---|---+---|
5 | 5 | 0 | 0 | 2 | 2 | 2 | 2 | 2 |
  |-------+-------|-------+-------|
6 | 5 | 0 | 0 | 2 | 2 | 2 | 2 | 2 |
  |---+---+---+---|---+---+---+---|
7 | 5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
  =================================

0 +- 0 +- 0 -> 3
  |    +- 1 -> 3
  |    +- 2 -> 4
  |    +- 3 -> 4
  +- 1      -> 3
  +- 2      -> 4
  +- 3      -> 5
1 +- 0      -> 3
  +- 1 +- 0 -> 3
  |    +- 1 -> 3
  |    +- 2 -> 4
  |    +- 3 -> 4
  +- 2 +- 0 -> 5
  |    +- 1 -> 1
  |    +- 2 -> 5
  |    +- 3 -> 1
  +- 3      -> 4
2 +- 0 +- 0 -> 5
  |    +- 1 -> 0
  |    +- 2 -> 5
  |    +- 3 -> 0
  +- 1 +- 0 -> 5
  |    +- 1 -> 5
  |    +- 2 -> 0
  |    +- 3 -> 2
  +- 2 +- 0 -> 5
  |    +- 1 -> 0
  |    +- 2 -> 5
  |    +- 3 -> 0
  +- 3 +- 0 -> 0
       +- 1 -> 2
       +- 2 -> 0
       +- 3 -> 0
3 +- 0 +- 0 -> 5
  |    +- 1 -> 1
  |    +- 2 -> 2
  |    +- 3 -> 2
  +- 1 +- 0 -> 4
  |    +- 1 -> 4
  |    +- 2 -> 2
  |    +- 3 -> 2
  +- 2 +- 0 -> 2
  |    +- 1 -> 2
  |    +- 2 -> 0
  |    +- 3 -> 0
  +- 3 +- 0 -> 2
       +- 1 -> 2
       +- 2 -> 0
       +- 3 -> 0

((1*4) + 3) + ((2*4) + 2) + (4 * 8) = 49 leaf nodes 
49 * (2 + 1) = 147 (2 * 8 bit indexer, 1 byte data)
+ 14 inner nodes -> 2 * 14 bytes (2 * 8 bit indexers)
= 175 Bytes
    0   1   2   3   4   5   6   7
  =================================
0 | 3   3   3   3   3   3   3   3 |
  |-------+---------------+-------|
1 | 4   4 | 3   3   3   3 | 4   4 |
  |       +-----------+---+       |
2 | 4   4 | 5   5   5 | 1 | 4   4 |
  |       |           |   |       |
3 | 4   4 | 5   5   5 | 1 | 4   4 |
  |---+---|           |   |       |
4 | 5 | 0 | 5   5   5 | 1 | 4   4 |
  |   + - +---+-------+---+-------|
5 | 5 | 0   0 | 2   2   2   2   2 |
  |   |       |                   |
6 | 5 | 0   0 | 2   2   2   2   2 |
  |   +-------+-------------------|
7 | 5 | 0   0   0   0   0   0   0 |
  =================================

0: (4,1; 4,1), (5,1; 6,2), (7,1; 7,7)         | 3
1: (2,5; 4,5)                                 | 1
2: (5,3; 6,7)                                 | 1
3: (0,0; 0,7), (1,2; 1,5)                     | 2
4: (1,0; 3,1), (1,6; 4,7)                     | 2
5: (2,2; 4,4), (4,0; 7,0)                     | 2
0   | 3 {8}                                 | 1
1   | 4 {2} | 3 {4} | 4 {2}                 | 2
2,3 | 4 {2} | 5 {3} | 1 {1} | 4 {2}         | 4
4   | 5 {1} | 0 {1} | 5 {3} | 1 {1} | 4 {2} | 5
5,6 | 5 {1} | 0 {2} | 2 {5}                 | 3
7   | 5 {1} | 0 {7}                         | 2


RLE Data:    (1 + 3+ 4 + 5 + 3 + 2) * 2 = 36
Bit Stream:   20 bits packed into 3 bytes = 3
Huffman Tree: 10 nodes * 3 = 30
= 69 Bytes
3{8};4{2};3{4};4{4};5{3};1{1};4{4};5{3};1{1};4{2};5{1};0{1};
5{3};1{1};4{2};5{1};0{2};2{5};5{1};0{2};2{5};5{1};0{7}

= 2 * 23 = 46 Bytes
3{8};
4{2};3{4};
4{4};5{3};1{1};
4{4};5{3};
1{1};4{2};5{1};0{1};5{3};
1{1};4{2};5{1};0{2};2{5};
5{1};0{2};2{5};
5{1};0{7}

0 + 0 -> 3{8};4{2};3{4};
  + 1 -> 4{4};5{3};1{1};

1 + 0 -> 4{2};5{1} + 0 -> 0{1};5{3};1{1};
  |                + 1 -> 0{2}
  |
  + 1 -> 2{5};5{1} + 0 -> 0{2};
                   + 1 -> 0{7}

3{8};4{2};3{4}           | 00
4{4};5{3};1{1}           | 01
4{4};5{3};1{1}           | 01
4{2};5{1};0{1};5{3};1{1} | 100
4{2};5{1};0{2}           | 101
2{5};5{1};0{2}           | 110
2{5};5{1};0{7}           | 111

Bit stream: 000101100101110111
RLE Data:  16 * 2 = 32
Tree:   : 5 * 2 = 10 
Bit stream: 18 bits in 3 bytes = 3
= 45 bytes
A = [1 -1  0  0  0]
    [0  1 -1  0  0]
    [0  0  1 -1  0]
    [0  0  0  1 -1]
    [0  0  0  0  1]
B = [1 1 1 1 1]
    [0 1 1 1 1]
    [0 0 1 1 1]
    [0 0 0 1 1]
    [0 0 0 0 1]
Mv = B AMA B v