用C语言strassen矩阵乘法的串行程序,并输出运行时间
时间: 2024-06-03 07:10:11 浏览: 91
好的,以下是C语言实现strassen矩阵乘法的串行程序,并输出运行时间的代码:
#include <stdio.h>
#include <stdlib.h>
<time.h>
void strassen(int n, int **a, int **b, int **c){
int **p1, **p2, **p3, **p4, **p5, **p6, **p7;
int **a11, **a12, **a21, **a22;
int **b11, **b12, **b21, **b22;
int **c11, **c12, **c21, **c22;
int i, j;
if(n==1){
c[0][0] = a[0][0] * b[0][0];
return;
}
n = n/2;
// 分配内存
p1 = (int **)malloc(n * sizeof(int *));
p2 = (int **)malloc(n * sizeof(int *));
p3 = (int **)malloc(n * sizeof(int *));
p4 = (int **)malloc(n * sizeof(int *));
p5 = (int **)malloc(n * sizeof(int *));
p6 = (int **)malloc(n * sizeof(int *));
p7 = (int **)malloc(n * sizeof(int *));
a11 = (int **)malloc(n * sizeof(int *));
a12 = (int **)malloc(n * sizeof(int *));
a21 = (int **)malloc(n * sizeof(int *));
a22 = (int **)malloc(n * sizeof(int *));
b11 = (int **)malloc(n * sizeof(int *));
b12 = (int **)malloc(n * sizeof(int *));
b21 = (int **)malloc(n * sizeof(int *));
b22 = (int **)malloc(n * sizeof(int *));
c11 = (int **)malloc(n * sizeof(int *));
c12 = (int **)malloc(n * sizeof(int *));
c21 = (int **)malloc(n * sizeof(int *));
c22 = (int **)malloc(n * sizeof(int *));
for(i=0; i<n; i++){
p1[i] = (int *)malloc(n * sizeof(int));
p2[i] = (int *)malloc(n * sizeof(int));
p3[i] = (int *)malloc(n * sizeof(int));
p4[i] = (int *)malloc(n * sizeof(int));
p5[i] = (int *)malloc(n * sizeof(int));
p6[i] = (int *)malloc(n * sizeof(int));
p7[i] = (int *)malloc(n * sizeof(int));
a11[i] = (int *)malloc(n * sizeof(int));
a12[i] = (int *)malloc(n * sizeof(int));
a21[i] = (int *)malloc(n * sizeof(int));
a22[i] = (int *)malloc(n * sizeof(int));
b11[i] = (int *)malloc(n * sizeof(int));
b12[i] = (int *)malloc(n * sizeof(int));
b21[i] = (int *)malloc(n * sizeof(int));
b22[i] = (int *)malloc(n * sizeof(int));
c11[i] = (int *)malloc(n * sizeof(int));
c12[i] = (int *)malloc(n * sizeof(int));
c21[i] = (int *)malloc(n * sizeof(int));
c22[i] = (int *)malloc(n * sizeof(int));
}
// 初始化 a, b
for(i=0; i<n; i++){
for(j=0; j<n; j++){
a11[i][j] = a[i][j];
a12[i][j] = a[i][j+n];
a21[i][j] = a[i+n][j];
a22[i][j] = a[i+n][j+n];
b11[i][j] = b[i][j];
b12[i][j] = b[i][j+n];
b21[i][j] = b[i+n][j];
b22[i][j] = b[i+n][j+n];
}
}
// p1 = (a11+a22)*(b11+b22)
for(i=0; i<n; i++){
for(j=0; j<n; j++){
p1[i][j] = 0;
p1[i][j] += (a11[i][j] + a22[i][j]) * (b11[i][j] + b22[i][j]);
}
}
// p2 = (a21+a22)*b11
for(i=0; i<n; i++){
for(j=0; j<n; j++){
p2[i][j] = 0;
p2[i][j] += (a21[i][j] + a22[i][j]) * b11[i][j];
}
}
// p3 = a11*(b12-b22)
for(i=0; i<n; i++){
for(j=0; j<n; j++){
p3[i][j] = 0;
p3[i][j] += a11[i][j] * (b12[i][j] - b22[i][j]);
}
}
// p4 = a22*(b21-b11)
for(i=0; i<n; i++){
for(j=0; j<n; j++){
p4[i][j] = 0;
p4[i][j] += a22[i][j] * (b21[i][j] - b11[i][j]);
}
}
// p5 = (a11+a12)*b22
for(i=0; i<n; i++){
for(j=0; j<n; j++){
p5[i][j] = 0;
p5[i][j] += (a11[i][j] + a12[i][j]) * b22[i][j];
}
}
// p6 = (a21-a11)*(b11+b12)
for(i=0; i<n; i++){
for(j=0; j<n; j++){
p6[i][j] = 0;
p6[i][j] += (a21[i][j] - a11[i][j]) * (b11[i][j] + b12[i][j]);
}
}
// p7 = (a12-a22)*(b21+b22)
for(i=0; i<n; i++){
for(j=0; j<n; j++){
p7[i][j] = 0;
p7[i][j] += (a12[i][j] - a22[i][j]) * (b21[i][j] + b22[i][j]);
}
}
// c11 = p1+p4-p5+p7
for(i=0; i<n; i++){
for(j=0; j<n; j++){
c11[i][j] = p1[i][j] + p4[i][j] - p5[i][j] + p7[i][j];
}
}
// c12 = p3+p5
for(i=0; i<n; i++){
for(j=0; j<n; j++){
c12[i][j] = p3[i][j] + p5[i][j];
}
}
// c21 = p2+p4
for(i=0; i<n; i++){
for(j=0; j<n; j++){
c21[i][j] = p2[i][j] + p4[i][j];
}
}
// c22 = p1-p2+p3+p6
for(i=0; i<n; i++){
for(j=0; j<n; j++){
c22[i][j] = p1[i][j] - p2[i][j] + p3[i][j] + p6[i][j];
}
}
// 复制结果
for(i=0; i<n; i++){
for(j=0; j<n; j++){
c[i][j] = c11[i][j];
c[i][j+n] = c12[i][j];
c[i+n][j] = c21[i][j];
c[i+n][j+n] = c22[i][j];
}
}
// 释放内存
for(i=0; i<n; i++){
free(p1[i]);
free(p2[i]);
free(p3[i]);
free(p4[i]);
free(p5[i]);
free(p6[i]);
free(p7[i]);
free(a11[i]);
free(a12[i]);
free(a21[i]);
free(a22[i]);
free(b11[i]);
free(b12[i]);
free(b21[i]);
free(b22[i]);
free(c11[i]);
free(c12[i]);
free(c21[i]);
free(c22[i]);
}
free(p1);
free(p2);
free(p3);
free(p4);
free(p5);
free(p6);
free(p7);
free(a11);
free(a12);
free(a21);
free(a22);
free(b11);
free(b12);
free(b21);
free(b22);
free(c11);
free(c12);
free(c21);
free(c22);
}
int main(){
int n;
int **a, **b, **c;
int i, j;
clock_t start, end;
double duration;
// 输入矩阵大小 n
printf("请输入矩阵大小 n:");
scanf("%d", &n);
// 分配内存
a = (int **)malloc(n * sizeof(int *));
b = (int **)malloc(n * sizeof(int *));
c = (int **)malloc(n * sizeof(int *));
for(i=0; i<n; i++){
a[i] = (int *)malloc(n * sizeof(int));
b[i] = (int *)malloc(n * sizeof(int));
c[i] = (int *)malloc(n * sizeof(int));
}
// 初始化矩阵
for(i=0; i<n; i++){
for(j=0; j<n; j++){
a[i][j] = rand()%10;
b[i][j] = rand()%10;
}
}
// 计算矩阵乘法并记录时间
start = clock();
strassen(n, a, b, c);
end = clock();
duration = (double)(end - start) / CLOCKS_PER_SEC;
// 输出结果及计算时间
printf("矩阵乘法结果:\n");
for(i=0; i<n; i++){
for(j=0; j<n; j++){
printf("%d ", c[i][j]);
}
printf("\n");
}
printf("计算时间:%f秒\n", duration);
// 释放内存
for(i=0; i<n; i++){
free(a[i]);
free(b[i]);
free(c[i]);
}
free(a);
free(b);
free(c);
return 0;
}
注意:为了保证精度,上面的代码中使用了 double 类型的变量记录时间。
阅读全文