119

Click here to load reader

第 17 次课 5.3.2 稀疏矩阵

  • Upload
    faxon

  • View
    151

  • Download
    3

Embed Size (px)

DESCRIPTION

第 17 次课 5.3.2 稀疏矩阵 什么是稀疏矩阵?简单说,设矩阵 A 中有 s 个非零元素,若 s 远远小于矩阵元素的总数(即 s≦m×n ),则称 A 为稀疏矩阵。精确点,设在的矩阵 A 中,有 s 个非零元素。令 e=s/(m*n) ,称 e 为矩阵的稀疏因子。通常认为 e≦0.05 时称之为稀疏矩阵。 - PowerPoint PPT Presentation

Citation preview

Page 1: 第 17 次课 5.3.2 稀疏矩阵

第 17次课5.3.2 稀疏矩阵

什么是稀疏矩阵?简单说,设矩阵 A 中有 s 个非零元素,若 s 远远小于矩阵元素的总数(即 s m×n≦ ),则称 A 为稀疏矩阵。精确点,设在的矩阵 A 中,有 s个非零元素。令 e=s/(m*n) ,称 e 为矩阵的稀疏因子。通常认为 e 0.05≦ 时称之为稀疏矩阵。

在存储稀疏矩阵时,为了节省存储单元,很自然地想到使用压缩存储方法。但由于非零元素的分布一般是没有规律的,因此在存储非零元素的同时,还必须同时记下它所在的行和列的位置( i,j) 。反之,一个三元组 (i,j,aij) 唯一确定了矩阵 A 的一个非零元。因此,稀疏矩阵可由表示非零元的三元组及其行列数唯一确定。

Page 2: 第 17 次课 5.3.2 稀疏矩阵

例如,下列三元组表((1,2,12)(1,3,9),(3,1,- 3),(3,6,14),(4,3,24), (5,2,18),(6,1,15),(6,4,-7))

加上 (6,7) 这一对行、列值便可作为下列矩阵 M的另一种描述。

0 12 9 0 0 0 0

0 0 0 0 0 0 0

-3 0 0 0 0 14 0

0 0 24 0 0 0 0

0 18 0 0 0 0 0

15 0 0 -7 0 0 0

Page 3: 第 17 次课 5.3.2 稀疏矩阵

而由上述三元组表的不同表示方法可引出稀疏矩阵不同的压缩存储方法。1. 三元组表示

假设以前面学过的顺序存储结构来表示三元组表,则可得到稀疏矩阵的一种压缩存储方法——三元顺序表。

设 A 为 TSMatrix 型的结构变量,图 5.5 中所示的稀疏矩阵的三元组的表示如下:

Page 4: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

Page 5: 第 17 次课 5.3.2 稀疏矩阵

下面以矩阵的转置为例,说明在这种压缩存储结构上如何实现矩阵的运算。 一个 m×n 的矩阵 A ,它的转置 B 是一个 n×m 的矩阵,且 a[i][j]=b[j][i] , 0 i m≦ ≦ , 0 j n≦ ≦ ,即 A 的行是 B 的列, A的列是 B 的行。 将 A 转置为 B ,就是将 A 的三元组表 a.data 置换为表 B的三元组表 b.data ,如果只是简单地交换 a.data 中 i 和 j 的内容,那么得到的 b.data 将是一个按列优先顺序存储的稀疏矩阵 B ,要得到按行优先顺序存储的 b.data ,就必须重新排列三元组的顺序。 由于 A 的列是 B 的行,因此,按 a.data 的列序转置,所得到的转置矩阵 B 的三元组表 b.data 必定是按行优先存放的。

按这种方法设计的算法,其基本思想是:对 A 中的每一列 col(0 col n-1)≦ ≦ ,通过从头至尾扫描三元表 a.data ,找出所有列号等于 col 的那些三元组,将它们的行号和列号互换后依次放入 b.data 中,即可得到 B 的按行优先的压缩存储表示。

Page 6: 第 17 次课 5.3.2 稀疏矩阵

三元组表示的稀疏矩阵的转置

Page 7: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

第 一 趟

不为 1 ,考察下一

Page 8: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

第 一 趟

不为 1 ,考察下一

Page 9: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

第 一 趟

为 1 ,填入到右表

Page 10: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

1 3 -3

第 一 趟

Page 11: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

1 3 -3

第 一 趟

不为 1 ,考察下一

Page 12: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

1 3 -3

第 一 趟

不为 1 ,考察下一

Page 13: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

1 3 -3

第 一 趟

不为 1 ,考察下一

Page 14: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

1 3 -3

第 一 趟

为 1 ,填入到右表

Page 15: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

1 3 -3

1 6 15

第 一 趟

Page 16: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

1 3 -3

1 6 15

第 一 趟

不为 1 ,且已经是最后一个,本趟结束

Page 17: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

1 3 -3

1 6 15

第 二 趟

为 2 ,写入右表

Page 18: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

1 3 -3

1 6 15

2 1 12

第 二 趟

Page 19: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

1 3 -3

1 6 15

2 1 12

第 二 趟

不为 2 ,考察下一

Page 20: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

1 3 -3

1 6 15

2 1 12

第 二 趟

不为 2 ,考察下一

Page 21: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

1 3 -3

1 6 15

2 1 12

第 二 趟

不为 2 ,考察下一

Page 22: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

1 3 -3

1 6 15

2 1 12

第 二 趟

不为 2 ,考察下一

Page 23: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

1 3 -3

1 6 15

2 1 12

第 二 趟

为 2 ,写入右表

Page 24: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

1 3 -3

1 6 15

2 1 12

2 5 18

第 二 趟

Page 25: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

1 3 -3

1 6 15

2 1 12

2 5 18

第 二 趟

不为 2 ,考察下一

Page 26: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

1 3 -3

1 6 15

2 1 12

2 5 18

第 二 趟

不为 2 ,且到达最后,

本趟结束

Page 27: 第 17 次课 5.3.2 稀疏矩阵

同理找出转置后行号为 3 、 4 、5 、 6 的元组。

Page 28: 第 17 次课 5.3.2 稀疏矩阵

矩阵转置算法如下:#include <iostream>#include<vector>// 顺序表模板using namespace std;class Triple// 定义一个三元组类{public:

int i,j; int e;

public:Triple(){}Triple(int row,int col,int elem){

i=row,j=col,e=elem;}~Triple(){}

};

Page 29: 第 17 次课 5.3.2 稀疏矩阵

class TSMatrix// 存储三元组的顺序表类{public:

vector<Triple> data;// 存储三元组int mu,nu,tu;// 矩阵的行数、列数、非零元个数

public:TSMatrix(){mu=nu=tu=0;};TSMatrix(int row,int col){

mu=row,nu=col,tu=0;}void InsertTriple(Triple elem){

data.push_back(elem);tu=data.size();

}void print(){

for(int i=0;i<data.size();i++)cout<<data[i].i<<" "<<data[i].j<<" "<<data[i].e<<endl;

}};

Page 30: 第 17 次课 5.3.2 稀疏矩阵

void TransposeSMatrix(TSMatrix M,TSMatrix& N)// 矩阵转置{

N.mu=M.mu,N.nu=M.nu;if(M.tu){

int total,col;for(col=0;col<M.nu;col++){

for(total=0;total<M.tu;total++){

int j=M.data[total].j;if(j==col){

Triple p=M.data[total];Triple temp(p.j,p.i,p.e);N.InsertTriple(temp);

}

}}

}}

Page 31: 第 17 次课 5.3.2 稀疏矩阵

int main(int argc, char* argv[]){

struct element{int i,j,e;};element s[8]={{1,2,12},{1,3,9},{3,1,-3},{3,6,14},{4,3,24},{5,2,18},{6,1,15},{6,4,-7}};int row=6,colum=7;TSMatrix m(row,colum),t;for(int i=0;i<=7;i++){

m.InsertTriple(Triple(s[i].i,s[i].j,s[i].e));}cout<<"Matrix M is:"<<endl;m.print();::TransposeSMatrix(m,t);cout<<"Matrix T is:"<<endl;t.print();return 0;

}

Page 32: 第 17 次课 5.3.2 稀疏矩阵

分析这个算法,主要的工作是在 total 和 col 的两个循环中完成的,故算法的时间复杂度为O(t*n) ,即矩阵的列数和非零元的个数的乘积成正比。而一般传统矩阵的转置算法为: for(col=0;col<=n-1;++col) for(row=0;row<=m;++row) t[col][row]=m[row][col]; 其时间复杂度为 O(n*m) 。当非零元素的个数 t 和 m*n 同数量级时,算法 transmatrix 的时间复杂度为 O(m*n2) 。三元组顺序表虽然节省了存储空间,但时间复杂度比一般矩阵转置的算法还要复杂,同时还有可能增加算是法的难度。因此,此算法仅适用于 t<<m*n 的情况。

Page 33: 第 17 次课 5.3.2 稀疏矩阵

有一种称为快速转置的算法,他对上述算法进行改造,增加了一些空间,但是却能使算法的时间复杂度达到 O(n*m) 。由于快速转置算法并没有改变矩阵的存储结构,只是在算法上面采用了一些技巧,所以我们在此不再赘述,仅介绍其基本思想。有兴趣的同学可以参考课本。

Page 34: 第 17 次课 5.3.2 稀疏矩阵

快速转置

Page 35: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

通过对待转置三元组的一趟扫描可以得到矩阵中每列有几个元素,也就是转置后每行有几个元素。

列 1 2 3 4 5 6 7

元素数 0 0 0 0 0 0 0

Page 36: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

通过对待转置三元组的一趟扫描可以得到矩阵中每列有几个元素,也就是转置后每行有几个元素。

列 1 2 3 4 5 6 7

元素数 0 0 0 0 0 0 0

Page 37: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

通过对待转置三元组的一趟扫描可以得到矩阵中每列有几个元素,也就是转置后每行有几个元素。

列 1 2 3 4 5 6 7

元素数 0 1 0 0 0 0 0

Page 38: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

通过对待转置三元组的一趟扫描可以得到矩阵中每列有几个元素,也就是转置后每行有几个元素。

列 1 2 3 4 5 6 7

元素数 0 1 0 0 0 0 0

Page 39: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

通过对待转置三元组的一趟扫描可以得到矩阵中每列有几个元素,也就是转置后每行有几个元素。

列 1 2 3 4 5 6 7

元素数 0 1 1 0 0 0 0

Page 40: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

通过对待转置三元组的一趟扫描可以得到矩阵中每列有几个元素,也就是转置后每行有几个元素。

列 1 2 3 4 5 6 7

元素数 0 1 1 0 0 0 0

Page 41: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

通过对待转置三元组的一趟扫描可以得到矩阵中每列有几个元素,也就是转置后每行有几个元素。

列 1 2 3 4 5 6 7

元素数 1 1 1 0 0 0 0

Page 42: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

通过对待转置三元组的一趟扫描可以得到矩阵中每列有几个元素,也就是转置后每行有几个元素。

列 1 2 3 4 5 6 7

元素数 1 1 1 0 0 0 0

Page 43: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

通过对待转置三元组的一趟扫描可以得到矩阵中每列有几个元素,也就是转置后每行有几个元素。

列 1 2 3 4 5 6 7

元素数 1 1 1 0 0 1 0

Page 44: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

通过对待转置三元组的一趟扫描可以得到矩阵中每列有几个元素,也就是转置后每行有几个元素。

列 1 2 3 4 5 6 7

元素数 1 1 1 0 0 1 0

Page 45: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

通过对待转置三元组的一趟扫描可以得到矩阵中每列有几个元素,也就是转置后每行有几个元素。

列 1 2 3 4 5 6 7

元素数 1 1 2 0 0 1 0

Page 46: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

通过对待转置三元组的一趟扫描可以得到矩阵中每列有几个元素,也就是转置后每行有几个元素。

列 1 2 3 4 5 6 7

元素数 1 1 2 0 0 1 0

Page 47: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

通过对待转置三元组的一趟扫描可以得到矩阵中每列有几个元素,也就是转置后每行有几个元素。

列 1 2 3 4 5 6 7

元素数 1 2 2 0 0 1 0

Page 48: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

通过对待转置三元组的一趟扫描可以得到矩阵中每列有几个元素,也就是转置后每行有几个元素。

列 1 2 3 4 5 6 7

元素数 1 2 2 0 0 1 0

Page 49: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

通过对待转置三元组的一趟扫描可以得到矩阵中每列有几个元素,也就是转置后每行有几个元素。

列 1 2 3 4 5 6 7

元素数 2 2 2 0 0 1 0

Page 50: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

通过对待转置三元组的一趟扫描可以得到矩阵中每列有几个元素,也就是转置后每行有几个元素。

列 1 2 3 4 5 6 7

元素数 2 2 2 0 0 1 0

Page 51: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

通过对待转置三元组的一趟扫描可以得到矩阵中每列有几个元素,也就是转置后每行有几个元素。

列 1 2 3 4 5 6 7

元素数 2 2 2 1 0 1 0

Page 52: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

根据每列元素的个数,可以算出来每列的第一个元素在转置后的表中的位置。如:如果第一列的第一个元素存储位置为 0 的话,那么第二列的第一个元素的存储位置应该为: 0+ 第一列元素的个数;同理第三列的第一个元素的位置应该为:第二列的第一个元素的位置 + 第二列元素的个数。

列 1 2 3 4 5 6 7

元素数 2 2 2 1 0 1 0

Page 53: 第 17 次课 5.3.2 稀疏矩阵

列 1 2 3 4 5 6 7

元素数 2 2 2 1 0 1 0

各列第一个元素在转置后元组中存储位置的求法:

列 1 2 3 4 5 6 7

首元素数地址: cpot

0

Page 54: 第 17 次课 5.3.2 稀疏矩阵

列 1 2 3 4 5 6 7

元素数 2 2 2 1 0 1 0

各列第一个元素在转置后元组中存储位置的求法:

列 1 2 3 4 5 6 7

首元素数地址: cpot

0 2

Page 55: 第 17 次课 5.3.2 稀疏矩阵

列 1 2 3 4 5 6 7

元素数 2 2 2 1 0 1 0

各列第一个元素在转置后元组中存储位置的求法:

列 1 2 3 4 5 6 7

首元素数地址: cpot

0 2 4

Page 56: 第 17 次课 5.3.2 稀疏矩阵

列 1 2 3 4 5 6 7

元素数 2 2 2 1 0 1 0

各列第一个元素在转置后元组中存储位置的求法:

列 1 2 3 4 5 6 7

首元素数地址: cpot

0 2 4 6

Page 57: 第 17 次课 5.3.2 稀疏矩阵

列 1 2 3 4 5 6 7

元素数 2 2 2 1 0 1 0

各列第一个元素在转置后元组中存储位置的求法:

列 1 2 3 4 5 6 7

首元素数地址: cpot

0 2 4 6 7

Page 58: 第 17 次课 5.3.2 稀疏矩阵

列 1 2 3 4 5 6 7

元素数 2 2 2 1 0 1 0

各列第一个元素在转置后元组中存储位置的求法:

列 1 2 3 4 5 6 7

首元素数地址: cpot

0 2 4 6 7 7

Page 59: 第 17 次课 5.3.2 稀疏矩阵

列 1 2 3 4 5 6 7

元素数 2 2 2 1 0 1 0

各列第一个元素在转置后元组中存储位置的求法:

列 1 2 3 4 5 6 7

首元素数地址: cpot

0 2 4 6 7 7 8

Page 60: 第 17 次课 5.3.2 稀疏矩阵

有了此表后,我们通过一次扫描就可以把三元组进行转置。当第 2 列的第一个元素被扫描出来且存入到合适位置后,那么第二个元素将成为未被扫描的第一个元素,且其位置是原第一个元素位置加 1 。

列 1 2 3 4 5 6 7

首元素数地址: cpot

0 2 4 6 7 7 8

Page 61: 第 17 次课 5.3.2 稀疏矩阵

快速转置过程列 1 2 3 4 5 6 7首元素数地址: cpot 0 2 4 6 7 7 8

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

0

1

2

3

4

5

6

7

Page 62: 第 17 次课 5.3.2 稀疏矩阵

快速转置过程列 1 2 3 4 5 6 7首元素数地址: cpot 0 3 4 6 7 7 8

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

0

1

2 2 1 12

3

4

5

6

7

Page 63: 第 17 次课 5.3.2 稀疏矩阵

快速转置过程列 1 2 3 4 5 6 7首元素数地址: cpot 0 3 4 6 7 7 8

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

0

1

2 2 1 12

3

4

5

6

7

Page 64: 第 17 次课 5.3.2 稀疏矩阵

快速转置过程列 1 2 3 4 5 6 7首元素数地址: cpot 0 3 5 6 7 7 8

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

0

1

2 2 1 12

3

4 3 1 9

5

6

7

Page 65: 第 17 次课 5.3.2 稀疏矩阵

快速转置过程列 1 2 3 4 5 6 7首元素数地址: cpot 0 3 5 6 7 7 8

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

0

1

2 2 1 12

3

4 3 1 9

5

6

7

Page 66: 第 17 次课 5.3.2 稀疏矩阵

快速转置过程列 1 2 3 4 5 6 7首元素数地址: cpot 1 3 5 6 7 7 8

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

0 1 3 -3

1

2 2 1 12

3

4 3 1 9

5

6

7

Page 67: 第 17 次课 5.3.2 稀疏矩阵

快速转置过程列 1 2 3 4 5 6 7首元素数地址: cpot 1 3 5 6 7 7 8

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

0 1 3 -3

1

2 2 1 12

3

4 3 1 9

5

6

7

Page 68: 第 17 次课 5.3.2 稀疏矩阵

快速转置过程列 1 2 3 4 5 6 7首元素数地址: cpot 1 3 5 6 7 8 8

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

0 1 3 -3

1

2 2 1 12

3

4 3 1 9

5

6

7 6 3 14

Page 69: 第 17 次课 5.3.2 稀疏矩阵

快速转置过程列 1 2 3 4 5 6 7首元素数地址: cpot 1 3 5 6 7 8 8

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

0 1 3 -3

1

2 2 1 12

3

4 3 1 9

5

6

7 6 3 14

Page 70: 第 17 次课 5.3.2 稀疏矩阵

快速转置过程列 1 2 3 4 5 6 7首元素数地址: cpot 1 3 6 6 7 8 8

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

0 1 3 -3

1

2 2 1 12

3

4 3 1 9

5 3 4 24

6

7 6 3 14

Page 71: 第 17 次课 5.3.2 稀疏矩阵

快速转置过程列 1 2 3 4 5 6 7首元素数地址: cpot 1 3 6 6 7 8 8

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

0 1 3 -3

1

2 2 1 12

3

4 3 1 9

5 3 4 24

6

7 6 3 14

Page 72: 第 17 次课 5.3.2 稀疏矩阵

快速转置过程列 1 2 3 4 5 6 7首元素数地址: cpot 1 4 6 6 7 8 8

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

0 1 3 -3

1

2 2 1 12

3 2 5 18

4 3 1 9

5 3 4 24

6

7 6 3 14

Page 73: 第 17 次课 5.3.2 稀疏矩阵

快速转置过程列 1 2 3 4 5 6 7首元素数地址: cpot 1 4 6 6 7 8 8

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

0 1 3 -3

1

2 2 1 12

3 2 5 18

4 3 1 9

5 3 4 24

6

7 6 3 14

Page 74: 第 17 次课 5.3.2 稀疏矩阵

快速转置过程列 1 2 3 4 5 6 7首元素数地址: cpot 2 4 6 6 7 8 8

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

0 1 3 -3

1 1 6 15

2 2 1 12

3 2 5 18

4 3 1 9

5 3 4 24

6

7 6 3 14

Page 75: 第 17 次课 5.3.2 稀疏矩阵

快速转置过程列 1 2 3 4 5 6 7首元素数地址: cpot 2 4 6 6 7 8 8

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

0 1 3 -3

1 1 6 15

2 2 1 12

3 2 5 18

4 3 1 9

5 3 4 24

6

7 6 3 14

Page 76: 第 17 次课 5.3.2 稀疏矩阵

快速转置过程列 1 2 3 4 5 6 7首元素数地址: cpot 2 4 6 7 7 8 8

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

0 1 3 -3

1 1 6 15

2 2 1 12

3 2 5 18

4 3 1 9

5 3 4 24

6 4 6 -7

7 6 3 14

Page 77: 第 17 次课 5.3.2 稀疏矩阵

快速转置过程列 1 2 3 4 5 6 7首元素数地址: cpot 2 4 6 7 7 8 8

i j e

1 2 12

1 3 9

3 1 -3

3 6 14

4 3 24

5 2 18

6 1 15

6 4 -7

i j e

0 1 3 -3

1 1 6 15

2 2 1 12

3 2 5 18

4 3 1 9

5 3 4 24

6 4 6 -7

7 6 3 14

转置过程结束。

Page 78: 第 17 次课 5.3.2 稀疏矩阵

二、带行表的三元组矩阵的乘法:已知三元组表示的矩阵 M ( 6*7 )、 N

( 7*6 )如下

Page 79: 第 17 次课 5.3.2 稀疏矩阵

M: i j e

1 2 1

1 3 1

3 1 1

3 6 1

4 3 1

5 2 1

6 1 1

6 4 1

N: i j e

1 3 1

1 6 1

2 1 1

2 5 1

3 1 1

3 4 1

4 6 1

6 3 1

现在要计算他们的乘积 Q( 6*6),该如何运算。

Page 80: 第 17 次课 5.3.2 稀疏矩阵

我们知道:Q ( 1 , 1 ) =M(1,1)*N(1,1)+M(1,2)*N(2,1)+M(1,3)*N(3,1)+…M(1,7)*N(7,1)+是一个累加的过程。同理 Q ( 1 , 2 )、 Q( 1 , 3 )… ..Q ( 1 , 6 )都是累加和。我们看一下,求 Q 的第一行元素的处理过程。这个过程只涉及到 M 的第一行元素,却可能涉及到 N 的所有元素。

Page 81: 第 17 次课 5.3.2 稀疏矩阵

矩阵相乘

Page 82: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 1

1 3 1

3 1 1

3 6 1

4 3 1

5 2 1

6 1 1

6 4 1

i j e

1 3 1

1 6 1

2 1 1

2 5 1

3 1 1

3 4 1

4 6 1

6 3 1

1 2 3 4 5 6

0 0 0 0 0 0sum

Page 83: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 1

1 3 1

3 1 1

3 6 1

4 3 1

5 2 1

6 1 1

6 4 1

i j e

1 3 1

1 6 1

2 1 1

2 5 1

3 1 1

3 4 1

4 6 1

6 3 1

1 2 3 4 5 6

0 0 0 0 0 0sum

Page 84: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 1

1 3 1

3 1 1

3 6 1

4 3 1

5 2 1

6 1 1

6 4 1

i j e

1 3 1

1 6 1

2 1 1

2 5 1

3 1 1

3 4 1

4 6 1

6 3 1

1 2 3 4 5 6

1 0 0 0 0 0sum

Page 85: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 1

1 3 1

3 1 1

3 6 1

4 3 1

5 2 1

6 1 1

6 4 1

i j e

1 3 1

1 6 1

2 1 1

2 5 1

3 1 1

3 4 1

4 6 1

6 3 1

1 2 3 4 5 6

1 0 0 0 0 0sum

Page 86: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 1

1 3 1

3 1 1

3 6 1

4 3 1

5 2 1

6 1 1

6 4 1

i j e

1 3 1

1 6 1

2 1 1

2 5 1

3 1 1

3 4 1

4 6 1

6 3 1

1 2 3 4 5 6

1 0 0 0 1 0sum

Page 87: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 1

1 3 1

3 1 1

3 6 1

4 3 1

5 2 1

6 1 1

6 4 1

i j e

1 3 1

1 6 1

2 1 1

2 5 1

3 1 1

3 4 1

4 6 1

6 3 1

1 2 3 4 5 6

1 0 0 0 1 0sum

Page 88: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 1

1 3 1

3 1 1

3 6 1

4 3 1

5 2 1

6 1 1

6 4 1

i j e

1 3 1

1 6 1

2 1 1

2 5 1

3 1 1

3 4 1

4 6 1

6 3 1

1 2 3 4 5 6

1 0 0 0 1 0sum

Page 89: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 1

1 3 1

3 1 1

3 6 1

4 3 1

5 2 1

6 1 1

6 4 1

i j e

1 3 1

1 6 1

2 1 1

2 5 1

3 1 1

3 4 1

4 6 1

6 3 1

1 2 3 4 5 6

2 0 0 0 1 0sum

Page 90: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 1

1 3 1

3 1 1

3 6 1

4 3 1

5 2 1

6 1 1

6 4 1

i j e

1 3 1

1 6 1

2 1 1

2 5 1

3 1 1

3 4 1

4 6 1

6 3 1

1 2 3 4 5 6

2 0 0 0 1 0sum

Page 91: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 1

1 3 1

3 1 1

3 6 1

4 3 1

5 2 1

6 1 1

6 4 1

i j e

1 3 1

1 6 1

2 1 1

2 5 1

3 1 1

3 4 1

4 6 1

6 3 1

1 2 3 4 5 6

2 0 0 1 1 0sum

Page 92: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 1

1 3 1

3 1 1

3 6 1

4 3 1

5 2 1

6 1 1

6 4 1

i j e

1 3 1

1 6 1

2 1 1

2 5 1

3 1 1

3 4 1

4 6 1

6 3 1

1 2 3 4 5 6

2 0 0 1 1 0sum

此时 Q 的第 1行元素已经存

在 sum 中

Page 93: 第 17 次课 5.3.2 稀疏矩阵

1 2 3 4 5 6

2 0 0 1 1 0sum

i j e

1 1 2

Q

Page 94: 第 17 次课 5.3.2 稀疏矩阵

1 2 3 4 5 6

2 0 0 1 1 0sum

i j e

1 1 2

Q

Page 95: 第 17 次课 5.3.2 稀疏矩阵

1 2 3 4 5 6

2 0 0 1 1 0sum

i j e

1 1 2

Q

Page 96: 第 17 次课 5.3.2 稀疏矩阵

1 2 3 4 5 6

2 0 0 1 1 0sum

i j e

1 1 2

1 4 1

Q

Page 97: 第 17 次课 5.3.2 稀疏矩阵

1 2 3 4 5 6

2 0 0 1 1 0sum

i j e

1 1 2

1 4 1

1 5 1

Q

Page 98: 第 17 次课 5.3.2 稀疏矩阵

1 2 3 4 5 6

2 0 0 1 1 0sum

i j e

1 1 2

1 4 1

1 5 1

Q

Page 99: 第 17 次课 5.3.2 稀疏矩阵

这是如何求 Q 中的第一行元素,同理可以求其他各行元素。经过分析可以发现,算法的时间将会浪费在如何在 M 、N 中确定元组的范围。比如下面的 M 中 i=1 的元组的范围,N 中 i=2 的元组的范围。如果每次都采取顺序扫描的话,将会非常浪费时间。

i j e

1 2 1

1 3 1

3 1 1

3 6 1

4 3 1

5 2 1

6 1 1

6 4 1

i j e

1 3 1

1 6 1

2 1 1

2 5 1

3 1 1

3 4 1

4 6 1

6 3 1

Page 100: 第 17 次课 5.3.2 稀疏矩阵

为了解决这个问题,可以像求矩阵的转置而引入列表一样,引进一个行表,则问题将会变得简单了。

i j e

1 2 1

1 3 1

3 1 1

3 6 1

4 3 1

5 2 1

6 1 1

6 4 1

i j e

1 3 1

1 6 1

2 1 1

2 5 1

3 1 1

3 4 1

4 6 1

6 3 1

Page 101: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 1

1 3 1

3 1 1

3 6 1

4 3 1

5 2 1

6 1 1

6 4 1

行号 1 2 3 4 5 6

行中元素个数

其求解过程跟求列表相似,不再赘述。

Page 102: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 1

1 3 1

3 1 1

3 6 1

4 3 1

5 2 1

6 1 1

6 4 1

行号 1 2 3 4 5 6

行中元素个数 2 0 2 1 1 2

同理可以求每行第一个元素在三元组表中的位置。

Page 103: 第 17 次课 5.3.2 稀疏矩阵

i j e

1 2 1

1 3 1

3 1 1

3 6 1

4 3 1

5 2 1

6 1 1

6 4 1

行号 1 2 3 4 5 6

行中元素个数 2 0 2 1 1 2

行号 1 2 3 4 5 6

行中首元素位置 rpos 0 2 2 4 5 6

那么我们想求第一行所有元素的范围时,可以如下来计算:

第一行第一个元素的位置为: rpos[1]

第一行最后一个元素的位置为: rpos[2]-1

同理,求其它各行元素的范围也是如此。

这样寻找各行元素的范围就容易得多了,算法的时间复杂度就能够降低。

Page 104: 第 17 次课 5.3.2 稀疏矩阵

矩阵相乘的思想介绍完毕

Page 105: 第 17 次课 5.3.2 稀疏矩阵

带行表的三元组表。其类型描述如下:#include<vector>using namespace std;class Triple// 三元组类{public:

int i,j; int e;

public:Triple(){}Triple(int row,int col,int elem){

i=row,j=col,e=elem;}~Triple(){}

};

Page 106: 第 17 次课 5.3.2 稀疏矩阵

class RLSMatrix{public:

vector<Triple> data;vector<int> rpos;//rpos[i] 的值表示第 i 行的第一

个元素在 data 数组中的位置int mu,nu,tu;// 矩阵的行数、列数、非零元个数

public:RLSMatrix(){mu=nu=tu=0;};RLSMatrix(int row,int col){ mu=row,nu=col,tu=0; }void InsertTriple(Triple temp){ data.push_back(temp);tu=data.size();}

Page 107: 第 17 次课 5.3.2 稀疏矩阵

void MakeRpos(){//初始化 rpos 数组

vector<int> num(mu+1);for(int i=0;i<=mu;i++)

num[i]=0;for(i=0;i<data.size();i++){//num[row] 记录了第 row 行共有多少个非 0 元素

int row=data[i].i;num[row]++;

}rpos.resize(mu+1);

rpos[1]=0;for(i=2;i<rpos.size();i++)

rpos[i]=rpos[i-1]+num[i-1];num.clear();

}

Page 108: 第 17 次课 5.3.2 稀疏矩阵

int getStart(int i){

if(i>=1&&i<=rpos.size()-1)return rpos[i];

else return -1;}int getEnd(int i){

if(i>=1&&i<rpos.size()-1)return rpos[i+1]-1;

else if(i==rpos.size()-1)return data.size()-1;// 最后一行的最后一个

元素的位置就是 data 数组的最后一个元素else return -1;

}

Page 109: 第 17 次课 5.3.2 稀疏矩阵

// 下面是矩阵的乘法:void MulSMatrix(RLSMatrix M,RLSMatrix N,RLSMatrix & Q)

{

if(M.nu!=N.mu) return;

Q.mu=M.mu,Q.nu=N.nu,Q.tu=0;

M.MakeRpos();//生成 M 的行表N.MakeRpos();//生成 N 的行表

Page 110: 第 17 次课 5.3.2 稀疏矩阵

int i;

for(i=1;i<=M.mu;i++)

{

vector<int> sum(Q.nu+1);

for(int clear=1;clear<=Q.nu;clear++)

sum[clear]=0;

int i_start=M.getStart(i);

// 得到第 i 行的开始位置int i_end=M.getEnd(i);

// 得到第 i 行的结束位置

Page 111: 第 17 次课 5.3.2 稀疏矩阵

int i_index;for(i_index=i_start;i_index<=i_end;i_index++){

int k=M.data[i_index].j;int k_start=N.getStart(k);// 得到第 k 行的开始位置int k_end=N.getEnd(k);// 得到第 k 行的结束位置int k_index;

for(k_index=k_start;k_index<=k_end;k_index++){

int j=N.data[k_index].j;

sum[j]+=M.data[i_index].e*N.data[k_index].e;}

}

Page 112: 第 17 次课 5.3.2 稀疏矩阵

// 第一行元素计算完毕,将其加入到 Q 中for(int j=1;j<=Q.nu;j++)

{

if(sum[j])

{

Triple temp(i,j,sum[j]);

Q.InsertTriple(temp);

}

}

}

}

Page 113: 第 17 次课 5.3.2 稀疏矩阵

void print()

{

for(int i=0;i<data.size();i++)

cout<<data[i].i<<" "<<data[i].j<<" "<<data[i].e<<endl;

cout<<"***********************"<<endl;

}

};

Page 114: 第 17 次课 5.3.2 稀疏矩阵

int main(int argc, char* argv[])

{

RLSMatrix M(6,7),N(7,6),Q(6,6);

M.InsertTriple(Triple(1,2,1));

M.InsertTriple(Triple(1,3,1));

M.InsertTriple(Triple(3,1,1));

M.InsertTriple(Triple(3,6,1));

M.InsertTriple(Triple(4,3,1));

M.InsertTriple(Triple(5,2,1));

M.InsertTriple(Triple(6,1,1));

M.InsertTriple(Triple(6,4,1));

Page 115: 第 17 次课 5.3.2 稀疏矩阵

//////N.InsertTriple(Triple(1,3,1));N.InsertTriple(Triple(1,6,1));N.InsertTriple(Triple(2,1,1));N.InsertTriple(Triple(2,5,1));N.InsertTriple(Triple(3,1,1));N.InsertTriple(Triple(3,4,1));N.InsertTriple(Triple(4,6,1));N.InsertTriple(Triple(6,3,1));/////M.MulSMatrix(M,N,Q);M.print();N.print();Q.print();

Page 116: 第 17 次课 5.3.2 稀疏矩阵

// 下面是用数组作为矩阵的存储结构,并进行矩阵的乘法

int m[6][7]={ {0,1,1,0,0,0,0},{0,0,0,0,0,0,0},

{1,0,0,0,0,1,0},{0,0,1,0,0,0,0},{0,1,0,0,0,0,0},{1,0,0,1,0,0,0}

};int n[7][6];//n 是 m 的转置矩阵int q[6][6];//q 作为 m*n 的结果int i,j;for(i=0;i<6;i++)// 转置

for(j=0;j<7;j++)n[j][i]=m[i][j];

Page 117: 第 17 次课 5.3.2 稀疏矩阵

for(i=0;i<6;i++)// 乘积{

for(j=0;j<7;j++){

q[i][j]=0;for(int k=0;k<7;k++){

q[i][j]+=m[i][k]*n[k][j];}

}}

Page 118: 第 17 次课 5.3.2 稀疏矩阵

for(i=0;i<6;i++)//打印结果for(j=0;j<6;j++)

{

if(q[i][j])cout<<i+1<<" "<<j+1<<" "<<q[i][j]<<endl;

}

cout<<"****************"<<endl;

return 0;

}

Page 119: 第 17 次课 5.3.2 稀疏矩阵

本节内容,大家应该把理解思想作为首要任务。算法及其实现,有能力的同学可以多下点功夫。