顺序存储结构的三元组稀疏矩阵的乘法运算

来源:互联网 发布:大学生网络借贷案例 编辑:程序博客网 时间:2024/06/05 15:34

顺序存储结构的三元组稀疏矩阵的乘法运算

完整代码可到CSDN资源中搜索顺序存储空间表示的稀疏矩阵的创建和矩阵运算进行下载。

三元组的含义为(行,列,元素值)

首先判断是否满足进行乘法运算的条件:只有当第一个矩阵的列数与第二个矩阵的行数相等时才可进行运算。

运算的规则如下:矩阵A[M][P]和矩阵B[P][N]相乘得到矩阵C[M][N],则C[M][N]的每一项的计算公式为:

对于用三元组的形式表示的稀疏矩阵,其存储的内容只有非零元素的值,例如:一个6行7列有8个非零值的矩阵,对应的三元组形式为:A[6][7]:((1,2,12),(1,3,9),(3,1,-3),(3,6,14),(4,3,24),(5,2,18),(6,1,15),(6,4,-7))

 一个7行5列的含有10个非零值的矩阵,对应的三元组的形式为:

B[7][5]:((1,3,4),(2,1,3),(2,4,2),(3,1,-3),(3,2,1),(4,3,2),(4,2,7),(5,3,8),(6,4,3),(7,2,5))

我们使用的算法描述如下:

1、用A[6][7]的第一个三元组(1,2,12)的列值2与B[7][5]的7个三元组的行值逐个进行比较,

(1)第二个矩阵中第一个符合相等条件的三元组:(2,1,3),则进行运算得到:C[1][1] = 12*3=36;C矩阵的第一个元素为(1,1,36),C中元素个数为1。此时C中对应的三元组为:((1,1,36)。

(2)第二个矩阵中第一个符合相等条件的三元组:(2,4,2),则进行运算得到:C[1][4] = 12*2=24;对应的三元组为(1,4,24)。将该结果与第一次的结果进行行列值的比较,若行列值都相等,则将后者的元素值加到前者元素值之上,再将后者的结果释放,C中的元素个数保持不变,若行列值有一个不相等,则两个结果都保存,此时C中元素个数增加一个。本例中,列值不相等,故C中元素个数为2。将该三元组加到C的三元组中,此时C中对应的三元组为:(1,1,36),(1,4,24))。

(3)第二个矩阵中再没有与第一个矩阵的第一个三元组满足可以相乘条件的元素,则开始对第一个矩阵的第二个三元组进行操作。

2、A[6][7]的第二个三元组(1,3,9)的列值3与B[7][5]的7个三元组的行值逐个进行比较,

1)第二个矩阵中第一个符合相等条件的三元组:(3,1,-3),则进行运算得到:C[1][1] = 9*-3=-27;对应的三元组为(1,1,-27),将该三元组的行列值与之前的两个元素的行列值进行比较:若存在行列值都相等的元组,则将后者的元素值加到前者元素值之上,再将后者的结果释放,C中的元素个数保持不变,若行列值有一个不相等,则将该结果保存,此时C中元素个数加1。本例中,(1,1,-27)的行列值与C中第一个元组的行列值相同,故将该元素值-27加到(1,1,36)中得到(1,1,9),即C矩阵的第一个三元组的元素值发生变化,此时C中元素个数仍为2。此时C中对应的三元组为(1,1,9),(1,4,24)

(2)第二个矩阵中第二个符合相等条件的三元组:(3,2,3),则进行运算得到:C[1][2] = 12*3=36;对应的三元组为(1,2,24)。将该结果C中现有的三元组进行行列值的比较,若行列值都相等,则将后者的元素值加到前者元素值之上,再将后者的结果释放,C中的元素个数仍为1,若行列值有一个不相等,则两个结果都保存,此时C中元素个数为2。本例中,列值不相等,故C中元素个数为3。将该三元组加到C的三元组中,此时C中对应的三元组为:(1,1,9),(1,4,24),(1,2,24)

(3)第二个矩阵中再没有与第一个矩阵的第二个三元组满足可以相乘条件的元素,则开始对第一个矩阵的第三个三元组进行操作。

3、每次都进行与1和2相似的操作,从第二个矩阵的所有三元组中寻找行值与第一个矩阵的第i个三元组的列值相等的三元组,计算得到对应的结果三元组,若该三元组的行列值与C中现有的三元组的行列值相同,则将两个三元组的元素值进行相加,这个相加的过程就相当于是中对k进行求和的过程,相加之后C的元组的个数不变。若该三元组的行列值与C中现有的所有三元组的行或者列不相等,则C中元素个数增加1,将该三元组加入C的三元组中。当矩阵2的所有三元组都判断完毕后,继续对第一个矩阵的下一个元素进行相似的运算直至第一个矩阵的所有元组都运算完毕。

4、对得到的结果矩阵按行列值进行重排序。

typedef int ElemType;typedef struct{int row;    //此处的行列值为真实值,都有从1开始没有第0行和第0列int col; ElemType value;   //矩阵第row行第col列对应的值}Triple;typedef struct{Triple *data; //非零三元组表int row_num;      //矩阵的总行数int col_num;//矩阵的总列数int non_zero;//矩阵总的非零值的个数}TSMatrix;


//当第一个矩阵的列值等于第二个矩阵的行值时,对这两个矩阵进行相乘的运算并将结果存在result矩阵中void MultSMatrix( TSMatrix *matrix1, TSMatrix *matrix2, TSMatrix *result ){int i = 0;int j = 0;int k = 0;int q;if( matrix1->col_num != matrix2->row_num ){  //如果两个矩阵的行数或者列数不相同printf( "AddSMatrix Error: the colum of the first matrix and therow of the second matrix is different!\n" );}else{   //否则为结果矩阵分配内存空间result->data = ( Triple *)malloc( sizeof( Triple ) * ( matrix1->row_num * matrix2->col_num ) ); if( !result->data )   //分配失败,则报错printf( "AddSMatrix Error:OVERFLOW!\n" );else{         //分配空间成功result->row_num  = matrix1->row_num;//设置结果矩阵的行值为第一个矩阵的行值result->col_num  = matrix2->col_num;//设置结果矩阵的行值为第二个矩阵的列值for( k = 0; k < matrix1->row_num * matrix2->col_num; k++ )( result->data + k )->value = 0;k = 0;while( i < matrix1->non_zero ){ //当两个矩阵的元素都没有处理完时for( j = 0; j < matrix1->non_zero; j++ ){//如果matrix1的第i个元素的列值与matrix2的第j个元素的行值相同,则进行相乘,相当于a[row1][col2] = b[row1][rc]*c[rc][col2]if( ( matrix1->data + i )->col == ( matrix2->data + j )->row ){( result->data + k )->row = ( matrix1->data + i )->row;//result的第k个元素的行值为第一个矩阵的第i个元素对应的行值( result->data + k )->col = ( matrix2->data + j )->col;//result的第k个元素的列值为第二个矩阵的第j个元素对应的列值//result的第k个元素的value值为第一个矩阵的第i个元素对应的value值与第二个矩阵的第j个元素对应的value值相乘的结果( result->data + k )->value = ( matrix1->data + i )->value * ( matrix2->data + j )->value;  //用当前result的第k个元素与前k-1个元素的行列值进行比较:若相等,将第k项对应的value值加到第q项//相当于a[row1][col2] = b[row1][rc]*c[rc][col2]中对rc从1到col1( = row2 )的求和for( q = 0; q < k; q++ ){if( ( result->data + k )->row == ( result->data + q )->row && ( result->data + k )->col == ( result->data + q )->col ){( result->data + q )->value += ( result->data + k )->value;  k--; //将k-1的目的是与下面的k+1对应,使k值不变,因为相等时将该项的结果与加到之前的结果上,故不需要生成新的项}}k++;}}i++;}result->non_zero = k;//重新为result->data分配适合大小的存储空间result->data = ( Triple *)realloc( result->data, sizeof( Triple ) * ( result->non_zero ) );ReorderSMatrix( result );}}}



0 0
原创粉丝点击