稀疏矩陣的存儲方法(DOK、LIL、COO、CSR, CRS)

存儲稀疏矩陣

經常用二維數組來存儲矩陣。 用數組的ai,ja_{i,j}可以用索引值iijj訪問。通常,ii是 行索引,從上往下編號,jj是列索引,從左到右進行編號。對於m×nm × n的矩陣,用這種格式存儲需要的內存和m×nm × n成比例。

對於稀疏矩陣,如果只存儲非零的數據,可以極大的節約內存。根據非零數據的數量和分佈情況,有不同的數據結構可以使用。需要權衡的是訪問單個元素時會比較複雜,並且需要額外的數據結構。

這些數據結構主要分爲兩組:

  • ˙支持高效修改的,如關鍵字字典DOK(Dictionary of keys)、LIL(List of List)或COO(Coordinate List)。它們通常用於構造矩陣。
  • 支持高效訪問和矩陣操作的那些,例如CSR(壓縮稀疏行)或CSC(壓縮稀疏列)。

關鍵字詞典(DOK)

DOK由一個將(行、列)作爲關鍵字映射到元素值的字典組成。字典中缺少的元素將被視爲零。這種格式有利於按隨機順序遞增地構造稀疏矩陣,但不利於按字典順序迭代非零值。通常用這種格式構造一個矩陣,然後轉換成另一種更有效的格式進行處理。

嵌套列表(LIL – List of List)

LIL每行存儲一個列表,每個條目包含列索引和值。通常,這些條目按列索引進行排序,以便更快地查找。這是另一種適合增量矩陣構造的格式。

座標列表(COO)

COO存儲(行、列、值)元組的列表。理想情況下,條目首先按行索引排序,然後按列索引排序,以提高隨機訪問時間。這是另一種適合增量矩陣構造的格式。

壓縮稀疏行(CSR、CRS或耶魯格式)

壓縮稀疏行(CSR)或壓縮行存儲(CRS)或Yale格式表示由三個(一維)數組組成的矩陣M,這些數組分別包含非零值、行的範圍和列索引。它類似於COO,但壓縮行索引,因此得名。這種格式允許快速行訪問和矩陣向量乘法(Mx)。CSR格式至少從20世紀60年代中期開始使用,第一次完整的描述出現在1967年

CSR格式使用三個(一維)數組(V,COL_INDEX,row_INDEX)以行的形式存儲稀疏m×n矩陣m。設NNZ表示M中非零項的數量(注意,此處應使用從零開始的索引)

  • 數組V和COL_INDEX的長度爲NNZ,分別包含這些值的非零值和列索引。
  • 數組ROW_INDEX在矩陣中每行有一個元素,並在給定行開始的地方將索引編碼爲V。(它可能包含一個設置爲NNZ的額外結束元素)。

例如,矩陣

(0000580000300600)\left( \begin{array}{cc} 0& 0 & 0 & 0 \\ 5 & 8 & 0 & 0 \\ 0 & 0 & 3 & 0 \\ 0 & 6 & 0 & 0 \end{array} \right)
是具有4個非零元素的4×4矩陣,因此

V=[5 8 3 6]
COL_INDEX=[0 1 2 1]
ROW_INDEX=[0 0 2 3]

假設是索引是從0開始的語言。
要提取行,我們首先定義:

row_start=ROW_INDEX[row]
row_end=ROW_INDEX[row+1]

然後我們從V和COL_INDEX中提取切片,從row_start到row_end。

爲了訪問這個矩陣的行1(第二行),我們設置row_start=0和row_end=2。然後我們將切片V[0:2]=[5,8]和COL_INDEX[0:2]=[0,1]。我們現在知道,在第1行的第0列和第1列有兩個元素,值分別爲5和8。

在這種情況下,CSR表示用了13個條目,而原始矩陣中只有16個條目。只有當NNZ<mn11/2NNZ<(m(n−1)–1 /2時,CSR格式纔會節約內存。另一個例子,矩陣

(10200000300400000050607000000080)\left( \begin{array}{cc} 10 & 20 & 0 & 0 & 0 & 0 \\ 30 & 0 & 40 & 0 & 0 & 0 \\ 0 & 0 & 50 & 60 & 70 & 0 \\ 0 & 0 & 0 & 0 & 0 & 80 \end{array} \right)
是一個有8個非零元素的4×6矩陣(24個元素),所以

   V         = [ 10 20 30 40 50 60 70 80 ]
   COL_INDEX = [  0  1  1  3  2  3  4  5 ]   
   ROW_INDEX = [  0  2  4  7  8 ]

整個存儲爲21個條目。

ROW_INDEX將數組V拆分成行:(10,20)(30,40)(50,60,70)(80);

列索引確定這些值的列:(10,20,…)(0,30,0,40,…)(0,0,50,60,70,0)(0,0,0,0,0,80)。
注意,在這種格式中,ROW_INDEX的第一個值始終爲零,最後一個值始終爲NNZ,因此它們在某種意義上是冗餘的(儘管在需要顯式存儲數組長度的編程語言中,NNZ不會是冗餘的)。儘管如此,這確實避免了在計算每一行的長度時處理異常情況的需要,因爲這保證了公式rowINDEX[i+1]rowINDEX[i]row_INDEX[i+1]-row_INDEX[i]對任何一行i都有效。此外,對於足夠大的矩陣來說,此冗餘存儲的內存成本是微不足道的。

耶魯稀疏矩陣格式(新版或舊版)是CSR方案的實例。舊的Yale格式與上面描述的完全一樣,有三個數組;新的格式將ROW_INDEX和COL_INDEX組合成一個數組,並分別處理矩陣的對角線。

對於邏輯鄰接矩陣,可以省略數據數組,因爲行數組中的元素的存在足以建模二元鄰接關係。

它被稱爲耶魯格式,可能因爲它是在1977年耶魯大學計算機科學系的耶魯稀疏矩陣包報告中提出的。

壓縮稀疏列(CSC或CCS)

CSC與CSR類似,不同之處在於首先按列讀取值,爲每個值存儲一個行索引,並存儲列指針。例如,CSC是(val,row_ind,col_ptr),其中val是矩陣的(從上到下,然後從左到右)非零值的數組;row_ind是對應於這些值的行索引;col_ptr是每列開始的val索引的列表。該名稱基於列索引信息相對於COO格式進行壓縮的事實。一種通常使用另一種格式(LIL、DOK、COO)進行構建。這種格式對於算術運算、列切片和矩陣向量積是有效的。見scipy.sparse.csc_矩陣. 這是在MATLAB中指定稀疏矩陣的傳統格式(通過稀疏函數)。

參考文獻
https://en.wikipedia.org/wiki/Sparse_matrix

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章