Advertisement
Heart_Under_Blade

exception

Dec 25th, 2021
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.42 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <vector>
  4. #include <omp.h>
  5. #include <chrono>
  6.  
  7. #pragma region Region_1
  8.  
  9. #define per(name, beg, en) for (int name = beg; name <= en; ++name)
  10. #define rep(name, beg, en) for (int name = beg; name >= en; --name)
  11.  
  12. #define pb push_back
  13. #define mp make_pair
  14. #define sz(x) (int)(x).size()
  15.  
  16. #define F first
  17. #define S second
  18. #define FF first.first
  19. #define FS first.second
  20. #define SF second.first
  21. #define SS second.second
  22.  
  23. #pragma endregion
  24.  
  25. using namespace std;
  26.  
  27. class Timer
  28. {
  29. private:
  30.     // Псевдонимы типов используются для удобного доступа к вложенным типам
  31.     using clock_t = std::chrono::high_resolution_clock;
  32.     using second_t = std::chrono::duration<double, std::ratio<1> >;
  33.  
  34.     std::chrono::time_point<clock_t> m_beg;
  35.     double last_elapsed;
  36. public:
  37.     Timer() : m_beg(clock_t::now()), last_elapsed(0)
  38.     {
  39.     }
  40.  
  41.     void reset()
  42.     {
  43.         m_beg = clock_t::now();
  44.         last_elapsed = 0.0;
  45.     }
  46.  
  47.     double elapsed()
  48.     {
  49.         last_elapsed = std::chrono::duration_cast<second_t>(clock_t::now() - m_beg).count();
  50.         return last_elapsed;
  51.     }
  52.  
  53.     inline double getLastElapsed()
  54.     {
  55.         return last_elapsed;
  56.     }
  57. };
  58.  
  59. using pii = pair<int, int>;
  60.  
  61. using GraphList = vector<vector<pii>>;       // Граф списком смежности
  62. using GraphMatrix = vector<vector<int>>;     // Граф матрицей смежности
  63.  
  64. const int inf = INT_MAX;
  65. const pii pinf = mp(inf, inf);
  66.  
  67. /// <summary>
  68. /// Находит ребро с конечной вершиной [v] в списке смежности [vec] от начальной вершины
  69. /// </summary>
  70. /// <param name="vec"> - список смежности для начальной вершины</param>
  71. /// <param name="v"> - конечная вершина</param>
  72. /// <returns></returns>
  73. inline pii finder(const vector < pii >& vec, int v)
  74. {
  75.     pii ans = pinf;
  76.     ans.F = v;
  77.  
  78.     for (const auto& x : vec)
  79.         if (x.F == v && x.S < ans.S)
  80.         {
  81.             ans = x;
  82.         }
  83.     return ans;
  84. }
  85.  
  86. inline void matrixPrinter(const GraphMatrix& graph, ostream& out)
  87. {
  88.     size_t size = graph.size();
  89.     per(u, 1, size - 1)
  90.     {
  91.         per(v, 1, size - 1)
  92.             out << ((graph[u][v] == inf) ? 0 : graph[u][v]) << " \t";
  93.         out << endl;
  94.     }
  95. }
  96.  
  97. inline void listPrinter(const GraphMatrix& graph, ostream& out)
  98. {
  99.     size_t size = graph.size();
  100.     per(u, 1, size - 1)
  101.     {
  102.         per(v, 1, size - 1)
  103.         {
  104.             if (u != v && graph[u][v] != inf)
  105.             {
  106.                 out << u << " \t" << v << " \t" << graph[u][v] << endl;
  107.             }
  108.         }
  109.     }
  110. }
  111.  
  112. /// <summary>
  113. /// Алгоритм Флойда от матрицы смежности
  114. /// </summary>
  115. /// <param name="sD"> Начальная матрица смежности, она же результат работы</param>
  116. inline void _floyd(GraphMatrix& sD, int numThreads = omp_get_max_threads())
  117. {
  118.     size_t size = sD.size();
  119.  
  120.     for (int i = 1; i < size; i++)
  121.     {
  122. #pragma omp parallel for num_threads(numThreads) schedule(dynamic, 200)
  123.         for (int u = 1; u < size; u++)
  124.         {
  125.             for (int v = 1; v < size; v++)
  126.             {
  127.                 if (sD[u][i] < inf && sD[i][v] < inf)
  128.                     sD[u][v] = min(sD[u][v], sD[u][i] + sD[i][v]);
  129.             }
  130.         }
  131.     }
  132. }
  133.  
  134. void floydAlgMatrix(const GraphMatrix& graph, ostream& out, int numThreads = omp_get_max_threads())
  135. {
  136.     //GraphMatrix sD = graph;
  137.     GraphMatrix sD;
  138.     int size = static_cast<int>(sz(graph));
  139.     sD.resize(size);
  140.  
  141. #pragma omp parallel for num_threads(numThreads)
  142.     per(u, 1, size - 1)
  143.     {
  144.         sD[u].resize(size);
  145.  
  146.         per(v, 1, size - 1)
  147.             if (graph[u][v] != 0)
  148.                 sD[u][v] = graph[u][v];
  149.             else
  150.                 sD[u][v] = inf;
  151.     }
  152.     _floyd(sD, numThreads);
  153.  
  154.     listPrinter(sD, out);
  155. }
  156.  
  157. void floydAlgList(const GraphList& graph, ostream& out, int numThreads = omp_get_max_threads())
  158. {
  159.     GraphMatrix sD;
  160.     int size = static_cast<int>(sz(graph));
  161.     sD.resize(size);
  162.  
  163. #pragma omp parallel for num_threads(numThreads)
  164.     per(i, 1, size - 1)
  165.     {
  166.         sD[i].pb(0);   // Заполняем нулевые элементы каждого ряда
  167.         per(j, 1, size - 1)
  168.         {
  169.             sD[i].pb(finder(graph[i], j).S);
  170.         }
  171.     }
  172.  
  173.     _floyd(sD, numThreads);
  174.  
  175.     listPrinter(sD, out);
  176. }
  177.  
  178. // Ввод данных и вызов методов
  179. void solve(int num_threads)
  180. {
  181.     ifstream in("input.txt");
  182.     if (!in.is_open()) throw exception("File input.txt wasn't open!");
  183.  
  184.     int n, m;
  185.     in >> n >> m;
  186.  
  187.     GraphMatrix matrixGraph;         // граф матрицей смежности
  188.     GraphList listGraph;             // граф списком смежности
  189.     listGraph.resize(n + 1);
  190.     matrixGraph.resize(n + 1);
  191.     per(i, 1, n)
  192.         matrixGraph[i].resize(n + 1, 0);
  193.  
  194.     per(i, 1, m)
  195.     {
  196.         int u, v, w;
  197.         in >> u >> v >> w;
  198.         matrixGraph[u][v] = matrixGraph[v][u] = (matrixGraph[u][v] == 0 ? w : min(w, matrixGraph[u][v]));
  199.         listGraph[u].pb(mp(v, w));
  200.         listGraph[v].pb(mp(u, w));
  201.     }
  202.     in.close();
  203.  
  204.     ofstream outMatrix("output.txt");
  205.     Timer timer;
  206.     floydAlgMatrix(matrixGraph, outMatrix, num_threads);
  207.     timer.elapsed();
  208.     cout << "Алгоритм по матрице завершил работу за " << timer.getLastElapsed() << " секунд" << endl;
  209.     outMatrix.close();
  210.  
  211.     ofstream outList("output.txt");
  212.     timer.reset();
  213.     floydAlgList(listGraph, outList, num_threads);
  214.     timer.elapsed();
  215.     cout << "Алгоритм по листу завершил работу за   " << timer.getLastElapsed() << " секунд" << endl;
  216.     outList.close();
  217. }
  218.  
  219. int main()
  220. {
  221.     setlocale(LC_ALL, "ru");
  222.     vector<int> numThreadsList = { 1 };
  223.     for (int i = 2; i <= omp_get_max_threads(); i += 2) numThreadsList.push_back(i);
  224.  
  225.     for (auto& numThreads : numThreadsList)
  226.     {
  227.         cout << "************************************" << endl;
  228.         cout << "Работа алгоритмов для [" << numThreads << "] потоков: " << endl << endl;
  229.         solve(numThreads);
  230.         cout << "************************************" << endl << endl;
  231.     }
  232. }
  233.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement