64,637
社区成员
发帖
与我相关
我的任务
分享
/*
本文件定义了CMatrix类,使用STL模板容器 vector 来存储矩阵,可以实现任意 n 的Strassen算法矩阵相乘
当 n 为奇数时,调用普通矩阵算法。
example:
CMatrix A(8),B(*),C(8);
A.Trun_Random();
B.Trun_Random();
C = A*B;
cout<<C;
*/
#ifndef matrix_h_
#define matrix_h_
#include<vector>
#include<iostream>
#include <time.h>
using namespace std;
class CMatrix{
//运算符重载
friend ostream& operator << (ostream &out,CMatrix& M);
friend CMatrix& operator + (CMatrix& M1,CMatrix& M2);
friend CMatrix& operator - (CMatrix& M1,CMatrix& M2);
friend CMatrix& operator * (CMatrix& M1,CMatrix& M2); //Strassen算法矩阵相乘
public:
int N;
vector< vector<int> > A; //二维
public:
CMatrix(int n); //构造,生成n阶二维数组,元素值都为1
CMatrix(int n,int a); //构造,生成n阶二维数组,元素值都为a;
~CMatrix(){ };
CMatrix(CMatrix& M2);
CMatrix& operator = (CMatrix& M2); //重载“=”
void Trun_Random(); //使数组的元素全部变成随机数,0~9
void Union(CMatrix& A11,CMatrix& A12,CMatrix& A21,CMatrix& A22);//联合4个小二维数组
CMatrix& normalMutil(CMatrix& M2); //普通矩阵乘法
};
#endif
/*
编译环境 studio 2008
最后修改 2009/11/4
*/
#include"matrix.h"
#include<time.h>
#include<stdio.h>
int main()
{
int n = 1;
srand( (unsigned)time(NULL )); //设置随机数发生种子
//clock_t start, end;
//start = clock();
//end = clock();
// printf("Pi = %lf\n用时为%.2f秒\n", pi, (float)(end-start)/CLOCKS_PER_SEC);
clock_t start, end;
start = clock();
int a[100][100],b[100][100],c[100][100];
for(int i = 0;i<100;i++)
{
for(int j = 0;j<100;j++)
{
a[i][j] = 0;
for(int k = 0;k<100;k++)
a[i][j] += b[i][k]*c[k][j];
}
}
end = clock();
printf("用时为%.2f秒\n", (float)(end-start)/CLOCKS_PER_SEC);
cout<<"程序将演示用Strassen算法计算矩阵相乘。"<<endl;
cout<<"程序可以计算任意阶的矩阵乘法,当n<=0,退出,请输入n:";
cin>>n;
while(n>0)
{
cout<<"当n = "<<n<<"时"<<endl;
CMatrix A(n),B(n),C(n); //创建三个n*n的矩阵对象
//A和B中的元素变成0~9的随机整数
A.Trun_Random();
B.Trun_Random();
cout<<"随机生成的第一个矩阵是:"<<endl;
// cout<<A;
cout<<"随机生成的第二个矩阵是:"<<endl;
// cout<<B;
clock_t start1, end1,start2,end2;
start1 = clock();
C = A*B; //Strassen算法计算矩阵相乘
end1 = clock();
cout<<"Strassen算法计算结果:"<<endl;
// cout<<C;
start2 = clock();
C = A.normalMutil(B); //普通乘法计算
end2 = clock();
cout<<"普通乘法计算结果:"<<endl;
// cout<<C;
printf("用时为%.6f秒\n",(float)(end1-start1)/CLOCKS_PER_SEC);
printf("用时为%.6f秒\n",(float)(end2-start2)/CLOCKS_PER_SEC);
cout<<"程序可以计算任意阶的矩阵乘法,请输入n:";
cin>>n;
}
}
#include"matrix.h"
#include<iostream>
#include "iomanip"
using namespace std;
int getRandom() //得到随机数
{
return rand();
}
void CMatrix::Trun_Random() //使矩阵内元素变为0~9的元素
{
for(int i = 0;i<N;i++)
{
for(int j = 0;j<N;j++)
A[i][j] = getRandom()%10;
}
}
CMatrix::CMatrix(int n)
{
N = n;
A = vector<vector<int>>(N,vector<int>(N,1));
}
CMatrix::CMatrix(int n, int a)
{
N = n;
A = vector<vector<int>>(N,vector<int>(N,a));
}
CMatrix::CMatrix(CMatrix& M2)
{
N = M2.N;
// A = vector<vector<int>>(N,vector<int>(N,1));
vector<vector<int>>::iterator iter;
for(iter = M2.A.begin();iter!=M2.A.end();iter++)
A.push_back(*iter);
}
//重载 +
CMatrix& operator + (CMatrix& M1,CMatrix& M2)
{
CMatrix* temp = new CMatrix(M1.N);
if(M1.N != M2.N)
cout<<"N != M2.N"<<endl;
temp->A = M2.A;
for(int i = 0;i<M1.N;i++)
{
for(int j = 0;j<M1.N;j++)
temp->A[i][j] += M1.A[i][j];
}
return *temp;
}
//重载 —
CMatrix& operator - (CMatrix& M1,CMatrix& M2)
{
if(M1.N != M2.N)
cout<<"M1.N != M2.N"<<endl;
CMatrix* temp = new CMatrix(M1.N);
temp->A = M1.A;
for(int i = 0;i<M1.N;i++)
{
for(int j = 0;j<M1.N;j++)
temp->A[i][j] -= M2.A[i][j];
}
return *temp;
}
//重载=
CMatrix& CMatrix::operator =(CMatrix &M2)
{
if(N != M2.N)
cout<<"N != M2.N"<<endl;
A = M2.A;
return *this;
}
//重载*
CMatrix& operator * (CMatrix& A,CMatrix& B)
{
int N = A.N;
if(A.N != B.N)
cout<<"error!A.N != B.N"<<endl;
if(N == 2) //当阶数为2时,做普通乘法运算
{
CMatrix* temp = new CMatrix(N);
(*temp) = A.normalMutil(B);
return *temp;
}
if(N%2 != 0) //当阶数为奇数时,做普通乘法运算
{
CMatrix* temp = new CMatrix(N);
(*temp) = A.normalMutil(B);
return *temp;
}
//M1~M7是中间结果
CMatrix *M1 = new CMatrix(N/2),*M2 = new CMatrix(N/2),*M3 = new CMatrix(N/2),*M4 = new CMatrix(N/2),
*M5 = new CMatrix(N/2),*M6 = new CMatrix(N/2),*M7 = new CMatrix(N/2);
//将矩阵分为4块
//A11,A12,A21,A22 是第一个矩阵 A 的分块
//B11,B12,B21,B22 是第二个矩阵 B 的分块
//C11,C12,C21,C22 是结果矩阵 C 的分块
CMatrix *A11 = new CMatrix(N/2),*A12 = new CMatrix(N/2),*A21 = new CMatrix(N/2),*A22 = new CMatrix(N/2);
CMatrix *B11 = new CMatrix(N/2),*B12 = new CMatrix(N/2),*B21 = new CMatrix(N/2),*B22 = new CMatrix(N/2);
CMatrix *C11 = new CMatrix(N/2),*C12 = new CMatrix(N/2),*C21 = new CMatrix(N/2),*C22 = new CMatrix(N/2);
CMatrix *C = new CMatrix(N); //结果存放在C中
//执行矩阵分块
for(int i = 0;i<N/2;i++)
{
for(int j = 0;j<N/2;j++)
{
A11->A[i][j]=A.A[i][j];
A12->A[i][j]=A.A[i][j+N/2];
A21->A[i][j]=A.A[i+N/2][j];
A22->A[i][j]=A.A[i+N/2][j+N/2];
B11->A[i][j]=B.A[i][j];
B12->A[i][j]=B.A[i][j+N/2];
B21->A[i][j]=B.A[i+N/2][j];
B22->A[i][j]=B.A[i+N/2][j+N/2];
}
}
//计算M1~M7
(*M1) = (*A11)*((*B12) - (*B22));
(*M2) = ((*A11) +(*A12))*(*B22);
(*M3 )= ((*A21) + (*A22))*(*B11);
(*M4) = (*A22)*((*B21) - (*B11));
(*M5) = ((*A11)+(*A22))*((*B11)+(*B22));
(*M6) = ((*A12)-(*A22))*((*B21)+(*B22));
(*M7) = ((*A11)-(*A21))*((*B11)+(*B12));
(*C11) = (*M5)+(*M4)-(*M2)+(*M6);
(*C12) = (*M1)+(*M2);
(*C21) = (*M3)+(*M4);
(*C22) = (*M5)+(*M1)-(*M3)-(*M7);
//把C11,C12,C21,C22合并成结果矩阵C
(*C).Union((*C11),(*C12),(*C21),(*C22));
return *C;
}
void CMatrix::Union(CMatrix &A11, CMatrix &A12, CMatrix &A21, CMatrix &A22)
{//把四个小矩阵合成一个矩阵
if(A11.N*2 != N)
cout<<"error! A11.N*2 != N";
for(int i = 0;i<N/2;i++)
{
for(int j = 0;j<N/2;j++)
{
A[i][j] = A11.A[i][j];
A[i][j+N/2] = A12.A[i][j];
A[i+N/2][j] = A21.A[i][j];
A[i+N/2][j+N/2] = A22.A[i][j];
}
}
}
CMatrix& CMatrix::normalMutil(CMatrix &M2) //普通矩阵乘法运算
{
if(N != M2.N)
cout<<"(N != M2.N!";
CMatrix *re = new CMatrix(N,0);
for(int i = 0;i<N;i++)
{
for(int j = 0;j<N;j++)
{
(*re).A[i][j] = 0;
for(int k = 0;k<N;k++)
(*re).A[i][j] += A[i][k]*M2.A[k][j];
}
}
return *re;
}
ostream& operator <<(ostream& out,CMatrix& M)
{//重载〈〈,输出矩阵
for(int i = 0;i<M.N;i++)
{
for(int j = 0;j<M.N;j++)
{
// out.precision(4);
out<<setw(4)<<M.A[i][j]<<" ";
}
cout<<endl;
}
return out;
}