Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <fstream>
- #include <vector>
- #include <omp.h>
- #include <chrono>
- #pragma region Region_1
- #define per(name, beg, en) for (int name = beg; name <= en; ++name)
- #define rep(name, beg, en) for (int name = beg; name >= en; --name)
- #define pb push_back
- #define mp make_pair
- #define sz(x) (int)(x).size()
- #define F first
- #define S second
- #define FF first.first
- #define FS first.second
- #define SF second.first
- #define SS second.second
- #pragma endregion
- using namespace std;
- class Timer
- {
- private:
- // Псевдонимы типов используются для удобного доступа к вложенным типам
- using clock_t = std::chrono::high_resolution_clock;
- using second_t = std::chrono::duration<double, std::ratio<1> >;
- std::chrono::time_point<clock_t> m_beg;
- double last_elapsed;
- public:
- Timer() : m_beg(clock_t::now()), last_elapsed(0)
- {
- }
- void reset()
- {
- m_beg = clock_t::now();
- last_elapsed = 0.0;
- }
- double elapsed()
- {
- last_elapsed = std::chrono::duration_cast<second_t>(clock_t::now() - m_beg).count();
- return last_elapsed;
- }
- inline double getLastElapsed()
- {
- return last_elapsed;
- }
- };
- using pii = pair<int, int>;
- using GraphList = vector<vector<pii>>; // Граф списком смежности
- using GraphMatrix = vector<vector<int>>; // Граф матрицей смежности
- const int inf = INT_MAX;
- const pii pinf = mp(inf, inf);
- /// <summary>
- /// Находит ребро с конечной вершиной [v] в списке смежности [vec] от начальной вершины
- /// </summary>
- /// <param name="vec"> - список смежности для начальной вершины</param>
- /// <param name="v"> - конечная вершина</param>
- /// <returns></returns>
- inline pii finder(const vector < pii >& vec, int v)
- {
- pii ans = pinf;
- ans.F = v;
- for (const auto& x : vec)
- if (x.F == v && x.S < ans.S)
- {
- ans = x;
- }
- return ans;
- }
- inline void matrixPrinter(const GraphMatrix& graph, ostream& out)
- {
- size_t size = graph.size();
- per(u, 1, size - 1)
- {
- per(v, 1, size - 1)
- out << ((graph[u][v] == inf) ? 0 : graph[u][v]) << " \t";
- out << endl;
- }
- }
- inline void listPrinter(const GraphMatrix& graph, ostream& out)
- {
- size_t size = graph.size();
- per(u, 1, size - 1)
- {
- per(v, 1, size - 1)
- {
- if (u != v && graph[u][v] != inf)
- {
- out << u << " \t" << v << " \t" << graph[u][v] << endl;
- }
- }
- }
- }
- /// <summary>
- /// Алгоритм Флойда от матрицы смежности
- /// </summary>
- /// <param name="sD"> Начальная матрица смежности, она же результат работы</param>
- inline void _floyd(GraphMatrix& sD, int numThreads = omp_get_max_threads())
- {
- size_t size = sD.size();
- for (int i = 1; i < size; i++)
- {
- #pragma omp parallel for num_threads(numThreads) schedule(dynamic, 200)
- for (int u = 1; u < size; u++)
- {
- for (int v = 1; v < size; v++)
- {
- if (sD[u][i] < inf && sD[i][v] < inf)
- sD[u][v] = min(sD[u][v], sD[u][i] + sD[i][v]);
- }
- }
- }
- }
- void floydAlgMatrix(const GraphMatrix& graph, ostream& out, int numThreads = omp_get_max_threads())
- {
- //GraphMatrix sD = graph;
- GraphMatrix sD;
- int size = static_cast<int>(sz(graph));
- sD.resize(size);
- #pragma omp parallel for num_threads(numThreads)
- per(u, 1, size - 1)
- {
- sD[u].resize(size);
- per(v, 1, size - 1)
- if (graph[u][v] != 0)
- sD[u][v] = graph[u][v];
- else
- sD[u][v] = inf;
- }
- _floyd(sD, numThreads);
- listPrinter(sD, out);
- }
- void floydAlgList(const GraphList& graph, ostream& out, int numThreads = omp_get_max_threads())
- {
- GraphMatrix sD;
- int size = static_cast<int>(sz(graph));
- sD.resize(size);
- #pragma omp parallel for num_threads(numThreads)
- per(i, 1, size - 1)
- {
- sD[i].pb(0); // Заполняем нулевые элементы каждого ряда
- per(j, 1, size - 1)
- {
- sD[i].pb(finder(graph[i], j).S);
- }
- }
- _floyd(sD, numThreads);
- listPrinter(sD, out);
- }
- // Ввод данных и вызов методов
- void solve(int num_threads)
- {
- ifstream in("input.txt");
- if (!in.is_open()) throw exception("File input.txt wasn't open!");
- int n, m;
- in >> n >> m;
- GraphMatrix matrixGraph; // граф матрицей смежности
- GraphList listGraph; // граф списком смежности
- listGraph.resize(n + 1);
- matrixGraph.resize(n + 1);
- per(i, 1, n)
- matrixGraph[i].resize(n + 1, 0);
- per(i, 1, m)
- {
- int u, v, w;
- in >> u >> v >> w;
- matrixGraph[u][v] = matrixGraph[v][u] = (matrixGraph[u][v] == 0 ? w : min(w, matrixGraph[u][v]));
- listGraph[u].pb(mp(v, w));
- listGraph[v].pb(mp(u, w));
- }
- in.close();
- ofstream outMatrix("output.txt");
- Timer timer;
- floydAlgMatrix(matrixGraph, outMatrix, num_threads);
- timer.elapsed();
- cout << "Алгоритм по матрице завершил работу за " << timer.getLastElapsed() << " секунд" << endl;
- outMatrix.close();
- ofstream outList("output.txt");
- timer.reset();
- floydAlgList(listGraph, outList, num_threads);
- timer.elapsed();
- cout << "Алгоритм по листу завершил работу за " << timer.getLastElapsed() << " секунд" << endl;
- outList.close();
- }
- int main()
- {
- setlocale(LC_ALL, "ru");
- vector<int> numThreadsList = { 1 };
- for (int i = 2; i <= omp_get_max_threads(); i += 2) numThreadsList.push_back(i);
- for (auto& numThreads : numThreadsList)
- {
- cout << "************************************" << endl;
- cout << "Работа алгоритмов для [" << numThreads << "] потоков: " << endl << endl;
- solve(numThreads);
- cout << "************************************" << endl << endl;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement