一,矩阵相乘 A*B
1,矩阵乘法一般算法
前提:A的列数等于B的行数
原理:
代码:
//一般算法
struct mat()
{
int r,c;
double date[MAXN][MAXN];
};
int mul(mat& d,const nat& a,const mat& b)
{
int i,j,k;
if(a.c!=b.r)return 0;
d.r=a.r;
d.c=b.c;
for(i=0;i<d.r;i++)
for(j=0;j<d.c;j++)
for(d.date[i][j]=k=0;k<a.c;k++)
d.date[i][j]+=a.date[i][k]*b.date[k][j];
return 1;
}
2,传统分治算法
C=AB
将A B C分成大小相等的方块
(分治算法的思想是,将一个难以解决的大问题,分割成一些规模较小的相同问题,分而治之)
如果n=2,则2个2阶方阵的乘积可以直接用(2)-(5)式计算出来,共需8次乘法和四次加法。
当矩阵的阶数大于2时,可以继续将子矩阵分块,直到子矩阵的阶数降为2.
这样就产生了一个分治降阶的递归算法。
3,Strassen算法
相较于分治算法,它减少了乘法运算的次数
做了七次乘法,再做若干次的加法减法
数据的存储结构:二维数组,二重指针
#include<iostream>
#include<cmath>
#define N 4
using namespace std;
//二阶矩阵相乘
void Matrix_Multiply(int A[][N],int B[][N],int C[][N])
{
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
{
C[i][j]=0;
for(int t=0;t<2;t++)
C[i][j]=C[i][j]+A[i][t]*B[t][j];
}
}
//矩阵加法
void Add(int n,int A[][N],int B[][N],int R[][N])
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
R[i][j]=A[i][j]+B[i][j];
}
//矩阵减法
void Sub(int n,int A[][N],int B[][N],int R[][N])
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
R[i][j]=A[i][j]-B[i][j];
}
//Strassen算法
void Strassen(int n,int A[][N],int B[][N],int C[][N])
{
//中间辅助矩阵
int A11[N][N], A12[N][N], A21[N][N], A22[N][N];
int B11[N][N], B12[N][N], B21[N][N], B22[N][N];
int C11[N][N], C12[N][N], C21[N][N], C22[N][N];
int AA[N][N], BB[N][N];
int M1[N][N], M2[N][N], M3[N][N], M4[N][N], M5[N][N],