Advertisement
Argent007

АОВС алгоритм Штрассена

Apr 19th, 2023
37
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.32 KB | None | 0 0
  1. // ConsoleApplication2.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
  2. //
  3.  
  4. #include <iostream>
  5. #include <vector>
  6. #include <algorithm>
  7.  
  8. using std::vector;
  9.  
  10. const int min_fast_mult_size = 64;
  11.  
  12. class matrix
  13. {
  14.     vector<vector<double>> m;
  15.     matrix _get_block(int r, int c, int size)const;
  16.     void _write_block(int r, int c, const matrix& block);
  17.     matrix _fastmult(const matrix& arg)const;
  18. public:
  19.     matrix(int n) { m.assign(n, vector<double>(n)); }
  20.     const vector<double>& operator[](int row)const { return m[row]; }
  21.     vector<double>& operator[](int row) { return m[row]; }
  22.     matrix operator+(const matrix& arg)const;
  23.     matrix operator-(const matrix& arg)const;
  24.     friend matrix mult(const matrix& arg1, const matrix& arg2); //обычное умножение
  25.     matrix operator*(const matrix& arg)const; //быстрое умножение
  26.     bool operator==(const matrix& arg)const { return m == arg.m; }
  27. };
  28.  
  29. int main()
  30. {
  31.     matrix  A(500), B(500);
  32.     for (size_t i = 0; i < 500; i++)
  33.     {
  34.         for (size_t j = 0; j < 500; j++)
  35.         {
  36.             A[i][j] = rand() % 10;
  37.             B[i][j] = rand() % 10;
  38.         }
  39.     }
  40.     matrix R1 = mult(A, B);
  41.     matrix R2 = A * B;
  42.     std::cout << (R1==R2) << "\n";
  43. }
  44.  
  45. // Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки"
  46. // Отладка программы: F5 или меню "Отладка" > "Запустить отладку"
  47.  
  48. // Советы по началу работы
  49. //   1. В окне обозревателя решений можно добавлять файлы и управлять ими.
  50. //   2. В окне Team Explorer можно подключиться к системе управления версиями.
  51. //   3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения.
  52. //   4. В окне "Список ошибок" можно просматривать ошибки.
  53. //   5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода.
  54. //   6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл.
  55.  
  56. matrix matrix::_get_block(int r, int c, int size) const
  57. {
  58.     matrix block(size);
  59.     for (size_t i = 0; i < size; i++)
  60.         for (size_t j = 0; j < size; j++)
  61.             block[i][j] = m[r + i][c + j];
  62.     return block;
  63. }
  64.  
  65. void matrix::_write_block(int r, int c, const matrix& block)
  66. {
  67.     int size = block.m.size();
  68.     for (size_t i = 0; i < size; i++)
  69.         for (size_t j = 0; j < size; j++)
  70.             m[r + i][c + j] = block[i][j];
  71. }
  72.  
  73. matrix matrix::_fastmult(const matrix& arg) const
  74. {
  75.     int n = m.size();
  76.     int half_n = n / 2;
  77.     if (n <= min_fast_mult_size)
  78.         return mult(*this, arg);
  79.     matrix a = _get_block(0, 0, half_n);
  80.     matrix b = _get_block(0, half_n, half_n);
  81.     matrix c = _get_block(half_n, 0, half_n);
  82.     matrix d = _get_block(half_n, half_n, half_n);
  83.     matrix e = arg._get_block(0, 0, half_n);
  84.     matrix g = arg._get_block(0, half_n, half_n);
  85.     matrix f = arg._get_block(half_n, 0, half_n);
  86.     matrix h = arg._get_block(half_n, half_n, half_n);
  87.     matrix P1 = a._fastmult(g - h);
  88.     matrix P2 = (a+b)._fastmult(h);
  89.     matrix P3 = (c+d)._fastmult(e);
  90.     matrix P4 = d._fastmult(f - e);
  91.     matrix P5 = (a+d)._fastmult(e + h);
  92.     matrix P6 = (b - d)._fastmult(f + h);
  93.     matrix P7 = (a - c)._fastmult(e + g);
  94.     matrix res(n);
  95.     res._write_block(0, 0, P5 + P6 + P4 - P2);
  96.     res._write_block(0, half_n, P1 + P2);
  97.     res._write_block(half_n, 0, P3 + P4);
  98.     res._write_block(half_n, half_n, P5 + P1 -P7 - P3);
  99.     return res;
  100. }
  101.  
  102. matrix matrix::operator+(const matrix& arg) const
  103. {
  104.     int n = m.size();
  105.     matrix res(n);
  106.     for (size_t i = 0; i < n; i++)
  107.         for (size_t j = 0; j < n; j++)
  108.             res[i][j] = m[i][j] + arg[i][j];
  109.     return res;
  110. }
  111.  
  112. matrix matrix::operator-(const matrix& arg) const
  113. {
  114.     int n = m.size();
  115.     matrix res(n);
  116.     for (size_t i = 0; i < n; i++)
  117.         for (size_t j = 0; j < n; j++)
  118.             res[i][j] = m[i][j] - arg[i][j];
  119.     return res;
  120. }
  121.  
  122. matrix matrix::operator*(const matrix& arg) const
  123. {
  124.     int n = m.size();
  125.     int count = 0, N=n;
  126.     while (N >= min_fast_mult_size)
  127.     {
  128.         N /= 2;
  129.         ++count;
  130.     }
  131.     N = (N + 1) << count;
  132.     matrix X(N), Y(N);
  133.     X._write_block(0, 0, *this);
  134.     Y._write_block(0, 0, arg);
  135.     return (X._fastmult(Y))._get_block(0,0,n);
  136. }
  137.  
  138. matrix mult(const matrix& arg1, const matrix& arg2)
  139. {
  140.     int n = arg1.m.size();
  141.     matrix res(n);
  142.     for (size_t i = 0; i < n; i++)
  143.         for (size_t j = 0; j < n; j++)
  144.             for (size_t k = 0; k < n; k++)
  145.                 res[i][j] += arg1[i][k] * arg2[k][j];
  146.     return res;
  147. }
  148.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement