两个n×n的矩阵相乘,按照定义来写算法,算法的时间复杂度是O(n³)。
Strassen算法是一个分治算法,可以将矩阵相乘的时间复杂度降为O(n^lg7)。
按照定义计算的算法,代码如下:
var a = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]; var b = [[1,5,9,13],[2,6,10,14],[3,7,11,15],[4,8,12,16]]; var d = [[1,3],[7,5]]; var e = [[6,8],[4,2]]; var c = squareMatrixMultiply(a, b); console.log(c); var f = squareMatrixMultiply(d, e); console.log(f); function squareMatrixMultiply(a, b){ var c = []; var n = a.length; for(var i = 0; i < n; i++){ c[i] = []; for(var j = 0; j < n; j++){ var cij = 0; for(var k = 0; k < n; k++){ cij += a[i][k] * b[k][j]; } c[i][j] = cij; } } return c; }
Strassen算法
var a = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]; var b = [[1,5,9,13],[2,6,10,14],[3,7,11,15],[4,8,12,16]]; var d = [[1,3],[7,5]]; var e = [[6,8],[4,2]]; var g = squareMatrixMultiplyRecursive(a, 0, 0, b, 0, 0, 4); console.log(g); var h = squareMatrixMultiplyRecursive(d, 0, 0, e, 0, 0, 2); console.log(h); function squareMatrixMultiplyRecursive(a, ai0, aj0, b, bi0, bj0, n){ var c = []; if(n == 1){ c[0] = []; c[0][0] = a[ai0][aj0] * b[bi0][bj0]; } else { var hn = n / 2; merge( squareMatrixMultiplyRecursive( a, ai0, aj0, b, bi0, bj0, hn), squareMatrixMultiplyRecursive( a, ai0, aj0 + hn, b, bi0 + hn, bj0, hn), c, 0, 0, hn );//c11 = a11 * b11 + a12 * b21; merge( squareMatrixMultiplyRecursive( a, ai0, aj0, b, bi0, bj0 + hn, hn), squareMatrixMultiplyRecursive( a, ai0, aj0 + hn, b, bi0 + hn, bj0 + hn, hn), c, 0, hn, hn );//c12 = a11 * b12 + a12 * b22; merge( squareMatrixMultiplyRecursive( a, ai0 + hn, aj0, b, bi0, bj0, hn), squareMatrixMultiplyRecursive( a, ai0 + hn, aj0 + hn, b, bi0 + hn, bj0, hn), c, hn, 0, hn );//c21 = a21 * b11 + a22 * b21; merge( squareMatrixMultiplyRecursive( a, ai0 + hn, aj0, b, bi0, bj0 + hn, hn), squareMatrixMultiplyRecursive( a, ai0 + hn, aj0 + hn, b, bi0 + hn, bj0 + hn, hn), c, hn, hn, hn );//c22 = a21 * b12 + a22 * b22; } return c; } function merge(a, b, c, i0, j0, n){ for(var i = 0; i < n; i++){ c[i0 + i] = c[i0 + i] || []; for(var j = 0; j < n; j++){ c[i0+i][j0+j] = a[i][j] + b[i][j]; } } }
Strassen算法时间复杂度降低了,但是空间复杂度太高了。
目前,n×n矩阵相乘的渐进复杂性最优的算法是Coppersmith和Winograd提出的,运行时间为O(n^2.376)。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。