稀疏矩阵(Sparse Matirx):一个矩阵的大部分元素为零
对于稀疏矩阵而言,实际存储的数据项很少,如果用传统的二维数组的方式来存储稀疏矩阵,会十分浪费计算机的内存空间。
C=[[None]*N for row in range(N)]
提高内存空间利用率的方法就是利用三项式(3-tuple)的数据结构,把每一个非零项以(i,j,item-value)来表示。
就是假如一个稀疏矩阵有n个非零项,那么可以利用一个A(0:n,1:3)的二维数组来存储这些非零项,这样存储的矩阵叫压缩矩阵。其中,A(0,1)存储这个稀疏矩阵的行数,A(0,2)存储这个稀疏矩阵的列数,而A(0,3)则是此稀疏矩阵非零项的总数。另外,每一个非零项以(i,j,item-value)来表示:
i为此矩阵非零项所在的行数
j为此矩阵非零项所在的列数
item-value则为此矩阵非零的值
一、压缩稀疏矩阵
设计一个Python程序来利用三项式(3-tuple)数据结构,并压缩 6 x 6稀疏矩阵,以减少内存不必要的浪费
NONZERO=0#记录非零项个数
temp=1
#声明稀疏矩阵
Sparse=[[15,0,0,22,0,-15],[0,11,3,0,0,0],[0,0,0,-6,0,0],
[0,0,0,0,0,0],[91,0,0,0,0,0],[0,0,28,0,0,0]]
#声明压缩矩阵
Compress=[[None]*3 for row in range(9)]
print('稀疏矩阵的各个元素')
for i in range(6):
for j in range(6):
print('%d' %Sparse[i][j],end='\t')
if Sparse[i][j]!=0:
NONZERO=NONZERO+1
print()
#开始压缩稀疏矩阵
Compress[0][0]=6 #矩阵的行数
Compress[0][1]=6 #矩阵的列数
Compress[0][2]=NONZERO #矩阵非零项的总数
for i in range(6):
for j in range(6):
if Sparse[i][j]!=0:
Compress[temp][0]=i
Compress[temp][1]=j
Compress[temp][2]=Sparse[i][j]
temp=temp+1
print('稀疏矩阵压缩后的内容')
for i in range(NONZERO+1):
for j in range(3):
print('%d' %Compress[i][j],end='\t')
print()
运行结果:
二、稀疏矩阵的相关操作
例如:矩阵的转置
“转置矩阵”就是把原矩阵的行坐标元素与列坐标元素相互调换
A[i,j]转置=A[j,i]
如果直接将稀疏矩阵进行转置,只需要使用两个for循环,时间复杂度为O(columns x rows);
如果用三项式存储的压缩矩阵,它首先会确定在原稀疏矩阵中每一列的元素个数。
可以事先确定转置矩阵中每一行的起始位置,接着将原稀疏矩阵中的原素一个个的放到转置矩阵中的正确位置,这样做的时间复杂度O(columns+rows)三、上三角矩阵压缩为一维数组
上三角矩阵(Upper Triangle Matrix):就是一种对角线以下元素都为0的n x n矩阵;
又可分为右上三角矩阵(Right Upper Triangle Matr)与左上三角函数(Left Upper Triangle Matr);
右上三角矩阵:
共有非零项:
此二维矩阵的非零项可按序列映射到一维矩阵,且需要一个一维数组
来存储,映射方式分为以行为组与以列为主两种数组内存分配的方式;
以行为组:
假设有一个5X5的右上三角矩阵A,以行为主映射到一维数组B:
#上三角矩阵
global ARRAY_SIZE #矩阵的维数大小
ARRAY_SIZE=5
#一维数组的声明
num=int(ARRAY_SIZE*(ARRAY_SIZE+1)/2)
B=[None]*(num+1)
def getValue(i,j):
index=int(ARRAY_SIZE*i-i*(i+1)/2+j)
return B[index]
#上三角矩阵的内容
A=[[7,8,9,10,12],
[0,5,4,3,2],
[0,0,5,6,45],
[0,0,0,3,2],
[0,0,0,0,100]]
print(' -----------上三角矩阵----------------')
for i in range(ARRAY_SIZE):
for j in range(ARRAY_SIZE):
print('%d' %A[i][j],end='\t')
print()
#将右上三角矩阵压缩为一维数组
index=0
for i in range(ARRAY_SIZE):
for j in range(ARRAY_SIZE):
if(A[i][j]!=0):
index=index+1
B[index]=A[i][j]
1
print('---------以一维数组的方式表示-------------')
print('[',end=' ')
for i in range(ARRAY_SIZE):
for j in range(i+1,ARRAY_SIZE+1):
print('%d' %getValue(i,j),end=' ')
print(']')