TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
boruvkas_minimum_spanning_tree.cpp File Reference

[Borůvkas Algorithm](https://en.wikipedia.org/wiki/Borůvka's_algorithm) to find the Minimum Spanning Tree More...

#include <cassert>
#include <climits>
#include <iostream>
#include <vector>
Include dependency graph for boruvkas_minimum_spanning_tree.cpp:

Go to the source code of this file.

Namespaces

namespace  greedy_algorithms
 for string class
 
namespace  boruvkas_minimum_spanning_tree
 Functions for the [Borůvkas Algorithm](https://en.wikipedia.org/wiki/Borůvka's_algorithm) implementation.
 

Functions

int greedy_algorithms::boruvkas_minimum_spanning_tree::findParent (std::vector< std::pair< int, int > > parent, const int v)
 Recursively returns the vertex's parent at the root of the tree.
 
std::vector< std::vector< int > > greedy_algorithms::boruvkas_minimum_spanning_tree::boruvkas (std::vector< std::vector< int > > adj)
 the implementation of boruvka's algorithm
 
int greedy_algorithms::boruvkas_minimum_spanning_tree::test_findGraphSum (std::vector< std::vector< int > > adj)
 counts the sum of edges in the given tree
 
static void tests ()
 Self-test implementations.
 
int main ()
 Main function.
 

Detailed Description

[Borůvkas Algorithm](https://en.wikipedia.org/wiki/Borůvka's_algorithm) to find the Minimum Spanning Tree

Author
Jason Nardoni

Boruvka's algorithm is a greepy algorithm to find the MST by starting with small trees, and combining them to build bigger ones.

  1. Creates a group for every vertex.
  2. looks through each edge of every vertex for the smallest weight. Keeps track of the smallest edge for each of the current groups.

Combine each group with the group it shares its smallest edge, adding the smallest edge to the MST.

  1. Repeat step 2-3 until all vertices are combined into a single group.

It assumes that the graph is connected. Non-connected edges can be represented using 0 or INT_MAX

Definition in file boruvkas_minimum_spanning_tree.cpp.

Function Documentation

◆ boruvkas()

std::vector< std::vector< int > > greedy_algorithms::boruvkas_minimum_spanning_tree::boruvkas ( std::vector< std::vector< int > > adj)

the implementation of boruvka's algorithm

Parameters
adja graph adjancency matrix stored as 2d vectors.
Returns
the MST as 2d vectors

Definition at line 60 of file boruvkas_minimum_spanning_tree.cpp.

60 {
61 size_t size = adj.size();
62 size_t total_groups = size;
63
64 if (size <= 1) {
65 return adj;
66 }
67
68 // Stores the current Minimum Spanning Tree. As groups are combined, they
69 // are added to the MST
70 std::vector<std::vector<int>> MST(size, std::vector<int>(size, INT_MAX));
71 for (int i = 0; i < size; i++) {
72 MST[i][i] = 0;
73 }
74
75 // Step 1: Create a group for each vertex
76
77 // Stores the parent of the vertex and its current depth, both initialized
78 // to 0
79 std::vector<std::pair<int, int>> parent(size, std::make_pair(0, 0));
80
81 for (int i = 0; i < size; i++) {
82 parent[i].first =
83 i; // Sets parent of each vertex to itself, depth remains 0
84 }
85
86 // Repeat until all are in a single group
87 while (total_groups > 1) {
88 std::vector<std::pair<int, int>> smallest_edge(
89 size, std::make_pair(-1, -1)); // Pairing: start node, end node
90
91 // Step 2: Look throught each vertex for its smallest edge, only using
92 // the right half of the adj matrix
93 for (int i = 0; i < size; i++) {
94 for (int j = i + 1; j < size; j++) {
95 if (adj[i][j] == INT_MAX || adj[i][j] == 0) { // No connection
96 continue;
97 }
98
99 // Finds the parents of the start and end points to make sure
100 // they arent in the same group
101 int parentA = findParent(parent, i);
102 int parentB = findParent(parent, j);
103
104 if (parentA != parentB) {
105 // Grabs the start and end points for the first groups
106 // current smallest edge
107 int start = smallest_edge[parentA].first;
108 int end = smallest_edge[parentA].second;
109
110 // If there is no current smallest edge, or the new edge is
111 // smaller, records the new smallest
112 if (start == -1 || adj[i][j] < adj[start][end]) {
113 smallest_edge[parentA].first = i;
114 smallest_edge[parentA].second = j;
115 }
116
117 // Does the same for the second group
118 start = smallest_edge[parentB].first;
119 end = smallest_edge[parentB].second;
120
121 if (start == -1 || adj[j][i] < adj[start][end]) {
122 smallest_edge[parentB].first = j;
123 smallest_edge[parentB].second = i;
124 }
125 }
126 }
127 }
128
129 // Step 3: Combine the groups based off their smallest edge
130
131 for (int i = 0; i < size; i++) {
132 // Makes sure the smallest edge exists
133 if (smallest_edge[i].first != -1) {
134 // Start and end points for the groups smallest edge
135 int start = smallest_edge[i].first;
136 int end = smallest_edge[i].second;
137
138 // Parents of the two groups - A is always itself
139 int parentA = i;
140 int parentB = findParent(parent, end);
141
142 // Makes sure the two nodes dont share the same parent. Would
143 // happen if the two groups have been
144 // merged previously through a common shortest edge
145 if (parentA == parentB) {
146 continue;
147 }
148
149 // Tries to balance the trees as much as possible as they are
150 // merged. The parent of the shallower
151 // tree will be pointed to the parent of the deeper tree.
152 if (parent[parentA].second < parent[parentB].second) {
153 parent[parentB].first = parentA; // New parent
154 parent[parentB].second++; // Increase depth
155 } else {
156 parent[parentA].first = parentB;
157 parent[parentA].second++;
158 }
159 // Add the connection to the MST, using both halves of the adj
160 // matrix
161 MST[start][end] = adj[start][end];
162 MST[end][start] = adj[end][start];
163 total_groups--; // one fewer group
164 }
165 }
166 }
167 return MST;
168}
int findParent(std::vector< std::pair< int, int > > parent, const int v)
Recursively returns the vertex's parent at the root of the tree.

◆ findParent()

int greedy_algorithms::boruvkas_minimum_spanning_tree::findParent ( std::vector< std::pair< int, int > > parent,
const int v )

Recursively returns the vertex's parent at the root of the tree.

Parameters
parentthe array that will be checked
vvertex to find parent of
Returns
the parent of the vertex

Definition at line 47 of file boruvkas_minimum_spanning_tree.cpp.

47 {
48 if (parent[v].first != v) {
49 parent[v].first = findParent(parent, parent[v].first);
50 }
51
52 return parent[v].first;
53}

◆ main()

int main ( void )

Main function.

Returns
0 on exit

Definition at line 224 of file boruvkas_minimum_spanning_tree.cpp.

224 {
225 tests(); // run self-test implementations
226 return 0;
227}
static void tests()
Self-test implementations.

◆ test_findGraphSum()

int greedy_algorithms::boruvkas_minimum_spanning_tree::test_findGraphSum ( std::vector< std::vector< int > > adj)

counts the sum of edges in the given tree

Parameters
adj2D vector adjacency matrix
Returns
the int size of the tree

Definition at line 175 of file boruvkas_minimum_spanning_tree.cpp.

175 {
176 size_t size = adj.size();
177 int sum = 0;
178
179 // Moves through one side of the adj matrix, counting the sums of each edge
180 for (int i = 0; i < size; i++) {
181 for (int j = i + 1; j < size; j++) {
182 if (adj[i][j] < INT_MAX) {
183 sum += adj[i][j];
184 }
185 }
186 }
187 return sum;
188}
T sum(const std::vector< std::valarray< T > > &A)

◆ tests()

static void tests ( )
static

Self-test implementations.

Returns
void

Definition at line 196 of file boruvkas_minimum_spanning_tree.cpp.

196 {
197 std::cout << "Starting tests...\n\n";
198 std::vector<std::vector<int>> graph = {
199 {0, 5, INT_MAX, 3, INT_MAX}, {5, 0, 2, INT_MAX, 5},
200 {INT_MAX, 2, 0, INT_MAX, 3}, {3, INT_MAX, INT_MAX, 0, INT_MAX},
201 {INT_MAX, 5, 3, INT_MAX, 0},
202 };
203 std::vector<std::vector<int>> MST =
205 assert(greedy_algorithms::boruvkas_minimum_spanning_tree::test_findGraphSum(
206 MST) == 13);
207 std::cout << "1st test passed!" << std::endl;
208
209 graph = {{0, 2, 0, 6, 0},
210 {2, 0, 3, 8, 5},
211 {0, 3, 0, 0, 7},
212 {6, 8, 0, 0, 9},
213 {0, 5, 7, 9, 0}};
215 assert(greedy_algorithms::boruvkas_minimum_spanning_tree::test_findGraphSum(
216 MST) == 16);
217 std::cout << "2nd test passed!" << std::endl;
218}
std::vector< std::vector< int > > boruvkas(std::vector< std::vector< int > > adj)
the implementation of boruvka's algorithm
Graph Algorithms.