递归与分治策略:Strassen矩阵乘法

辅助函数

为了便于代码的编写,以及在函数参数中传二维数组的方便,写了以下三个辅助函数。

//数组寻址辅助函数int& GetArrayVal( int* pMatrix, int nCol, int i, int j ){return *( pMatrix + i * nCol + j);}//创建矩阵void CreateMatrix( int** pMatrix, int nRow, int nCol ){*pMatrix = new int[nRow*nCol];memset( *pMatrix, 0, sizeof(int*)*nRow*nCol );for( int i = 0; i < nRow; ++i ){for( int j = 0; j < nCol; ++j ){GetArrayVal( *pMatrix, nCol, i, j ) = rand() % 5;}}}//销毁矩阵void DeleteMatrix( int** pMatrix ){if ( NULL != *pMatrix ){delete *pMatrix;*pMatrix = NULL;}}

普通矩阵乘法

根据矩阵乘法的定义,,可以迅速写出程序代码,如下

//常规数组乘法bool MatrixMuiltiplyGeneral( int* pMatrix1, int nRow1, int nCol1,int* pMatrix2, int nRow2,int nCol2, int** pResult ){if ( nCol1 != nRow2 ) return false;*pResult = new int[nRow1*nCol2];for( int i = 0; i < nRow1; ++i ){for( int j = 0; j < nCol2; ++j ){GetArrayVal( *pResult, nCol2, i, j ) = 0;for( int k = 0; k < nCol1; ++k ){GetArrayVal( *pResult, nCol2, i, j ) += GetArrayVal( pMatrix1, nCol1, i, k)* GetArrayVal( pMatrix2, nCol2, k, j );}}}return true;}

递归方法(矩阵方阵,即n*n)—-8次乘法

将矩阵A

由此可得

/////////////////////////////////////////////////////////////////////////矩阵乘法,递归调用(8次乘法)/****************************************************************** 时 间: [2015年6月22日]* 作 者:shanql* 函数描述:数组乘法* 函数参数:pMatrix1–矩阵1nLeftIndex1,nTopIndex1–矩阵1左上角索引点(相对于源矩阵pMatrixl)pMatrix2–矩阵2nLeftIndex2, nTopIndex2–矩阵2左上角索引点(相对于源矩阵pMatrix2)nCount–方阵nnTotalCol–使用矩阵列大小(指针取值使用)pResult–相乘结果保存* 函数返回:*****************************************************************/bool MatrixMuiltiplyGeneralEx_8( int* pMatrix1, int nLeftIndex1, int nTopIndex1,int* pMatrix2, int nLeftIndex2, int nTopIndex2,int nCount, int nTotalCol, int** pResult ){*pResult = new int[nCount*nCount];for( int i = 0; i < nCount; ++i ){for( int j = 0; j < nCount; ++j ){GetArrayVal( *pResult, nCount, i, j ) = 0;for( int k = 0; k < nCount; ++k ){GetArrayVal( *pResult, nCount, i, j ) += GetArrayVal( pMatrix1, nTotalCol, nLeftIndex1+i, nTopIndex1+k)* GetArrayVal( pMatrix2, nTotalCol, nLeftIndex2+k, nTopIndex2+j );}}}return true;}//矩阵加法(n*n),结果保存在第一个矩阵中void MatrixAddOrSub( int* pMatrix1, int* pMatrix2, int nCount, bool bAdd = true ){for( int i = 0; i < nCount; ++i ){for( int j = 0; j < nCount; ++j ){if ( bAdd ){GetArrayVal( pMatrix1, nCount, i, j ) += GetArrayVal( pMatrix2, nCount, i, j );}else{GetArrayVal( pMatrix1, nCount, i, j ) -= GetArrayVal( pMatrix2, nCount, i, j );}}}}//递归求解n*n方矩阵之积(8次乘法)void RecursiveMuiltiplyMatrix( int* pMatrix1, int nLeftIndex1, int nTopIndex1,int* pMatrix2, int nLeftIndex2, int nTopIndex2,int nCount, int nTotalCol, int** pResult ){if ( nCount == 2 ){MatrixMuiltiplyGeneralEx_8( pMatrix1, nLeftIndex1, nTopIndex1,pMatrix2, nLeftIndex2, nTopIndex2, nCount, nTotalCol, pResult );}else{//拆分成4个大小相等的子矩阵int* pResult1 = NULL;int* pResult2 = NULL;int* pResult3 = NULL;int* pResult4 = NULL;int* pResult5 = NULL;int* pResult6 = NULL;int* pResult7 = NULL;int* pResult8 = NULL;//A[1][1]*B[1][1];RecursiveMuiltiplyMatrix( pMatrix1, nLeftIndex1, nTopIndex1,pMatrix2, nLeftIndex2, nTopIndex2, nCount / 2, nTotalCol, &pResult1 );//A[1][2]*B[2][1];RecursiveMuiltiplyMatrix( pMatrix1, nLeftIndex1, nTopIndex1+nCount/2,pMatrix2, nLeftIndex2+nCount/2, nTopIndex2, nCount / 2, nTotalCol, &pResult2 );//A[1][1]*B[1][2];RecursiveMuiltiplyMatrix( pMatrix1, nLeftIndex1, nTopIndex1,pMatrix2, nLeftIndex2, nTopIndex2+nCount/2, nCount / 2, nTotalCol, &pResult3 );//A[1][2]*B[2][2];RecursiveMuiltiplyMatrix( pMatrix1, nLeftIndex1, nTopIndex1+nCount/2,pMatrix2, nLeftIndex2+nCount/2, nTopIndex2+nCount/2, nCount / 2, nTotalCol, &pResult4 );//A[2][1]*B[1][1];RecursiveMuiltiplyMatrix( pMatrix1, nLeftIndex1+nCount/2, nTopIndex1,pMatrix2, nLeftIndex2, nTopIndex2, nCount / 2, nTotalCol, &pResult5 );//A[2][2]*B[2][1];RecursiveMuiltiplyMatrix( pMatrix1, nLeftIndex1+nCount/2, nTopIndex1+nCount/2,pMatrix2, nLeftIndex2+nCount/2, nTopIndex2, nCount / 2, nTotalCol, &pResult6 );//A[2][1]*B[1][2];RecursiveMuiltiplyMatrix( pMatrix1, nLeftIndex1+nCount/2, nTopIndex1,pMatrix2, nLeftIndex2, nTopIndex2+nCount/2, nCount / 2, nTotalCol, &pResult7 );//A[2][2]*B[2][2];RecursiveMuiltiplyMatrix( pMatrix1, nLeftIndex1+nCount/2, nTopIndex1+nCount/2,pMatrix2, nLeftIndex2+nCount/2, nTopIndex2+nCount/2, nCount / 2, nTotalCol, &pResult8 );//加法运算MatrixAddOrSub( pResult1, pResult2, nCount/2 );MatrixAddOrSub( pResult3, pResult4, nCount/2);MatrixAddOrSub( pResult5, pResult6, nCount/2 );MatrixAddOrSub( pResult7, pResult8, nCount/2 );//构造结果*pResult = new int[nCount*nCount];for( int i = 0; i < nCount/2; ++i ){for( int j = 0; j <nCount/2; ++j ){GetArrayVal( *pResult, nCount, i, j ) = GetArrayVal( pResult1, nCount/2, i, j );GetArrayVal( *pResult, nCount, i, j+nCount/2 ) = GetArrayVal( pResult3, nCount/2, i, j );GetArrayVal( *pResult, nCount, i+nCount/2, j ) = GetArrayVal( pResult5, nCount/2, i, j );GetArrayVal( *pResult, nCount, i+nCount/2, j+nCount/2 ) = GetArrayVal( pResult7, nCount/2, i, j );}}DeleteMatrix( &pResult1 );DeleteMatrix( &pResult2 );DeleteMatrix( &pResult3 );DeleteMatrix( &pResult4 );DeleteMatrix( &pResult5 );DeleteMatrix( &pResult6 );DeleteMatrix( &pResult7 );DeleteMatrix( &pResult8 );}}

递归方法(矩阵方阵,即n*n)—-7次乘法

7次乘法运算如下:

做了7次乘法后,再做若干次加、减法即可得到结果

勇于接受自己的失败,告诉自己,这就是自己的现实,

递归与分治策略:Strassen矩阵乘法

相关文章:

你感兴趣的文章:

标签云: