問題:給定兩個n階方陣相乘,對求解演算法進行優化。
首先,根據傳統演算法,兩個n階矩陣相乘,對於n2個元素,每個元素想要被計算出來,至少要進行n次乘法和n-1次加法,演算法複雜度達到o(n3)。
考慮將矩陣分塊,分為4個n/2的方陣,那麼每個兩個小方陣相乘的複雜度為o(n3)/8,要想得出最終結果,一共需要8次小方陣相乘,複雜度沒有減小。
為了減小複雜度,必須減小相乘的次數。
strassen乘法:通過數學構造,將8個不同的小方陣轉化為7個不同的小方陣,從而減少相乘的次數。
**:
#include using namespace std;
void matrixadd(int **a,int **b,int **c,int n)
void matrixsub(int **a,int **b,int **c,int n)
// 用strassen演算法計算矩陣a與b的乘積,儲存在矩陣c中
// 輸入:矩陣a,b,c,矩陣維數n
void matrixmulti(int **a,int **b,int **c,int n)else
//分割輸入矩陣a和b
for(int i = 0;i < n/2;i++)
}//計算p1~p7
matrixadd(a11, a22, as, n/2);
matrixadd(b11, b22, bs, n/2);
matrixmulti(as, bs, p1, n/2);
matrixadd(a21, a22, as, n/2);
matrixmulti(as, b11, p2, n/2);
matrixsub(b12, b22, bs, n/2);
matrixmulti(a11, bs, p3, n/2);
matrixsub(b21, b11, bs, n/2);
matrixmulti(a22, bs, p4, n/2);
matrixadd(a11, a12, as, n/2);
matrixmulti(as, b22, p5, n/2);
matrixsub(a21, a11, as, n/2);
matrixadd(b11, b12, bs, n/2);
matrixmulti(as, bs, p6, n/2);
matrixsub(a12, a22, as, n/2);
matrixadd(b21, b22, bs, n/2);
matrixmulti(as, bs, p7, n/2);
//計算c的各個分塊
matrixadd(p1, p4, as, n/2);
matrixsub(p7, p5, bs, n/2);
matrixadd(as, bs, c11, n/2);
matrixadd(p3, p5, c12, n/2);
matrixadd(p2, p4, c21, n/2);
matrixadd(p1, p3, as, n/2);
matrixsub(p6, p2, bs, n/2);
matrixadd(as, bs, c22, n/2);
//將小矩陣組合為大矩陣c
for(int i = 0;i < n/2;i++)
for(int j = 0;j < n/2;j++)
//**分配的記憶體空間
for(int i = 0;i < n/2;i++)
delete a11;
delete a12;
delete a21;
delete a22;
delete b11;
delete b12;
delete b21;
delete b22;
delete c11;
delete c12;
delete c21;
delete c22;
delete p1;
delete p2;
delete p3;
delete p4;
delete p5;
delete p6;
delete p7;
delete as;
delete bs;
}}// 測試資料:0~63的8*8矩陣
int main()
int cnt = 0;
for(int i = 0;i < n;i++)
for(int j = 0;j < n;j++)
matrixmulti(a, b, c, n);
for(int i = 0;i < n;i++){
for(int j = 0;j < n;j++){
cout《在c++中,二維矩陣作為函式的形參主要有以下幾種方式:
採用類似一維陣列的方式,但是必須指明第二維的確切大小,適合維度明確的引數,實參為陣列名
int a[3][4]
int a[4]
int (*a)[4]
在函式內訪問陣列元素時,正常訪問即可
二維陣列當成一維陣列訪問,不需要指明第二維的確切大小,實參實際上是二維陣列的首個元素的位置,可以是*a,也可以是a[0]
int *a
在函式內訪問陣列元素時,可以正常訪問,也可以按照以下方式訪問:
*(p+i*col+j)
二維陣列通過二級指標傳遞,不需要指明第二維的確切大小,實參必須是指標,可以是陣列名
int **a
需要注意的是,需要對二級指標進行記憶體的分配與**:
int **a;
a = new int*[row];
for(int i = 0;i < row;i++)
a[i] = new int[col];
for(int i = 0;i < row;i++)
delete a[i];
delete a;
此外還有什麼強制型別轉換的方法,沒看懂,這裡不整理了。
當然了,沒有維度限制的二維矩陣相乘還可以使用vector。
Strassen s 矩陣乘法 分治法實現
內容會持續更新,有錯誤的地方歡迎指正,謝謝 題目 1.比較數學定義的矩陣乘法演算法和strassen s 矩陣乘法演算法的效率 2.自主生成兩個16 16的矩陣,輸出strassen s 矩陣乘法演算法結果。數學定義的矩陣乘法演算法 利用三個for迴圈來解決,時間複雜度為o n 3 數學定義的矩陣乘...
大整數乘法 分治法
import sys def add n1,n2 字串加法 n1 n1 1 n2 n2 1 補齊到和的最大位數 相加後可能在最後進一位,所以末尾補乙個0 if len n1 1 and sum 0 0 sum sum 1 return sum def muti x1,x2 xi 123435 5 分...
矩陣相乘(分治法)
乙個簡單的分治演算法求矩陣相乘 c a b 假設三個矩陣均為n n,n為2的冪。可以對其分解為4個n 2 n 2的子矩陣分別遞迴求解 遞迴分治演算法 演算法中乙個重要的細節就是在分塊的時候,採用的是下標的方式。include include define row 16 指定 行數 define co...