Advertisement
Vladislav_Bezruk

Kruskal and Prima algorithms

Nov 17th, 2021
1,056
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.14 KB | None | 0 0
  1. #include <iostream>
  2. #include <time.h>
  3.  
  4. //кількість вершин
  5. #define N 10
  6.  
  7. using namespace std;
  8.  
  9. //операції присвоювання, порівняння
  10. int assignCount, compCount;
  11.  
  12. //час виконання
  13. clock_t sTime, eTime;
  14.  
  15. //граф
  16. class Graph {
  17.     public:
  18.         //кількість ребер
  19.         int n;
  20.        
  21.         //матриця інцидентності    
  22.         int** c;
  23.    
  24.     public:
  25.         Graph(int n) {
  26.             c = new int* [n];
  27.            
  28.             for (int i = 0; i < n; i++) {
  29.                 c[i] = new int[n];
  30.                
  31.                 for (int j = 0; j < n; j++) {
  32.                     c[i][j] = -1;
  33.                 }
  34.             }
  35.            
  36.             this->n = n;
  37.         }
  38.        
  39.         //функція читання графа
  40.         void set() {
  41.             cout << "Enter graph:" << endl;
  42.            
  43.             for (int i = 0; i < n; i++) {
  44.                 for (int j = 0; j < n; j++) {
  45.                     cin >> c[i][j];
  46.                 }
  47.             }
  48.         }
  49.        
  50.         //функція друкування графа
  51.         void print() {
  52.             cout << "   ";
  53.             for (int i = 0; i < n; i++) {
  54.                 cout << i + 1 << " ";
  55.             }
  56.             cout << endl << "--";
  57.             for (int i = 0; i < n; i++) {
  58.                 cout << "--";
  59.             }
  60.             cout << endl;
  61.             for (int i = 0; i < n; i++) {
  62.                 cout << i + 1 << ": ";
  63.                 for (int j = 0; j < n; j++) {
  64.                     if (c[i][j] > 0) {
  65.                         cout << c[i][j] << " ";
  66.                     } else {
  67.                         cout << "  ";
  68.                     }
  69.                 }
  70.                 cout << endl;
  71.             }
  72.             cout << endl;
  73.         }
  74.  
  75.         friend Graph kruskalAlgo(Graph g, int& sum);
  76.        
  77.         friend int** getCArr(Graph &g, int &k);
  78.        
  79.         friend bool checkLoop(Graph &g, int u, int v, bool t[]);
  80.        
  81.         friend Graph primAlgo(Graph g, int &sum);
  82. };
  83.  
  84. //функція для отримування масиву усіх ребер
  85. int** getCArr(Graph &g, int &k) {
  86.     k = 0;
  87.     int n = g.n * (g.n - 1);
  88.     int** cArr = new int* [n];
  89.    
  90.     for (int i = 0; i < n; i++) {
  91.         cArr[i] = new int[3];
  92.     }
  93.    
  94.     for (int i = 0; i < g.n; i++) {
  95.         for (int j = 0; j < g.n; j++) {
  96.             compCount++;
  97.             if (g.c[i][j] > 0) {
  98.                
  99.                 cArr[k][0] = i;
  100.                 cArr[k][1] = j;
  101.                 cArr[k][2] = g.c[i][j];
  102.                
  103.                 assignCount += 3;
  104.                
  105.                 k++;
  106.             }
  107.         }
  108.     }
  109.     return cArr;
  110. }
  111.  
  112. //функці для сортування масиву усіх ребер у порядку зростання
  113. void sortCArr(int** &cArr, int k) {
  114.     for (int i = 1, j = i; i < k; i++, j = i) {
  115.         while (j > 0 && cArr[j][2] < cArr[j - 1][2]) {
  116.             compCount++;
  117.             for (int k = 0; k < 3; k++) {
  118.                 swap(cArr[j][k], cArr[j - 1][k]);
  119.             }
  120.             assignCount += 3;    
  121.             j--;
  122.         }  
  123.     }
  124. }
  125.  
  126. //функція для перевірки того чи вершини u та v з'єднані
  127. bool checkLoop(Graph &g, int u, int v, bool t[]) {
  128.     if (t[u]) return false;
  129.     if (u == v) return true;
  130.    
  131.     t[u] = true;
  132.     assignCount++;
  133.    
  134.     for (int i = 0; i < g.n; i++) {
  135.         if (g.c[u][i] > 0) {
  136.             if (checkLoop(g, i, v, t) == true) {
  137.                 return true;
  138.             }
  139.         }
  140.     }
  141.    
  142.     t[u] = false;
  143.    
  144.     return false;
  145. }
  146.  
  147. //алгоритм Крускала
  148. Graph kruskalAlgo(Graph g, int &sum) {
  149.     Graph r(g.n);
  150.     sum = 0;
  151.     int k = 0, **cArr = getCArr(g, k);
  152.    
  153.     //отримуємо відсортований масив ребер по зростанню
  154.     sortCArr(cArr, k);
  155.    
  156.     for (int i = 0, n = 0; i < k && n < r.n - 1; i++) {
  157.         bool t[g.n] = { false };
  158.        
  159.         int u = cArr[i][0];
  160.         int v = cArr[i][1];
  161.            
  162.         //якщо вставка мінімального ребра не утворить петлю то вставляємо ребро у граф
  163.         if (checkLoop(r, u, v, t) == false) {
  164.             r.c[u][v] = r.c[v][u] = cArr[i][2];
  165.             n++;
  166.             sum += cArr[i][2];
  167.             assignCount += 2;
  168.         }
  169.     }
  170.     return r;
  171. }
  172.  
  173. //алгоритм Прима
  174. Graph primAlgo(Graph g, int &sum) {
  175.     Graph r(g.n);
  176.     sum = 0;
  177.     int k = 0, **cArr = getCArr(g, k);
  178.     bool c[g.n] = { false };
  179.    
  180.     c[0] = true;
  181.     //отримуємо відсортований масив ребер по зростанню
  182.     sortCArr(cArr, k);
  183.    
  184.     for (int j = 0; j < r.n - 1; j++) {
  185.         for (int i = 0; i < k; i++) {
  186.             int u = cArr[i][0];
  187.             int v = cArr[i][1];
  188.            
  189.             compCount += 2;
  190.            
  191.             //шукаємо манімальне ребро між вершиною у матриці С та вершиною якої немає у матриці С
  192.             //та вставляємо це ребро у граф
  193.             if (c[u] && not c[v]) {    
  194.                 r.c[u][v] = r.c[v][u] = cArr[i][2];
  195.                 sum += cArr[i][2];
  196.                 c[v] = true;
  197.                 assignCount += 2;
  198.                 break;
  199.             }
  200.         }
  201.     }
  202.     return r;
  203. }
  204.  
  205. int main() {
  206.     int sum;
  207.     Graph g(N);
  208.    
  209.     g.set();
  210.    
  211.     cout << endl << "Kruskal result:" << endl;
  212.     assignCount = compCount = 0;
  213.     sTime = clock();
  214.     kruskalAlgo(g, sum).print();
  215.     eTime = clock();
  216.    
  217.     cout << "assignment operations = " << assignCount << endl;
  218.     cout << "comparison operations = " << compCount << endl;
  219.     cout << "time = " << int(eTime - sTime) << endl;
  220.     cout << "sum = " << sum << endl;
  221.    
  222.     cout << endl << "Prima result:" << endl;
  223.     assignCount = compCount = 0;
  224.     sTime = clock();
  225.     primAlgo(g, sum).print();
  226.     eTime = clock();
  227.    
  228.     cout << "assignment operations = " << assignCount << endl;
  229.     cout << "comparison operations = " << compCount << endl;
  230.     cout << "time = " << int(eTime - sTime) << endl;
  231.     cout << "sum = " << sum << endl;
  232.    
  233.     return 0;
  234. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement