欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > 三角矩阵和对称阵的压缩存储

三角矩阵和对称阵的压缩存储

2025/4/19 3:10:22 来源:https://blog.csdn.net/xuchaoxin1375/article/details/144335662  浏览:    关键词:三角矩阵和对称阵的压缩存储

文章目录

    • 矩阵的存储
    • 对称矩阵
    • 三角阵
      • 三角阵的压缩
      • 下三角矩阵
        • 按行优先
        • 按列优先
      • 上三角矩阵
        • 按行优先
        • 按列优先
    • `A[0...][0...]` vs `A[1...][1...]`

矩阵的存储

  • 对于多维数组,有两种映射方法:按行优先和按列优先。
    A n = ( a 11 a 12 ⋯ a 1 n a 21 a 22 ⋯ a 2 n ⋮ ⋮ ⋱ ⋮ a n 1 a n 2 ⋯ a n n ) A_{n}= \begin{pmatrix} a_{11}& a_{12}& \cdots & a_{1n} \\ a_{21}& a_{22}& \cdots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{n1}& a_{n2}& \cdots & a_{nn} \end{pmatrix} An= a11a21an1a12a22an2a1na2nann

  • 以二维数组为例

    • 按行优先存储的基本思想是:先行后列,先存储行号较小的元素,行号相等先存储列号较小的元素。对于上述 A n A_{n} An,存储顺序为 a 11 , a 12 , ⋯ , a n n a_{11},a_{12},\cdots,a_{nn} a11,a12,,ann
      • 设二维数组的行下标与列下标的范围分别为 [ 0 , h 1 , ] , [ 0 , h 2 ] [0,h_{1},],[0,h_2] [0,h1,],[0,h2],则存储结构关系式为 L o c ( a i j ) = L o c ( a 00 ) + ( i ( h 2 + 1 ) + j ) L \rm{Loc(a_{ij})}=Loc(a_{00})+(i(h_{2}+1)+j)L Loc(aij)=Loc(a00)+(i(h2+1)+j)L
    • 按优先存储,存储顺序为 a 11 , a 21 , ⋯ , a n n a_{11},a_{21},\cdots,a_{nn} a11,a21,,ann
      • L o c ( a i j ) = L o c ( a 00 ) + ( j ( h 1 + 1 ) + i ) L \rm{Loc(a_{ij})}=Loc(a_{00})+(j(h_{1}+1)+i)L Loc(aij)=Loc(a00)+(j(h1+1)+i)L
    • 其中 [ i ( h 2 + 1 ) + j ] [i(h_{2}+1)+j] [i(h2+1)+j], [ j ( h 1 + 1 ) + i ] [j(h_{1}+1)+i] [j(h1+1)+i]是偏移数组首地址的元素数量,再乘以单个元素所占存储单元数 L = s i z e o f ( E l e m T y p e ) L=\rm{sizeof(ElemType)} L=sizeof(ElemType),即可得到 L o c ( a i j ) \rm{Loc(a_{ij})} Loc(aij)

对称矩阵

对称矩阵的定义及其存储方式。

对称矩阵是指一个 n n n 阶矩阵 A A A 中的任意一个元素 a i j a_{ij} aij 都有 a i j = a j i a_{ij} = a_{ji} aij=aji 1 ≤ i , j ≤ n 1 \leq i, j \leq n 1i,jn),即矩阵与其转置相等。对称矩阵的元素可以划分为三个部分:上三角区、主对角线和下三角区

对于 n n n 阶对称矩阵,上三角区的所有元素和下三角区的对应元素相同。若仍采用二维数组存放,则会浪费几乎一半的空间。因此,可以将 n n n 阶对称矩阵 A A A 存放在一维数组 B [ n ( n + 1 ) / 2 ] B[n(n+1)/2] B[n(n+1)/2] 中,即元素 a i j a_{ij} aij 存放在 b k b_k bk 中。比如只存放下半部分(含主对角线)的元素。

在数组 B B B 中,位于元素 a i j a_{ij} aij i ≥ j i \geq j ij)前面的元素个数为:

  • 1 1 1 行: 1 1 1 个元素( a 1 , 1 a_{1,1} a1,1)。
  • 2 2 2 行: 2 2 2 个元素( a 2 , 1 , a 2 , 2 a_{2,1}, a_{2,2} a2,1,a2,2)。
  • ……
  • i − 1 i-1 i1 行: i − 1 i-1 i1 个元素( a i − 1 , 1 , a i − 1 , 2 , ⋯ , a i − 1 , j − 1 a_{i-1,1}, a_{i-1,2}, \cdots, a_{i-1,j-1} ai1,1,ai1,2,,ai1,j1)。
  • i i i 行: j − 1 j-1 j1 个元素( a i , 1 , a i , 2 , ⋯ , a i , j − 1 a_{i,1}, a_{i,2}, \cdots, a_{i,j-1} ai,1,ai,2,,ai,j1)。

因此,元素 a i j a_{ij} aij 在数组 B B B 中的下标 k = 1 + 2 + ⋯ + ( i − 1 ) + j − 1 k = 1 + 2 + \cdots + (i-1) + j-1 k=1+2++(i1)+j1= i ( i − 1 ) / 2 + j − 1 i(i-1)/2 + j-1 i(i1)/2+j1(数组下标从 0 0 0 开始)

k ( i , j ) k(i,j) k(i,j)= i ( i − 1 ) / 2 + j − 1 i(i-1)/2 + j-1 i(i1)/2+j1, ( i ⩾ j ) (i\geqslant{j}) (ij)(1)

上面讨论的是下三角内 a i j a_{ij} aij, ( i ⩾ j ) (i\geqslant{j}) (ij)条件下的 i , j , k i,j,k i,j,k关系式,给出了 a i j , ( i ⩾ j ) a_{ij},(i\geqslant{j}) aij,(ij)存储到B中的位置索引 k k k,即 B [ k ] = a i j B[k]=a_{ij} B[k]=aij,

在压缩对称阵的时候,可以仅遍历矩阵的下三角形以及主对角线部分的元素;上三角部分的元素不用遍历,就可以存储这个矩阵的元素的完整信息,可以无损解压出来

那么 i < j i<j i<j的情况下 i , j , k i,j,k i,j,k之间的关系又是如何?或者说若 a i j , ( i < j ) a_{ij},(i<j) aij,(i<j) a i j a_{ij} aij对应于数组B中的索引为 k k k的元素,那么 k , i , j k,i,j k,i,j之间满足什么关系

注意到对称矩阵的特点: a i , j = a j , i a_{i,j}=a_{j,i} ai,j=aj,i,这样就可以将 i < j i<j i<j的情况转换到 i > j i>j i>j的情况

i < j i<j i<j j > i j>i j>i,所以 a j i a_{ji} aji满足公式(1)的条件, k ( j , i ) k(j,i) k(j,i)= j ( j − 1 ) / 2 + i − 1 j(j-1)/2+i-1 j(j1)/2+i1, ( j > i ) (j>i) (j>i)

综上元素下标 i , j , k i,j,k i,j,k之间的对应关系如下:
k = { i ( i − 1 ) 2 + j − 1 , i ⩾ j j ( j − 1 ) 2 + i − 1 , i < j k = \begin{cases} \frac{i(i-1)}{2} + j-1, & i \geqslant j \\ \frac{j(j-1)}{2} + i-1, & i < j \end{cases} k={2i(i1)+j1,2j(j1)+i1,iji<j
对称阵和其他特殊矩阵不同,对称阵上三角按列优先存储和下三角按行优先存储到一维数组B时序列是一样的;

因此对称阵中遇到上三角案列优先存储的问题,可以考虑转换为对应的按行优先存储的情况来解决,并且,无论哪种存储, a i j a_{ij} aij= a j i a_{ji} aji,当 i > j i>j i>j时总是可以考虑转换为 a j i a_{ji} aji来处理

对于对称阵上三角按列优先存储, a i j a_{ij} aij存储在 B [ k ] B[k] B[k],则 k = 1 + 2 + ⋯ + ( j − 1 ) + i − 1 k=1+2+\cdots+(j-1)+i-1 k=1+2++(j1)+i1= 1 2 j ( j − 1 ) + i − 1 \frac{1}{2}j(j-1)+i-1 21j(j1)+i1, ( i ⩽ j ) (i\leqslant{j}) (ij), k = 1 2 i ( i − 1 ) + j − 1 k=\frac{1}{2}i(i-1)+j-1 k=21i(i1)+j1, ( i > j ) (i>j) (i>j)

例如 a 7 , 2 a_{7,2} a7,2, k = 1 2 × 7 × 6 + 1 k=\frac{1}{2}\times7\times{6}+1 k=21×7×6+1=22

三角阵

和对称阵的压缩类似,以下三角为例,将元素的下三角和住对角线元素压缩到数组,但是上三角部分元素都是相同且无法通过下三角矩阵推出,需要存储到数组中,对于 n n n阶三角阵,压缩需要的一维数组长度为 1 2 n ( n + 1 ) + 1 \frac{1}{2}n(n+1)+1 21n(n+1)+1,比对称真要多1

三角阵的压缩

  • 三角矩阵(方阵) A [ 1... n ] [ 1... n ] A[1...n][1...n] A[1...n][1...n],包括
    • 上三角矩阵(下三角所有元为同一个常量) j ⩽ i j\leqslant i ji
    • 下三角矩阵(上三角所有元素为同一个常量) i ⩽ j i\leqslant j ij
  • 上下三角包含 n ( n + 1 ) 2 个元素 ; 在加上 ( 占据矩阵其余位置的 ) 一个常量 c 上下三角包含\frac{n(n+1)}{2}个元素;在加上(占据矩阵其余位置的)一个常量c 上下三角包含2n(n+1)个元素;在加上(占据矩阵其余位置的)一个常量c
  • 所以需要一个大小 至少 ‾ 为 n ( n + 1 ) 2 + 1 维的数组来保存必要元素 所以需要一个大小\underline{至少}为\frac{n(n+1)}{2}+1维的数组来保存必要元素 所以需要一个大小至少2n(n+1)+1维的数组来保存必要元素
    • A [ 1 , . . . , n ] [ 1 , . . . , n ] ; B [ 1... 1 2 n ( n + 1 ) + 1 ] A[1,...,n][1,...,n];B[1...\frac{1}{2}{n(n+1)}+1] A[1,...,n][1,...,n];B[1...21n(n+1)+1]

下三角矩阵

按行优先

推到过程和存储下三角对称阵过程几乎一样
k = { i ( i − 1 ) 2 + j − 1 , i ⩾ j 1 2 n ( n + 1 ) , i < j k = \begin{cases} \frac{i(i-1)}{2} + j-1, & i \geqslant j \\ \frac{1}{2}n(n+1), & i < j \end{cases} k={2i(i1)+j1,21n(n+1),iji<j
这里 i < j i<j i<j的情况是上三角中的元素,上三角中的元素都存储在B[0...n(n+1)/2]中的最后一个元素中,索引为 1 2 n ( n + 1 ) \frac{1}{2}{n}(n+1) 21n(n+1)

如果数组B从1开始计数,那么对上述公式加1即可

按列优先

和按行优先存储的上三角矩阵压缩的推导几乎一样,可以先参考该节

j j j j j j列需要进入数组B的元素个数
1 n n n
2 n − 1 n-1 n1
3 3 3 n − 2 n-2 n2
j − 1 j-1 j1 n − ( j − 2 ) n-(j-2) n(j2)
i i i b i ⩽ n − ( i − 1 ) b_{i}\leqslant n-(i-1) bin(i1)

s j − 1 s_{j-1} sj1= 1 2 ( n + ( n − ( j − 2 ) ) ) ( j − 1 ) \frac{1}{2}(n+(n-(j-2)))(j-1) 21(n+(n(j2)))(j1)= 1 2 ( 2 n − j + 2 ) ( j − 1 ) \frac{1}{2}(2n-j+2)(j-1) 21(2nj+2)(j1)

j j j列需要入数组的元素数量为 b j = i − j + 1 b_{j}=i-j+1 bj=ij+1,(由于是下三角, i ⩾ j i\geqslant{j} ij)

k k k= s j − 1 + ( i − j ) s_{j-1}+(i-j) sj1+(ij)= 1 2 ( 2 n − j + 2 ) ( j − 1 ) + ( i − j ) \frac{1}{2}(2n-j+2)(j-1)+(i-j) 21(2nj+2)(j1)+(ij),B[0...n(n+1)/2]

k k k= 1 2 ( 2 n − j + 2 ) ( j − 1 ) + ( i − j ) + 1 \frac{1}{2}(2n-j+2)(j-1)+(i-j)+1 21(2nj+2)(j1)+(ij)+1,B[1...n(n+1)/2+1]

上三角矩阵

分别讨论按行优先和按列优先存储下, i , j , k i,j,k i,j,k的关系

按行优先
i i i i i i行需要进入数组B的元素个数 b i b_{i} bi(行 i i i上属于上三角的元素的个数)
1 n n n
2 n − 1 n-1 n1
3 3 3 n − 2 n-2 n2
i − 1 i-1 i1 n − ( i − 2 ) n-(i-2) n(i2)
i i i b i ⩽ n − ( i − 1 ) b_{i}\leqslant n-(i-1) bin(i1)

上面的表格中,第 i i i行实际上不一定填满,利用第 i i i行的公式,带入 i − 1 i-1 i1得出第 i − 1 i-1 i1行需要入B数组的元素个数: n − i + 2 n-i+2 ni+2

累计前 i − 1 i-1 i1行的元素的入数组B的元素个数(为了讨论方便,后续省略入数组B这几个字,直接用元素数量称呼),这是个等差数列求和问题, s i − 1 s_{i-1} si1= 1 2 ( n + ( n − i + 2 ) ) ( i − 1 ) \frac{1}{2}(n+(n-i+2))(i-1) 21(n+(ni+2))(i1)= 1 2 ( i − 1 ) ( 2 n − i + 2 ) \frac{1}{2}(i-1)(2n-i+2) 21(i1)(2ni+2),利用的求和公式中没有公差的 s n = 1 2 ( a 1 + a n ) n s_{n}=\frac{1}{2}(a_{1}+a_{n})n sn=21(a1+an)n(注意这里项数 n = i − 1 n=i-1 n=i1,对应的是求和前 i − 1 i-1 i1行的元素数量)

然后单独计算第 i i i行的元素数量,这时候 b i = j − i + 1 b_{i}=j-i+1 bi=ji+1,第 i i i行中 a i j a_{ij} aij前面的元素为 j − i j-i ji;

因此 a i j a_{ij} aij存入数组B[0...n(n+1)/2]后的索引为

  • k k k= s i − 1 + b i − 1 s_{i-1}+b_{i}-1 si1+bi1= 1 2 ( i − 1 ) ( 2 n − i + 2 ) + ( j − i ) \frac{1}{2}(i-1)(2n-i+2)+(j-i) 21(i1)(2ni+2)+(ji), ( i ⩽ j ) (i\leqslant{j}) (ij) 主对角线和上三角区域

  • k = n ( n + 1 ) 2 k=\frac{n(n+1)}{2} k=2n(n+1), ( j < i ) (j<i) (j<i),下三角区域

使用条件大括号描述
k 0 ( i , j ) = { ( i − 1 ) ( 2 n − i + 2 ) 2 + j − i ; ( i ⩽ j ) n ( n + 1 ) 2 ; ( j < i ) k_0(i,j)=\begin{cases} \frac{(i-1)(2n-i+2)}{2}+j-i ;(i\leqslant j) \\\frac{n(n+1)}{2};(j<i) \end{cases} k0(i,j)={2(i1)(2ni+2)+ji;(ij)2n(n+1);(j<i)

下三角区域的元素取值都一样,因此总是将值存放到同一个位置,这个位置一般设置在数组B的最后一个位置(数组的长度为 n ( n + 1 ) 2 + 1 \frac{n(n+1)}{2}+1 2n(n+1)+1,数组B从0开始计数(B[0...n(n+1)/2],那么最后一个元素的索引就是 n ( n + 1 ) 2 \frac{n(n+1)}{2} 2n(n+1)

如果是存入B[1...n(n+1)/2+1],公式会发生变换

  • k 1 = S i − 1 + s i k_1=S_{i-1}+s_i k1=Si1+si= 1 2 ( i − 1 ) ( 2 n − i + 2 ) + ( j − i + 1 ) \frac{1}{2}(i-1)(2n-i+2)+(j-i+1) 21(i1)(2ni+2)+(ji+1), ( i ⩽ j ) (i\leqslant{j}) (ij)

  • k 1 k_{1} k1= n ( n + 1 ) 2 + 1 \frac{n(n+1)}{2}+1 2n(n+1)+1, ( j < i ) (j<i) (j<i)

按列优先

案列优先存储上三角矩阵的上三角部分和对角线元素,推导过程和按行存储类似

j j j j j j列需要进入数组B的元素个数
1 1 1 1
2 2 2 2
3 3 3 3 3 3
j − 1 j-1 j1 j − 1 j-1 j1
j j j ⩽ j \leqslant j j

先计算前 j − 1 j-1 j1列需要压缩的元素数量, s j − 1 s_{j-1} sj1= 1 2 ( 1 + ( j − 1 ) ) ( j − 1 ) \frac{1}{2}(1+(j-1))(j-1) 21(1+(j1))(j1)= 1 2 j ( j − 1 ) \frac{1}{2}j(j-1) 21j(j1)

j j j列的元素数量为 i i i;

所以 k ( i , j ) k(i,j) k(i,j)= 1 2 j ( j − 1 ) + i − 1 \frac{1}{2}j(j-1)+i-1 21j(j1)+i1,(B[0...n(n+1)/2])

若存入B[1...n(n+1)/2+1],则 k ( i , j ) k(i,j) k(i,j)= 1 2 j ( j − 1 ) + i \frac{1}{2}j(j-1)+i 21j(j1)+i

A[0...][0...] vs A[1...][1...]

  • 前面的公式都是在 i ∈ [ 1 , n ] , j ∈ [ 1 , n ] i\in[1,n],j\in[1,n] i[1,n],j[1,n]情况下推导的
  • 有时矩阵的坐标是从0开始的: i ∈ [ 0 , n ] , j ∈ [ 0 , n ] i\in[0,n],j\in[0,n] i[0,n],j[0,n]
    • 如果矩阵是A[0...][0...],第一个元素是 a 00 a_{00} a00,那么相关公式不能直接使用
    • 幸运的是,这个调整比较简单,只需要将 i , j i,j i,j直接映射 i + 1 , j + 1 i+1,j+1 i+1,j+1就可以了

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词