stas224

Алгоритм Борувки

Dec 28th, 2021 (edited)
31
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.78 KB | None | 0 0
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. struct Edge// структура для представления взвешенного ребра в графе
  6. {
  7. int src;
  8. int dest;
  9. int weight;
  10. };
  11. struct Graph // структура для представления подключенной, ненаправленной и взвешенный граф как набор ребер.
  12. {
  13. int V;// V->Количество вершин,
  14. int E;// E->Количество ребер
  15. Edge* edge;
  16. };
  17. struct subset // Структура для представления подмножества для union-find
  18. {
  19. int parent;
  20. int rank;
  21. };
  22. // Прототипы функций для union-find (Эти функции определены после борувкаМСТ ())
  23. int find(struct subset subsets[], int i);
  24. void Union(struct subset subsets[], int x, int y);
  25. void boruvkaMST(struct Graph* graph)// Основная функция для MST с использованием алгоритма Борувки
  26. {
  27. int V = graph->V, E = graph->E; Edge* edge = graph->edge;// Получить данные данного графика
  28. struct subset* subsets = new subset[V];// Выделить память для создания V подмножеств.
  29. int* cheapest = new int[V];// Массив для хранения индекса самого дешевого края
  30. //подмножество. Сохраненный индекс для индексации массива 'edge []'
  31. for (int v = 0; v < V; ++v) // Создать V подмножеств с отдельными элементами
  32. {
  33. subsets[v].parent = v;
  34. subsets[v].rank = 0;
  35. cheapest[v] = -1;
  36. }
  37. // Изначально существует V разных деревьев. Наконец, будет одно дерево, которое будет MST
  38. int numTrees = V;
  39. int MSTweight = 0;
  40. // Продолжаем комбинировать компоненты (или наборы), пока все Компоненты не объединяются в один MST.
  41. while (numTrees > 1)
  42. {
  43. for (int v = 0; v < V; ++v)// Каждый раз инициализируем самый дешевый массив
  44. cheapest[v] = -1;
  45. for (int i = 0; i < E; i++)// Пройдите через все ребра и обновите самый дешевый из каждого компонента
  46. {
  47. // Найти компоненты (или наборы) двух углов текущего края
  48. int set1 = find(subsets, edge[i].src);
  49. int set2 = find(subsets, edge[i].dest);
  50. if (set1 == set2) // Если два угла текущего ребра принадлежат тот же набор, игнорировать текущее ребро
  51. continue;
  52. // Иначе проверяем, находится ли текущий фронт ближе к предыдущему
  53. // самые дешевые ребра set1 и set2
  54. else
  55. {
  56. if (cheapest[set1] == -1 || edge[cheapest[set1]].weight > edge[i].weight)
  57. cheapest[set1] = i;
  58. if (cheapest[set2] == -1 ||edge[cheapest[set2]].weight > edge[i].weight)
  59. cheapest[set2] = i;
  60. }
  61. }
  62. for (int i = 0; i < V; i++)// Рассмотрим выбранные выше самые дешевые ребра и добавим их в MST
  63. {
  64. if (cheapest[i] != -1)// Проверяем, существует ли самый дешевый для текущего набора
  65. {
  66. int set1 = find(subsets, edge[cheapest[i]].src);
  67. int set2 = find(subsets, edge[cheapest[i]].dest);
  68. if (set1 == set2)
  69. continue;
  70. MSTweight += edge[cheapest[i]].weight;
  71. printf("Edge %d-%d included in MST\n",
  72. edge[cheapest[i]].src, edge[cheapest[i]].dest);
  73. Union(subsets, set1, set2);// Делаем объединение set1 и set2 и уменьшаем число деревьев
  74. numTrees--;
  75. }
  76. }
  77. }
  78. printf("Weight of MST is %d\n", MSTweight);
  79. return;
  80. }
  81. struct Graph* createGraph(int V, int E) // Создаем граф с V вершинами и E ребрами
  82. {
  83. Graph* graph = new Graph;
  84. graph->V = V;
  85. graph->E = E;
  86. graph->edge = new Edge[E];
  87. return graph;
  88. }
  89. int find(struct subset subsets[], int i) // Полезная функция для поиска множества элементов i (использует технику сжатия пути)
  90. {
  91. if (subsets[i].parent != i) // найти root и сделать root родителем i (сжатие пути)
  92. subsets[i].parent = find(subsets, subsets[i].parent);
  93. return subsets[i].parent;
  94. }
  95. void Union(struct subset subsets[], int x, int y) // Функция, которая объединяет два набора x и y (использует объединение по рангу)
  96. {
  97. int xroot = find(subsets, x);
  98. int yroot = find(subsets, y);
  99. // Прикрепить дерево меньшего ранга под корень высокого ранговое дерево (объединение по рангу)
  100. if (subsets[xroot].rank < subsets[yroot].rank)
  101. subsets[xroot].parent = yroot;
  102. else if (subsets[xroot].rank > subsets[yroot].rank)
  103. subsets[yroot].parent = xroot;
  104. else// Если ранги одинаковы, то создайте их как root и увеличиваем ранг на единицу
  105. {
  106. subsets[yroot].parent = xroot;
  107. subsets[xroot].rank++;
  108. }
  109. }
  110. // Программа драйвера для проверки вышеуказанных функций
  111. int main()
  112. {
  113. int V = 4; // Количество вершин в графе
  114. int E = 5; // Количество ребер в графе
  115. struct Graph* graph = createGraph(V, E);
  116. graph->edge[0].src = 0; graph->edge[0].dest = 1; graph->edge[0].weight = 10;// добавляем ребро 0-1
  117. graph->edge[1].src = 0; graph->edge[1].dest = 2; graph->edge[1].weight = 6;// добавляем ребро 0-2
  118. graph->edge[2].src = 0; graph->edge[2].dest = 3; graph->edge[2].weight = 5;// добавляем ребро 0-3
  119. graph->edge[3].src = 1;graph->edge[3].dest = 3;graph->edge[3].weight = 15;// добавить ребро 1-3
  120. graph->edge[4].src = 2;graph->edge[4].dest = 3;graph->edge[4].weight = 100;// добавить ребро 2-3
  121.  
  122. boruvkaMST(graph);
  123.  
  124. return 0;
  125. }
Add Comment
Please, Sign In to add comment