Strassen-algoritmus
Kiejtés
- IPA: [ ˈʃtrɒʃːɛnɒlɡoritmuʃ]
Főnév
- (matematika, algoritmusok) A **Strassen-algoritmus** egy hatékony mátrixszorzási algoritmus, amely csökkenti a hagyományos mátrixszorzás számítási komplexitását. Hans Werner Strassen fejlesztette ki 1969-ben, és különösen nagy méretű mátrixok szorzásakor nyújt jelentős előnyt.
—
- **Hagyományos mátrixszorzás komplexitása**
Két -es mátrix szorzása hagyományos módszerrel időbonyolultságú, mivel minden mátrixelem kiszámításához szorzás és összeadás szükséges.
Strassen algoritmusa optimalizálja ezt a folyamatot, és a komplexitást -re csökkenti.
—
- **Strassen-algoritmus működése**
- **Fő ötlet** Az algoritmus a mátrixszorzást **rekurzív felbontással** végzi: 1. A két -es mátrixot négy -es blokkmátrixra bontja. 2. A al-mátrixszorzás kiszámítása után a végeredményt ezekből állítja össze, csökkentve a szükséges szorzások számát (a hagyományos -ról -re).
- **Mátrixok felbontása**: Legyen és az -es mátrixok:
- **Strassen-féle 7 szorzás**: A hét szorzás az alábbiak szerint történik:
- **Végeredmény összeállítása**: A mátrix blokkjai az alábbi módon állnak elő:
—
- **Időbonyolultság**
- **Rekurzív felosztás**: - Az algoritmus minden lépésben szorzást és összeadást/levonást végez. - **Összkomplexitás**: Ez a **Master-tétel** alapján:
—
- **Példa**
- **Mátrixok**:
- **Blokkok**: Hasonlóképpen feloszthatók .
- **Strassen-módszer**: 1. Számítsuk ki a értékeit. 2. Állítsuk össze a mátrixot.
—
Python implementáció
import numpy as np
def add_matrix(A, B):
return np.add(A, B)
def sub_matrix(A, B):
return np.subtract(A, B)
def strassen(A, B):
n = A.shape[0]
if n == 1:
return A * B
k = n // 2
# Mátrixok felosztása
A11, A12, A21, A22 = A[:k, :k], A[:k, k:], A[k:, :k], A[k:, k:]
B11, B12, B21, B22 = B[:k, :k], B[:k, k:], B[k:, :k], B[k:, k:]
# Strassen-féle szorzások
M1 = strassen(add_matrix(A11, A22), add_matrix(B11, B22))
M2 = strassen(add_matrix(A21, A22), B11)
M3 = strassen(A11, sub_matrix(B12, B22))
M4 = strassen(A22, sub_matrix(B21, B11))
M5 = strassen(add_matrix(A11, A12), B22)
M6 = strassen(sub_matrix(A21, A11), add_matrix(B11, B12))
M7 = strassen(sub_matrix(A12, A22), add_matrix(B21, B22))
# Mátrix blokkok összeállítása
C11 = add_matrix(sub_matrix(add_matrix(M1, M4), M5), M7)
C12 = add_matrix(M3, M5)
C21 = add_matrix(M2, M4)
C22 = add_matrix(sub_matrix(add_matrix(M1, M3), M2), M6)
# Mátrixok összeillesztése
C = np.zeros((n, n))
C[:k, :k], C[:k, k:], C[k:, :k], C[k:, k:] = C11, C12, C21, C22
return C
# Példa használat
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
C = strassen(A, B)
print("A × B =")
print(C)
Kimenet:
A × B = [[19 22] [43 50]]
C++ implementáció
#include <iostream>
#include <vector>
using namespace std;
using Matrix = vector<vector<int>>;
Matrix add_matrix(const Matrix& A, const Matrix& B) {
int n = A.size();
Matrix C(n, vector<int>(n));
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
C[i][j] = A[i][j] + B[i][j];
return C;
}
Matrix sub_matrix(const Matrix& A, const Matrix& B) {
int n = A.size();
Matrix C(n, vector<int>(n));
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
C[i][j] = A[i][j] - B[i][j];
return C;
}
Matrix strassen(const Matrix& A, const Matrix& B) {
int n = A.size();
if (n == 1) {
return {{A[0][0] * B[0][0]}};
}
int k = n / 2;
Matrix A11(k, vector<int>(k)), A12(k, vector<int>(k)),
A21(k, vector<int>(k)), A22(k, vector<int>(k)),
B11(k, vector<int>(k)), B12(k, vector<int>(k)),
B21(k, vector<int>(k)), B22(k, vector<int>(k));
for (int i = 0; i < k; ++i) {
for (int j = 0; j < k; ++j) {
A11[i][j] = A[i][j];
A12[i][j] = A[i][j + k];
A21[i][j] = A[i + k][j];
A22[i][j] = A[i + k][j + k];
B11[i][j] = B[i][j];
B12[i][j] = B[i][j + k];
B21[i][j
] = B[i + k][j];
B22[i][j] = B[i + k][j + k];
}
}
auto M1 = strassen(add_matrix(A11, A22), add_matrix(B11, B22));
auto M2 = strassen(add_matrix(A21, A22), B11);
auto M3 = strassen(A11, sub_matrix(B12, B22));
auto M4 = strassen(A22, sub_matrix(B21, B11));
auto M5 = strassen(add_matrix(A11, A12), B22);
auto M6 = strassen(sub_matrix(A21, A11), add_matrix(B11, B12));
auto M7 = strassen(sub_matrix(A12, A22), add_matrix(B21, B22));
Matrix C(n, vector<int>(n));
for (int i = 0; i < k; ++i) {
for (int j = 0; j < k; ++j) {
C[i][j] = M1[i][j] + M4[i][j] - M5[i][j] + M7[i][j];
C[i][j + k] = M3[i][j] + M5[i][j];
C[i + k][j] = M2[i][j] + M4[i][j];
C[i + k][j + k] = M1[i][j] - M2[i][j] + M3[i][j] + M6[i][j];
}
}
return C;
}
int main() {
Matrix A = {{1, 2}, {3, 4}};
Matrix B = {{5, 6}, {7, 8}};
Matrix C = strassen(A, B);
cout << "A × B = " << endl;
for (const auto& row : C) {
for (int val : row)
cout << val << " ";
cout << endl;
}
return 0;
}
Kimenet:
A × B = 19 22 43 50
Előnyök
- Gyorsabb, mint a hagyományos módszer nagyobb mátrixok esetén.
- Hatékony rekurzív algoritmus.
Hátrányok
- További memóriaigény a mátrixok felosztása miatt.
- Nehéz implementáció nagyobb rendszerekhez.
Alkalmazások
- Nagy mátrixok szorzása gépi tanulásban, jelfeldolgozásban.
- Tudományos számítások optimalizálása.
Összegzés
A Strassen-algoritmus hatékony módszer a mátrixszorzás gyorsítására, amely csökkenti a számítási költségeket nagy mátrixok esetén. Bár komplexebb, mint a hagyományos módszer, jelentős előnyt nyújt modern alkalmazásokban.
Fordítások
Tartalom
- Strassen-algoritmus - Értelmező szótár (MEK)
- Strassen-algoritmus - Etimológiai szótár (UMIL)
- Strassen-algoritmus - Szótár.net (hu-hu)
- Strassen-algoritmus - DeepL (hu-de)
- Strassen-algoritmus - Яндекс (hu-ru)
- Strassen-algoritmus - Google (hu-en)
- Strassen-algoritmus - Helyesírási szótár (MTA)
- Strassen-algoritmus - Wikidata
- Strassen-algoritmus - Wikipédia (magyar)