DacCum

Графы

Dec 21st, 2021 (edited)
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.88 KB | None | 0 0
  1. /*
  2. 10 17
  3. 0 4 5 3 0 0 0 0 0 0
  4. 4 0 0 0 5 0 0 0 0 0
  5. 5 0 0 0 9 5 10 0 0 0
  6. 3 0 0 0 0 7 0 8 0 0
  7. 0 5 9 0 0 0 5 0 0 14
  8. 0 0 5 7 0 0 9 4 8 0
  9. 0 0 10 0 5 9 0 0 5 8
  10. 0 0 0 8 0 4 0 0 11 0
  11. 0 0 0 0 0 8 5 11 0 3
  12. 0 0 0 0 14 0 8 0 3 0
  13. */
  14. #include <iostream>
  15. #include <ctime> //библиотека функции clock()
  16. #include <fstream> //библиотека для работы с файлами
  17.  
  18. using namespace std;
  19.  
  20. unsigned long long compareOperations = 0, //подсчет операторов сравнения
  21. asignmentOperations = 0; //подсчет операторов присваивания
  22.  
  23. #define INF 9999999 //число бесконечности
  24. #define in_filename "input.txt" //названия файла входных данных
  25. #define _x 0 //индекс под которым храниться первая вершина ребра
  26. #define _y 1 //индекс под которым храниться вторая вершина ребра
  27. #define _w 2 //индекс под которым храниться вес ребра
  28.  
  29. //класс Графа
  30. class graph {
  31. private:
  32.     int** G; //таблиця смежности графа
  33.     int** T; //остовное дерево
  34.     int* parent; //массив кластеров
  35.     int V; //количество вершин
  36.     int U; //количество ребер
  37. public:
  38.     graph(string filename) {
  39.         //открываем файл с входными данными
  40.         ifstream in(filename);
  41.         if (in.is_open()) {
  42.             //если файл открыт, то вводим данные из него
  43.             in >> V;
  44.             in >> U;
  45.             G = new int* [V];
  46.             parent = new int[V];
  47.             for (int i = 0; i < V; i++) {
  48.                 G[i] = new int[V];
  49.                 parent[i] = i;
  50.                 for (int j = 0; j < V; j++)
  51.                     in >> G[i][j];
  52.             }
  53.         }
  54.         else {
  55.             //если файл не найден выводим соответственную ошибку
  56.             cout << "ERROR: file not found." << endl;
  57.             G = NULL;
  58.         }
  59.         T = new int* [V - 1];
  60.         for (int i = 0; i < V - 1; i++) {
  61.             T[i] = new int[3];
  62.         }
  63.     }
  64.     //фукнция создания представления графа
  65.     //в виде (вершина  вершина  вес)
  66.     int** setGk() {
  67.         int** Gk = new int* [U];
  68.         for (int i = 0; i < U; i++)
  69.             Gk[i] = new int[3];
  70.  
  71.         int k = 0;
  72.         for (int i = 0; i < V; i++) {
  73.             for (int j = i; j < V; j++) {
  74.                 if (G[i][j] != 0) {
  75.                     Gk[k][_w] = G[i][j];
  76.                     Gk[k][_x] = i;
  77.                     Gk[k][_y] = j;
  78.                     k++;
  79.                 }
  80.             }
  81.         }
  82.         return Gk;
  83.     }
  84.     int find_set(int i);
  85.     void union_set(int u, int v);
  86.     void kraskal();
  87.     void prima();
  88.     //функция записи остовного дерева в файл
  89.     void print() {
  90.         if (G == NULL)
  91.             //если дерево пустое, то завершаем выполнения функции
  92.             return;
  93.  
  94.         ofstream out_res("result.txt", ios::app);
  95.         out_res << "Edge :" << " Weight" << endl;
  96.         for (int i = 0; i < V - 1; i++)
  97.             out_res << T[i][_x] << " - " << T[i][_y] << " : " << T[i][_w] << endl;
  98.     }
  99. };
  100.  
  101. //функция сортирровки Gk типа записи графа в порядку возростания
  102. //методом бульбашки
  103. void sortGk(int** Gk, int U) {
  104.     for (int i = 1; i < U; i++) {
  105.         compareOperations++;
  106.         asignmentOperations++;
  107.         for (int j = 0; j < U - i; j++) {
  108.             asignmentOperations++;
  109.             compareOperations++;
  110.             if (Gk[j][_w] > Gk[j + 1][_w]) {
  111.                 compareOperations++;
  112.                 int* tmp = Gk[j];
  113.                 Gk[j] = Gk[j + 1];
  114.                 Gk[j + 1] = tmp;
  115.             }
  116.         }
  117.     }
  118. }
  119.  
  120. //функция нахождения нужных вершин
  121. int graph::find_set(int i) {
  122.     if (i == parent[i]) {
  123.         compareOperations++;
  124.         return i;
  125.     }
  126.     else
  127.         return find_set(parent[i]);
  128. }
  129.  
  130. //функция создания кластеров
  131. void graph::union_set(int u, int v) {
  132.     parent[u] = parent[v];
  133.     asignmentOperations++;
  134. }
  135.  
  136. //алгоритм Краскала
  137. void graph::kraskal() {
  138.     if (G == NULL)
  139.         //если граф пустой, то завершить выполнения функции
  140.         return;
  141.     //обнуляем счетчики операторов
  142.     compareOperations = 0, asignmentOperations = 0;
  143.  
  144.     int k = 0, uRep, vRep;
  145.     int** Gk = setGk();
  146.     //сортируем граф для дальнейшей работы с ним
  147.     sortGk(Gk, U);
  148.     for (int i = 0; i < U; i++) {
  149.         compareOperations++;
  150.         //ищем нужные вершини
  151.         uRep = find_set(Gk[i][_x]);
  152.         vRep = find_set(Gk[i][_y]);
  153.         asignmentOperations += 2;
  154.         if (uRep != vRep) {
  155.             //если не создается цикл,
  156.             //то добавляем ребро в остовное дерево
  157.             compareOperations++;
  158.             T[k][_x] = Gk[i][_x] + 1;
  159.             T[k][_y] = Gk[i][_y] + 1;
  160.             T[k][_w] = Gk[i][_w];
  161.             k++;
  162.             asignmentOperations += 4;
  163.             //добавляем в вершины кластер
  164.             union_set(uRep, vRep);
  165.         }
  166.     }
  167. }
  168.  
  169. //алгоритм Прима
  170. void graph::prima() {
  171.     if (G == NULL)
  172.         //если граф пустой, то завершить выполнения функции
  173.         return;
  174.     //обнуляем счетчики операторов
  175.     compareOperations = 0, asignmentOperations = 0;
  176.     //массив для запоминания какие вершини мы уже прошли
  177.     bool* selected = new bool[V]();
  178.  
  179.     int no_edge = 0; //подсчет найденых ребер
  180.     selected[0] = true;
  181.     asignmentOperations += 2;
  182.     while (no_edge < V - 1) {
  183.         /*
  184.         Для каждой вершины в множестве S найти все смежные вершины
  185.         вычисляем расстояние от вершины, выбранной на шаге 1.
  186.         если вершина уже находится в множестве S, отбрасываем в противном случае
  187.         выбираем другую вершину, ближайшую к выбранной вершине на шаге 1.
  188.         */
  189.         compareOperations++;
  190.         int min = INF;
  191.         int x = 0;
  192.         int y = 0;
  193.         asignmentOperations += 3;
  194.  
  195.         for (int i = 0; i < V; i++) {
  196.             asignmentOperations++;
  197.             compareOperations++;
  198.             if (selected[i]) {
  199.                 compareOperations++;
  200.                 for (int j = 0; j < V; j++) {
  201.                     compareOperations++;
  202.                     if (!selected[j] && G[i][j]) {
  203.                         compareOperations += 2;
  204.                         if (min > G[i][j]) {
  205.                             compareOperations++;
  206.                             min = G[i][j];
  207.                             x = i;
  208.                             y = j;
  209.                             asignmentOperations += 3;
  210.                         }
  211.                     }
  212.                 }
  213.             }
  214.         }
  215.  
  216.         T[no_edge][_x] = x + 1;
  217.         T[no_edge][_y] = y + 1;
  218.         T[no_edge][_w] = min;
  219.         selected[y] = true;
  220.         no_edge++;
  221.         asignmentOperations += 5;
  222.     }
  223. }
  224.  
  225. int main() {
  226.     graph g(in_filename);
  227.     ofstream out_res;
  228.     out_res.open("result.txt");
  229.     out_res << "algorithm Kraskala: " << endl;
  230.     out_res.close();
  231.     unsigned long long Time = clock();
  232.     g.kraskal();
  233.     Time = clock() - Time;
  234.     g.print();
  235.     ofstream out_log;
  236.     out_log.open("report.txt");
  237.     out_log << "algorithm Kraskala: " << endl;
  238.     out_log << "time: " << Time << "ms" << endl;
  239.     out_log << "asignment operations: " << asignmentOperations << endl;
  240.     out_log << "compare operations: " << compareOperations << endl;
  241.     out_log.close();
  242.  
  243.     out_res.open("result.txt", ios::app);
  244.     out_res << endl << "algorithm Prima: " << endl;
  245.     out_res.close();
  246.     Time = clock();
  247.     g.prima();
  248.     Time = clock() - Time;
  249.     g.print();
  250.     out_log.open("report.txt", ios::app);
  251.     out_log << endl << "algorithm Prima: " << endl;
  252.     out_log << "time: " << Time << "ms" << endl;
  253.     out_log << "asignment operations: " << asignmentOperations << endl;
  254.     out_log << "compare operations: " << compareOperations << endl;
  255.     out_log.close();
  256.  
  257.     cout << "Complite! Open your file`s with result and report" << endl;
  258.     return 0;
  259. }
  260.  
Add Comment
Please, Sign In to add comment