矩阵相乘算法及斯特拉森算法

先挖坑,再填坑~

一、实验要求

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、朴素方法的代码部分

#include<iostream>
using namespace std;
#include<stdio.h>
#include<math.h>
int a[1000][1000],b[1000][1000];
int out[1000][1000];
int main()
{
    
    
    int i,j,k,t;
    int n,m;
    scanf("%d %d",&n,&m);
    //首先输入第一个矩阵的值
    for(t=0;t<n;t++)//一共有多少对矩阵
    {
    
    
        for(j=0;j<m;j++)
        {
    
    
            for(k=0;k<m;k++)
            {
    
    
                scanf("%d",&a[j][k]);
				out[j][k]=0;
            }
        }
        for(j=0;j<m;j++)
        {
    
    
            for(k=0;k<m;k++)
            {
    
    
                scanf("%d",&b[j][k]);
            }
        }
        //开始矩阵的乘法;
        for(i=0;i<m;i++)
        {
    
    
            for(j=0;j<m;j++)
            {
    
    
                //out[i][j] = out[i][j] + a[i][j]*b[j][i];
                for(k=0;k<m;k++)
                {
    
    
                    out[i][j]+=a[i][k]*b[k][j];
                }
            }
        }
        //下面是打印阶段
        for(i=0;i<m;i++)
        {
    
    
            for(j=0;j<m;j++)
            {
    
    
                if(j==m-1)
                {
    
    
                    printf("%d",out[i][j]);
					printf("\n");
                }
                else
                printf("%d ",out[i][j]);
            }
        }
    }
    return 在这里插入图片描述
0;
}

运行结果为:
在这里插入图片描述

三、斯特拉森算法部分

完整代码如下:
(由于我们的题目要求时间有严格的限制,所以在最后32个数时我采用了朴素算法,其实应该都用这个高级算法的)

1.#include<iostream>  
2.using namespace std;  
3.#include<stdio.h>  
4.  
5.void PrintMatrix(int **MatrixA, int N)  
6.{
    
      
7.    for(int i=0;i<N;i++)  
8.        {
    
      
9.            for(int j=0;j<N;j++)  
10.            {
    
      
11.                if(j==N-1)  
12.                {
    
      
13.                    printf("%d",MatrixA[i][j]);  
14.                    printf("\n");  
15.                }  
16.                else  
17.                printf("%d ",MatrixA[i][j]);  
18.            }  
19.        }  
20.}  
21.int add(int** MatrixA, int** MatrixB, int** MatrixResult, int MatrixSize )//加法  
22.{
    
         
23.    for ( int o = 0; o < MatrixSize; o++)  
24.    {
    
      
25.        for ( int p = 0; p < MatrixSize; p++)  
26.        {
    
      
27.            MatrixResult[o][p] =  MatrixA[o][p] + MatrixB[o][p];  
28.        }  
29.    }  
30.    return 0;  
31.}  
32.int sub(int** MatrixA, int** MatrixB, int** MatrixResult, int MatrixSize )//减法  
33.{
    
         
34.    int q=0,r=0;  
35.    for ( q = 0; q < MatrixSize; q++)  
36.    {
    
      
37.        for (  r = 0; r < MatrixSize; r++)  
38.        {
    
      
39.            MatrixResult[q][r] =  MatrixA[q][r] - MatrixB[q][r];  
40.        }  
41.    }  
42.    return 0;  
43.}  
44.  
45.void strassen(int N, int** MatrixA, int** MatrixB, int** MatrixC)  
46.{
    
      
47.    if(N<=0)   
48.    {
    
      
49.        return;  
50.    }  
51.    else if (N == 1)  
52.    {
    
      
53.        MatrixC[0][0] = MatrixA[0][0]*MatrixB[0][0];  
54.        return;  
55.    }  
56.    else if (N<=128)  
57.    {
    
      
58.        for(int i=0;i<N;i++)  
59.        {
    
      
60.            for(int j=0;j<N;j++)  
61.            {
    
      
62.                for(int k=0;k<N;k++)  
63.                {
    
      
64.                    MatrixC[i][j]+=MatrixA[i][k]*MatrixB[k][j];  
65.                }  
66.            }  
67.        }  
68.        return;  
69.    }  
70.      
71.    int** MatrixA11;  
72.    int** MatrixA12;  
73.    int** MatrixA21;  
74.    int** MatrixA22;  
75.  
76.    int** MatrixB11;  
77.    int** MatrixB12;  
78.    int** MatrixB21;  
79.    int** MatrixB22;  
80.  
81.    int** MatrixC11;  
82.    int** MatrixC12;  
83.    int** MatrixC21;  
84.    int** MatrixC22;//新建矩阵  
85.  
86.    MatrixA11 = new int*[N/2];//数组的第二维一定要显示指定  
87.    MatrixA12 = new int*[N/2];//这是初始化小矩阵,每一个矩阵掰成四瓣  
88.    MatrixA21 = new int*[N/2];  
89.    MatrixA22 = new int*[N/2];  
90.  
91.    MatrixB11 = new int*[N/2];  
92.    MatrixB12 = new int*[N/2];  
93.    MatrixB21 = new int*[N/2];  
94.    MatrixB22 = new int*[N/2];  
95.  
96.    MatrixC11 = new int*[N/2];  
97.    MatrixC12 = new int*[N/2];  
98.    MatrixC21 = new int*[N/2];  
99.    MatrixC22 = new int*[N/2];  
100.    for (int i = 0; i < N/2; i++)//分配连续内存  
101.    {
    
      
102.        MatrixA11[i] = new int[N/2];  
103.        MatrixA12[i] = new int[N / 2];  
104.        MatrixA21[i] = new int[N / 2];  
105.        MatrixA22[i] = new int[N / 2];  
106.  
107.        MatrixB11[i] = new int[N / 2];  
108.        MatrixB12[i] = new int[N / 2];  
109.        MatrixB21[i] = new int[N / 2];  
110.        MatrixB22[i] = new int[N / 2];  
111.          
112.        MatrixC11[i] = new int[N / 2];  
113.        MatrixC12[i] = new int[N / 2];  
114.        MatrixC21[i] = new int[N / 2];  
115.        MatrixC22[i] = new int[N / 2];  
116.    }//必须分配  
117.    //为每个小矩阵赋值,将大矩阵分割为4个小矩阵  
118.    for (int i = 0; i < N / 2; i++)//!!!!!!!!!!!!!!!!!!!!!!!!!  
119.    {
    
      
120.        for (int j = 0; j < N / 2; j++)  
121.        {
    
      
122.            MatrixA11[i][j] = MatrixA[i][j];  
123.            MatrixA12[i][j] = MatrixA[i][j + N / 2];  
124.            MatrixA21[i][j] = MatrixA[i + N / 2][j];  
125.            MatrixA22[i][j] = MatrixA[i + N / 2][j + N / 2];  
126.  
127.            MatrixB11[i][j] = MatrixB[i][j];  
128.            MatrixB12[i][j] = MatrixB[i][j + N / 2];  
129.            MatrixB21[i][j] = MatrixB[i + N / 2][j];  
130.            MatrixB22[i][j] = MatrixB[i + N / 2][j + N / 2];  
131.        }  
132.    }  
133.    int** MatrixS1 = new int*[N / 2];    //做10个辅助矩阵S,计算加法  
134.    int** MatrixS2 = new int*[N / 2];  
135.    int** MatrixS3 = new int*[N / 2];  
136.    int** MatrixS4 = new int*[N / 2];  
137.    int** MatrixS5 = new int*[N / 2];  
138.    int** MatrixS6 = new int*[N / 2];  
139.    int** MatrixS7 = new int*[N / 2];  
140.    int** MatrixS8 = new int*[N / 2];  
141.    int** MatrixS9 = new int*[N / 2];  
142.    int** MatrixS10 = new int*[N / 2];  
143.      
144.    for (int i = 0; i < N / 2; i++)//分配连续内存,同上  
145.    {
    
      
146.        MatrixS1[i] = new int[N / 2];  
147.        MatrixS2[i] = new int[N / 2];  
148.        MatrixS3[i] = new int[N / 2];  
149.        MatrixS4[i] = new int[N / 2];  
150.        MatrixS5[i] = new int[N / 2];  
151.        MatrixS6[i] = new int[N / 2];  
152.        MatrixS7[i] = new int[N / 2];  
153.        MatrixS8[i] = new int[N / 2];  
154.        MatrixS9[i] = new int[N / 2];  
155.        MatrixS10[i] = new int[N / 2];  
156.    }  
157.    //做7个辅助矩阵P,计算乘法!!!!!!!!!!!  
158.    int** MatrixP1 = new int*[N / 2];  
159.    int** MatrixP2 = new int*[N / 2];  
160.    int** MatrixP3 = new int*[N / 2];  
161.    int** MatrixP4 = new int*[N / 2];  
162.    int** MatrixP5 = new int*[N / 2];  
163.    int** MatrixP6 = new int*[N / 2];  
164.    int** MatrixP7 = new int*[N / 2];  
165.  
166.    for (int i = 0; i < N / 2; i++)//分配连续内存  
167.    {
    
      
168.        MatrixP1[i] = new int[N / 2];  
169.        MatrixP2[i] = new int[N / 2];  
170.        MatrixP3[i] = new int[N / 2];  
171.        MatrixP4[i] = new int[N / 2];  
172.        MatrixP5[i] = new int[N / 2];  
173.        MatrixP6[i] = new int[N / 2];  
174.        MatrixP7[i] = new int[N / 2];  
175.    }  
176.  
177.    sub(MatrixB12, MatrixB22, MatrixS1,N/2);//S1 = B12 - B22  
178.    strassen(N/2,MatrixA11, MatrixS1, MatrixP1);  
179.  
180.    add(MatrixA11, MatrixA12, MatrixS2,N/2);//S2 = A11 + A12  
181.    strassen(N/2,MatrixS2, MatrixB22, MatrixP2);  
182.  
183.    add(MatrixA21, MatrixA22, MatrixS3,N/2);//S3 = A21 + A22  
184.    strassen(N/2,MatrixS3, MatrixB11, MatrixP3);  
185.  
186.    sub(MatrixB21, MatrixB11, MatrixS4,N/2);  
187.    strassen(N/2,MatrixA22, MatrixS4, MatrixP4);//P4 = A22 • S4  
188.  
189.    add(MatrixA11, MatrixA22, MatrixS5,N/2);//S5 = A11 + A22  
190.    add(MatrixB11, MatrixB22, MatrixS6,N/2);//S6 = B11 + B22  
191.    strassen(N/2,MatrixS5, MatrixS6, MatrixP5);//P5 = S5 • S6  
192.  
193.    sub(MatrixA12, MatrixA22, MatrixS7,N/2);//S7 = A12 - A22  
194.    add(MatrixB21, MatrixB22, MatrixS8,N/2);//S8 = B21 + B22  
195.    strassen(N/2,MatrixS7, MatrixS8, MatrixP6);//P6 = S7 • S8  
196.  
197.    sub(MatrixA11, MatrixA21, MatrixS9,N/2);//S9 = A11 - A21  
198.    add(MatrixB11, MatrixB12, MatrixS10,N/2);//S10 = B11 + B12  
199.    strassen(N/2,MatrixS9, MatrixS10, MatrixP7);//P7 = S9 • S10  
200.  
201.      
202.  
203.    add(MatrixP5, MatrixP4, MatrixC11,N/2); //C11 = P5 + P4 - P2 + P6  
204.    sub(MatrixC11, MatrixP2, MatrixC11,N/2);  
205.    add(MatrixC11, MatrixP6, MatrixC11,N/2);  
206.    add(MatrixP1, MatrixP2, MatrixC12,N/2);//C12 = P1 + P2  
207.    add(MatrixP3, MatrixP4, MatrixC21,N/2); //C21 = P3 + P4  
208.    add(MatrixP5, MatrixP1, MatrixC22,N/2); //C22 = P5 + P1 - P3 - P7  
209.    sub(MatrixC22, MatrixP3, MatrixC22,N/2);  
210.    sub(MatrixC22, MatrixP7, MatrixC22,N/2);  
211.  
212.    //将C11,C12,C21,C21合并为C矩阵  
213.    for (int i = 0; i < N / 2; i++){
    
      
214.        for (int j = 0; j < N / 2; j++){
    
      
215.            MatrixC[i][j] = MatrixC11[i][j];  
216.            MatrixC[i][j+N/2] = MatrixC12[i][j];  
217.            MatrixC[i+N/2][j] = MatrixC21[i][j];  
218.            MatrixC[i+N/2][j+N/2] = MatrixC22[i][j];  
219.        }  
220.    }  
221.    delete MatrixA11;delete MatrixA12;delete MatrixA21;delete MatrixA22;  
222.    delete MatrixB11;delete MatrixB12;delete MatrixB21;delete MatrixB22;  
223.    delete MatrixC11;delete MatrixC12;delete MatrixC21;delete MatrixC22;  
224.    delete MatrixS1;delete MatrixS2;delete MatrixS3;delete MatrixS4;delete MatrixS5;  
225.    delete MatrixS6;delete MatrixS7;delete MatrixS8;delete MatrixS9;delete MatrixS10;  
226.      
227.}  
228.  
229.int main()  
230.{
    
      
231.  
232.    int i,j,k,t;  
233.    int n,m;  
234.    scanf("%d %d",&n,&m);//多少对、多少阶  
235.    int** MatrixA = new int *[m];  
236.    int** MatrixB = new int *[m];  
237.    int** MatrixC = new int *[m];//测试Strassen矩阵  
238.    for (int i = 0; i < m; i++)  //分配连续内存非常重要!!  
239.    {
    
      
240.        MatrixA[i] = new int[m];  
241.        MatrixB[i] = new int[m];  
242.        MatrixC[i] = new int[m];  
243.    }  
244.  
245.    for(k=0;k<n;k++)//外侧大循环  
246.    {
    
      
247.        for(i=0;i<m;i++)//输入了两个即一对矩阵  
248.        {
    
      
249.            for(j=0;j<m;j++)  
250.            {
    
      
251.                scanf("%d",&MatrixA[i][j]);  
252.            }  
253.        }  
254.  
255.        for(i=0;i<m;i++)  
256.        {
    
      
257.            for(j=0;j<m;j++)  
258.            {
    
      
259.                scanf("%d",&MatrixB[i][j]);  
260.                MatrixC[i][j] = 0;  
261.            }  
262.        }  
263.          
264.        strassen(m,MatrixA,MatrixB,MatrixC);//m阶的矩阵  
265.        PrintMatrix(MatrixC, m);  
266.          
267.    }  
268.    return 0;  
269.}  

四、总结

这个算法好难写啊呜哇呜哇~~~~

猜你喜欢

转载自blog.csdn.net/m0_51499597/article/details/120535626