矩阵的应用的场景是计算矩阵A的n次幂,也就是为了加速
An
的过程,我们可以通过矩阵的结合律来使我们的矩阵次数减少从而来达到加速矩阵连乘的问题。我们通过一个例子来看一下,假如我们需要计算
A6
的话,常规我们需要乘5次,但是我们要利用结合律来改进我们的连乘问题,
(A∗A)∗(A∗A)∗(A∗A)
,这样一来我们只需要计算三次乘法就足够了,好那么我们将具体进行抽象,在计算我们的
An
的时候应该采取怎样的策略呢?一个很巧妙的思想那就是利用二进制来确定,因为在计算完
(A2)n
的时候我们可以用一个变量将其保存下来,这样一来我们就可以减少计算量,例如我们在计算
A9
的时候可以变为
A8∗A
,
((A2)2)2∗A
,因为
9
的二进制数为js
代码来实现一下这个思想:
// 测试数组
var A = [[2, 1], [4, 3]],
B = [[1, 2], [1, 0]];
function Counting (matrix, power) {
var res = 1;
while (power) {
if (power & 1) {
res = matrixMul(A, res);
}
power >>= 1;
if (power)
A = matrixMul(A, A);
}
return res;
}
// 封装矩阵乘法
function matrixMul (matrixA, matrixB) {
if (matrixA === 1) {
return matrixB;
} else if (matrixB === 1) {
return matrixA;
} else if (matrixA.length === void 0 || matrixB.length === void 0) {
var arr = matrixA.length ? matrixA : matrixB,
num = +(matrixA) || +(matrixB),
result = [];
for (var i = 0, len = arr.length; i < len; i++) {
result[i] = [];
for (var j = 0, childLen = arr[i].length; j < childLen; j++) {
result[i][j] = num * arr[i][j];
}
}
return result;
} else {
var result = [];
for (var i = 0; i < matrixA.length; i++) {
result[i] = [];
for (var k = 0; k < matrixB[0].length; k++) {
result[i][k] = 0;
for (var j = 0; j < matrixB.length; j++) {
result[i][k] += matrixA[i][j] * matrixB[j][k];
}
}
}
return result;
}
}
// 测试
console.log(matrixMul(A, 2)); // [ [ 4, 2 ], [ 8, 6 ] ]
console.log(matrixMul(A, B)); // [ [ 3, 4 ], [ 7, 8 ] ]
console.log(Counting(A, 4)); // [ [ 164, 105 ], [ 420, 269 ] ]