На этом шаге мы рассмотрим особенности этого алгоритма.
Самая затратная по времени арифметическая операция в предыдущих алгоритмах - это скалярное умножение в двух начальных условиях. Оба они, подобно простой итерационной версии с тройным циклом, требуют p*q*r таких умножений. Однако небезынтересно оценить временную сложность для исходных матриц размерности n*n. В этом случае время выполнения можно определить следующей функцией:
1, если n ≤ 1, T(n) = (6.6) 8T(n/2) + 4Θ(n2), если n > 1,
Метод, как и стандартный алгоритм, разбивает каждую из входных матриц на четыре блока. Таким образом, AB = C можно записать как:
⌈ ⌉ ⌈ ⌉ ⌈ ⌉ A1,1 A1,2 B1,1 B1,2 С1,1 С1,2 = A2,1 A2,2 B2,1 B2,2 С2,1 С2,2 ⌊ ⌋ ⌊ ⌋ ⌊ ⌋
Цель метода - определить следующие новые матрицы, которые используют всего одну операцию умножения матриц:
М1 = (A1,1 + A2,2)(B1,1 + B2,2) М2 = (A2,1 + A2,2) B1,1 M3 = A1,1 (B1,2 - B2,2) M4 = A2,2 (B2,1 - B1,1) (6.7) M5 = (A1,1 + A1,2) B2,2 M6 = (A2,1 - A1,1)(B1,1 + B1,2) M7 = (A1,2 - A2,2)(B2,1 + B2,2).
После чего эти матрицы могут быть сгруппированы так, чтобы сформировать выходные блочные матрицы:
C1,1 = M1 + M4 - M5 + M7 C1,2 = M3 + M5 (6.8) C2,1 = M2 + M4 C2,2 = M1 - M2 + M3 + M6.
Таким образом, в каждом рекурсивном вызове алгоритм выполняет 7 произведений и 18 сложений (или вычитаний). Поэтому оценка времени его выполнения:
1, если n ≤ 1, T(n) = (6.9) 7T(n/2) + 18Θ(n2), если n > 1,
Наконец, теоретически входы этого алгоритма должны быть квадратными матрицами n*n, где n - степень двух. На практике эффективные реализации разбивают матрицы на множество квадратных подматриц и неоднократно применяют этот алгоритм. Более простая, но медленная альтернатива - дополнить (расширить) входные матрицы нулями до размерности 2k*2k.
На следующем шаге мы рассмотрим задачу укладки тримино.