Изменения

Перейти к: навигация, поиск

Метод четырёх русских для умножения матриц

254 байта убрано, 07:00, 16 декабря 2011
Нет описания правки
== Код алгоритма ==
<code>
int n, cur; vector <vector <int> > a, b, preculc, anew, bnew, ans; int main() { freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout); cin >> n; a.resize(n); b.resize(n); ans.resize(n); // Чтение матриц for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { cin >> cur; a[i].push_back(cur); } for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { cin >> cur; b[i].push_back(cur); }
// Предподсчёт скалярных произведений
int k = ceil(log( (double) n)); preculc.resize(1 << k); for (int i I = 0; i < (to 2^k - 1 << k); i++)do for (int j J = 0; j < (to 2^k - 1 << k); j++) do { int scalmul = 0; for (int pos = 0; pos < k; pos++) if (((1 << pos) & i) != 0 && ((1 << pos) & j) != 0) { scalmul = (scalmul + 1) % 2; }Считаем скалярное произведение двоичных векторов, заданных двоичным представлением чисел I и J. Записываем результат в матрицу preculc, где precul[I][iJ].push_back(scalmul);- "скалярное произведение для битовых представлений" I и J
}
// Создание сжатых матриц
int m = ceilчисло (((double) n) / k);, округленное вверх anew.resize(n); bnew.resize(m); for (int i I = 0; i < to n; i++) - 1 { for (int start = 0; для всех стартовых позиций группы из k элементов start < n; start += k) { int cursuma = 0Считаем сумму в горизонтальной группе матрицы a, cursumb = 0, curpos = которая начинается с позиции start, deg = (1 << (k - 1));и записываем десятичное значение полученного двоичного представления в а'. while (curpos < Считаем сумму в вертикальной группе матрицы b, которая начинается с позиции start + k && curpos < n) { cursuma += a[i][curpos] * deg; cursumb += , и записываем десятичное значение полученного двоичного представления в b[curpos][i] * deg; deg /= 2; curpos++; } anew[i].push_back(cursuma); bnew[start / k]'.push_back(cursumb);
}
}
//Перемножение полученных матриц
for (int i I = 0; i < to n; i++)- 1 do for (int j J = 0; j < to n; j++) - 1 do { int curans = 0; for (int pos = 0; pos < m; pos++) { curans = (curans + Считаем сумму по модулю 2 всех произведений группы чисел из k элементов, пользуясь предподсчётом preculc[anew[i][pos]][bnew[pos][j]]) % 2; }. ans[i]Записываем полученное значение в матрицу ответа.push_back(curans);
}
// Вывод ответа for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cout << ans[i][j] << " "; } cout << endl; } return 0; }
</code>
== Ссылки ==
Анонимный участник

Навигация