From 8d67fd57c000b725df74a87d96b642ec86185690 Mon Sep 17 00:00:00 2001 From: P Shiva Rama Krishna Date: Sat, 21 Aug 2021 18:11:37 +0530 Subject: [PATCH 01/14] =?UTF-8?q?Added=20Bor=C5=AFvka's=20algorithm.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- graphs/boruvka.py | 187 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 graphs/boruvka.py diff --git a/graphs/boruvka.py b/graphs/boruvka.py new file mode 100644 index 000000000000..fe6f47735eb5 --- /dev/null +++ b/graphs/boruvka.py @@ -0,0 +1,187 @@ +"""Borůvka's algorithm. + + Determines the minimum spanning tree(MST) of a graph using the Borůvka's algorithm. + Borůvka's algorithm is a greedy algorithm for finding a minimum spanning tree in a graph, + or a minimum spanning forest in the case of a graph that is not connected. + + The time complexity of this algorithm is O(ElogV), where E represents the number of edges, + while V represents the number of nodes. + + The space complexity of this algorithm is O(V + E), since we have to keep a couple of lists whose sizes are equal + to the number of nodes, as well as keep all the edges of a graph inside of the data structure itself. + + Borůvka's algorithm gives us pretty much the same result as other MST Algorithms - they all find the minimum spanning + tree, and the time complexity is approximately the same. + + One advantage that Borůvka's algorithm has compared to the alternatives is that it doesn't + need to presort the edges or maintain a priority queue in order to find the minimum spanning tree. + Even though that doesn't help its complexity, since it still passes the edges logE times, + it is a bit more simple to code. + + Details: https://en.wikipedia.org/wiki/Bor%C5%AFvka%27s_algorithm +""" + + +class Graph: + """Class Graph.""" + def __init__(self, num_of_nodes): + """ + Arguments: + num_of_nodes - the number of nodes in the graph + Attributes: + m_v - the number of nodes in the graph. + m_edges - the list of edges. + m_component - the dictionary which stores the index of the component which a node belongs to. + """ + + self.m_v = num_of_nodes + self.m_edges = [] + self.m_component = {} + + def add_edge(self, u, v, weight): + """Adds an edge in the format [first, second, edge weight] to graph.""" + + self.m_edges.append([u, v, weight]) + + def find_component(self, u): + """Propagates a new component throughout a given component.""" + + if self.m_component[u] == u: + return u + return self.find_component(self.m_component[u]) + + def set_component(self, u): + """Finds the component index of a given node""" + + if self.m_component[u] == u: + return + else: + for k in self.m_component.keys(): + self.m_component[k] = self.find_component(k) + + def union(self, component_size, u, v): + """Union finds the roots of components for two nodes, compares the components in terms of size, + and attaches the smaller one to the larger one to form single component """ + + if component_size[u] <= component_size[v]: + self.m_component[u] = v + component_size[v] += component_size[u] + self.set_component(u) + + elif component_size[u] >= component_size[v]: + self.m_component[v] = self.find_component(u) + component_size[u] += component_size[v] + self.set_component(v) + + print(self.m_component) + + def boruvka(self): + """Performs Borůvka's algorithm to find MST.""" + + #Initialize additional lists required to algorithm. + component_size = [] + mst_weight = 0 + + minimum_weight_edge = [-1] * self.m_v + + #A list of components (initialized to all of the nodes) + for node in range(self.m_v): + self.m_component.update({node: node}) + component_size.append(1) + + num_of_components = self.m_v + + while num_of_components > 1: + for i in range(len(self.m_edges)): + + u = self.m_edges[i][0] + v = self.m_edges[i][1] + w = self.m_edges[i][2] + + u_component = self.m_component[u] + v_component = self.m_component[v] + + if u_component != v_component: + """If the current minimum weight edge of component u doesn't exist (is -1), or if + it's greater than the edge we're observing right now, we will assign the value + of the edge we're observing to it. + + If the current minimum weight edge of component v doesn't exist (is -1), or if + it's greater than the edge we're observing right now, we will assign the value + of the edge we're observing to it""" + + if minimum_weight_edge[u_component] == -1 or minimum_weight_edge[u_component][2] > w: + minimum_weight_edge[u_component] = [u, v, w] + if minimum_weight_edge[v_component] == -1 or minimum_weight_edge[v_component][2] > w: + minimum_weight_edge[v_component] = [u, v, w] + + for node in range(self.m_v): + if minimum_weight_edge[node] != -1: + u = minimum_weight_edge[node][0] + v = minimum_weight_edge[node][1] + w = minimum_weight_edge[node][2] + + u_component = self.m_component[u] + v_component = self.m_component[v] + + if u_component != v_component: + mst_weight += w + self.union(component_size, u_component, v_component) + print("Added edge [" + str(u) + " - " + + str(v) + "]\n" + + "Added weight: " + str(w) + "\n") + num_of_components -= 1 + + minimum_weight_edge = [-1] * self.m_v + print("The total weight of the minimal spanning tree is: " + str(mst_weight)) + +def test_vector() -> None: + """ + >>>g=Graph(8) + >>>g.add_edge(0, 1, 10) + >>>g.add_edge(0, 2, 6) + >>>g.add_edge(0, 3, 5) + >>>g.add_edge(1, 3, 15) + >>>g.add_edge(2, 3, 4) + >>>g.add_edge(3, 4, 8) + >>>g.add_edge(4, 5, 10) + >>>g.add_edge(4, 6, 6) + >>>g.add_edge(4, 7, 5) + >>>g.add_edge(5, 7, 15) + >>>g.add_edge(5, 7, 4) + >>>g.boruvka() + {0: 3, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7} + Added edge [0 - 3] + Added weight: 5 + + {0: 3, 1: 3, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7} + Added edge [0 - 1] + Added weight: 10 + + {0: 3, 1: 3, 2: 3, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7} + Added edge [2 - 3] + Added weight: 4 + + {0: 3, 1: 3, 2: 3, 3: 3, 4: 7, 5: 5, 6: 6, 7: 7} + Added edge [4 - 7] + Added weight: 5 + + {0: 3, 1: 3, 2: 3, 3: 3, 4: 7, 5: 7, 6: 6, 7: 7} + Added edge [5 - 7] + Added weight: 4 + + {0: 3, 1: 3, 2: 3, 3: 3, 4: 7, 5: 7, 6: 7, 7: 7} + Added edge [4 - 6] + Added weight: 6 + + {0: 7, 1: 7, 2: 7, 3: 7, 4: 7, 5: 7, 6: 7, 7: 7} + Added edge [3 - 4] + Added weight: 8 + + The total weight of the minimal spanning tree is: 42 + """ + +if __name__ == "__main__": + import doctest + + doctest.testmod() From 93e229873486dfe24b0a64404dd2e4d5530fae40 Mon Sep 17 00:00:00 2001 From: P Shiva Rama Krishna Date: Sat, 21 Aug 2021 18:28:15 +0530 Subject: [PATCH 02/14] =?UTF-8?q?Added=20Bor=C5=AFvka's=20algorithm,=20a?= =?UTF-8?q?=20graph=20algorithm=20that=20finds=20the=20minimum=20spanning?= =?UTF-8?q?=20tree.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- graphs/boruvka.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/graphs/boruvka.py b/graphs/boruvka.py index fe6f47735eb5..6e6e2906404d 100644 --- a/graphs/boruvka.py +++ b/graphs/boruvka.py @@ -24,7 +24,8 @@ class Graph: """Class Graph.""" - def __init__(self, num_of_nodes): + + def __init__(self, num_of_nodes) -> None: """ Arguments: num_of_nodes - the number of nodes in the graph @@ -38,19 +39,19 @@ def __init__(self, num_of_nodes): self.m_edges = [] self.m_component = {} - def add_edge(self, u, v, weight): + def add_edge(self, u, v, weight) -> None: """Adds an edge in the format [first, second, edge weight] to graph.""" self.m_edges.append([u, v, weight]) - def find_component(self, u): + def find_component(self, u) -> int: """Propagates a new component throughout a given component.""" if self.m_component[u] == u: return u return self.find_component(self.m_component[u]) - def set_component(self, u): + def set_component(self, u) -> None: """Finds the component index of a given node""" if self.m_component[u] == u: @@ -59,7 +60,7 @@ def set_component(self, u): for k in self.m_component.keys(): self.m_component[k] = self.find_component(k) - def union(self, component_size, u, v): + def union(self, component_size, u, v) -> None: """Union finds the roots of components for two nodes, compares the components in terms of size, and attaches the smaller one to the larger one to form single component """ @@ -75,16 +76,16 @@ def union(self, component_size, u, v): print(self.m_component) - def boruvka(self): + def boruvka(self) -> None: """Performs Borůvka's algorithm to find MST.""" - - #Initialize additional lists required to algorithm. + + # Initialize additional lists required to algorithm. component_size = [] mst_weight = 0 minimum_weight_edge = [-1] * self.m_v - - #A list of components (initialized to all of the nodes) + + # A list of components (initialized to all of the nodes) for node in range(self.m_v): self.m_component.update({node: node}) component_size.append(1) @@ -109,7 +110,7 @@ def boruvka(self): If the current minimum weight edge of component v doesn't exist (is -1), or if it's greater than the edge we're observing right now, we will assign the value of the edge we're observing to it""" - + if minimum_weight_edge[u_component] == -1 or minimum_weight_edge[u_component][2] > w: minimum_weight_edge[u_component] = [u, v, w] if minimum_weight_edge[v_component] == -1 or minimum_weight_edge[v_component][2] > w: @@ -135,6 +136,7 @@ def boruvka(self): minimum_weight_edge = [-1] * self.m_v print("The total weight of the minimal spanning tree is: " + str(mst_weight)) + def test_vector() -> None: """ >>>g=Graph(8) @@ -181,6 +183,7 @@ def test_vector() -> None: The total weight of the minimal spanning tree is: 42 """ + if __name__ == "__main__": import doctest From 89cf0a434a44c6410764c7e9703d39e730453bf0 Mon Sep 17 00:00:00 2001 From: P Shiva Rama Krishna Date: Sat, 21 Aug 2021 18:34:11 +0530 Subject: [PATCH 03/14] =?UTF-8?q?Added=20Bor=C5=AFvka's=20algorithm,=20a?= =?UTF-8?q?=20graph=20algorithm=20that=20finds=20the=20minimum=20spanning?= =?UTF-8?q?=20tree.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- graphs/boruvka.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/graphs/boruvka.py b/graphs/boruvka.py index 6e6e2906404d..000c398b32f5 100644 --- a/graphs/boruvka.py +++ b/graphs/boruvka.py @@ -25,7 +25,7 @@ class Graph: """Class Graph.""" - def __init__(self, num_of_nodes) -> None: + def __init__(self, num_of_nodes: int) -> None: """ Arguments: num_of_nodes - the number of nodes in the graph @@ -39,19 +39,19 @@ def __init__(self, num_of_nodes) -> None: self.m_edges = [] self.m_component = {} - def add_edge(self, u, v, weight) -> None: + def add_edge(self, u: int, v: int, weight: int) -> None: """Adds an edge in the format [first, second, edge weight] to graph.""" self.m_edges.append([u, v, weight]) - def find_component(self, u) -> int: + def find_component(self, u: int) -> int: """Propagates a new component throughout a given component.""" if self.m_component[u] == u: return u return self.find_component(self.m_component[u]) - def set_component(self, u) -> None: + def set_component(self, u: int) -> None: """Finds the component index of a given node""" if self.m_component[u] == u: @@ -60,7 +60,7 @@ def set_component(self, u) -> None: for k in self.m_component.keys(): self.m_component[k] = self.find_component(k) - def union(self, component_size, u, v) -> None: + def union(self, component_size: list, u: int, v: int) -> None: """Union finds the roots of components for two nodes, compares the components in terms of size, and attaches the smaller one to the larger one to form single component """ From d8b61325fefbea2289acc05e420ff1427c77979f Mon Sep 17 00:00:00 2001 From: P Shiva Rama Krishna Date: Sat, 21 Aug 2021 19:11:15 +0530 Subject: [PATCH 04/14] =?UTF-8?q?Added=20Bor=C5=AFvka's=20algorithm,=20a?= =?UTF-8?q?=20graph=20algorithm=20that=20finds=20the=20minimum=20spanning?= =?UTF-8?q?=20tree.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- graphs/boruvka.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/graphs/boruvka.py b/graphs/boruvka.py index 000c398b32f5..f557ff12363b 100644 --- a/graphs/boruvka.py +++ b/graphs/boruvka.py @@ -4,7 +4,7 @@ Borůvka's algorithm is a greedy algorithm for finding a minimum spanning tree in a graph, or a minimum spanning forest in the case of a graph that is not connected. - The time complexity of this algorithm is O(ElogV), where E represents the number of edges, + The time complexity of this algorithm is O(ELogV), where E represents the number of edges, while V represents the number of nodes. The space complexity of this algorithm is O(V + E), since we have to keep a couple of lists whose sizes are equal @@ -39,40 +39,40 @@ def __init__(self, num_of_nodes: int) -> None: self.m_edges = [] self.m_component = {} - def add_edge(self, u: int, v: int, weight: int) -> None: + def add_edge(self, u_node: int, v_node: int, weight: int) -> None: """Adds an edge in the format [first, second, edge weight] to graph.""" - self.m_edges.append([u, v, weight]) + self.m_edges.append([u_node, v_node, weight]) - def find_component(self, u: int) -> int: + def find_component(self, u_node: int) -> int: """Propagates a new component throughout a given component.""" - if self.m_component[u] == u: - return u - return self.find_component(self.m_component[u]) + if self.m_component[u_node] == u_node: + return u_node + return self.find_component(self.m_component[u_node]) - def set_component(self, u: int) -> None: + def set_component(self, u_node: int) -> None: """Finds the component index of a given node""" - if self.m_component[u] == u: + if self.m_component[u_node] == u_node: return else: for k in self.m_component.keys(): self.m_component[k] = self.find_component(k) - def union(self, component_size: list, u: int, v: int) -> None: + def union(self, component_size: list, u_node: int, v_node: int) -> None: """Union finds the roots of components for two nodes, compares the components in terms of size, and attaches the smaller one to the larger one to form single component """ - if component_size[u] <= component_size[v]: - self.m_component[u] = v - component_size[v] += component_size[u] - self.set_component(u) + if component_size[u_node] <= component_size[v_node]: + self.m_component[u_node] = v_node + component_size[v_node] += component_size[u_node] + self.set_component(u_node) - elif component_size[u] >= component_size[v]: - self.m_component[v] = self.find_component(u) - component_size[u] += component_size[v] - self.set_component(v) + elif component_size[u_node] >= component_size[v_node]: + self.m_component[v_node] = self.find_component(u_node) + component_size[u_node] += component_size[v_node] + self.set_component(v_node) print(self.m_component) From 88bb91e0607a524d660df22fa770327b572ab22a Mon Sep 17 00:00:00 2001 From: P Shiva Rama Krishna Date: Sat, 21 Aug 2021 19:21:53 +0530 Subject: [PATCH 05/14] =?UTF-8?q?Added=20Bor=C5=AFvka's=20algorithm,=20a?= =?UTF-8?q?=20graph=20algorithm=20that=20finds=20the=20minimum=20spanning?= =?UTF-8?q?=20tree.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- graphs/boruvka.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/graphs/boruvka.py b/graphs/boruvka.py index f557ff12363b..2aabd74c19bd 100644 --- a/graphs/boruvka.py +++ b/graphs/boruvka.py @@ -150,7 +150,7 @@ def test_vector() -> None: >>>g.add_edge(4, 6, 6) >>>g.add_edge(4, 7, 5) >>>g.add_edge(5, 7, 15) - >>>g.add_edge(5, 7, 4) + >>>g.add_edge(6, 7, 4) >>>g.boruvka() {0: 3, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7} Added edge [0 - 3] @@ -169,18 +169,18 @@ def test_vector() -> None: Added weight: 5 {0: 3, 1: 3, 2: 3, 3: 3, 4: 7, 5: 7, 6: 6, 7: 7} - Added edge [5 - 7] - Added weight: 4 + Added edge [4 - 5] + Added weight: 10 {0: 3, 1: 3, 2: 3, 3: 3, 4: 7, 5: 7, 6: 7, 7: 7} - Added edge [4 - 6] - Added weight: 6 + Added edge [6 - 7] + Added weight: 4 {0: 7, 1: 7, 2: 7, 3: 7, 4: 7, 5: 7, 6: 7, 7: 7} Added edge [3 - 4] Added weight: 8 - The total weight of the minimal spanning tree is: 42 + The total weight of the minimal spanning tree is: 46 """ From c4a2e46a80965b5f5b8793aca8a7666ec5926d43 Mon Sep 17 00:00:00 2001 From: P Shiva Rama Krishna Date: Sun, 22 Aug 2021 00:52:46 +0530 Subject: [PATCH 06/14] =?UTF-8?q?Added=20Bor=C5=AFvka's=20algorithm,=20a?= =?UTF-8?q?=20graph=20algorithm=20that=20finds=20the=20minimum=20spanning?= =?UTF-8?q?=20tree.=20Solved=20Test=20Cases=20Errors.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- graphs/boruvka.py | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/graphs/boruvka.py b/graphs/boruvka.py index 2aabd74c19bd..39e2beeb6c3f 100644 --- a/graphs/boruvka.py +++ b/graphs/boruvka.py @@ -139,47 +139,47 @@ def boruvka(self) -> None: def test_vector() -> None: """ - >>>g=Graph(8) - >>>g.add_edge(0, 1, 10) - >>>g.add_edge(0, 2, 6) - >>>g.add_edge(0, 3, 5) - >>>g.add_edge(1, 3, 15) - >>>g.add_edge(2, 3, 4) - >>>g.add_edge(3, 4, 8) - >>>g.add_edge(4, 5, 10) - >>>g.add_edge(4, 6, 6) - >>>g.add_edge(4, 7, 5) - >>>g.add_edge(5, 7, 15) - >>>g.add_edge(6, 7, 4) - >>>g.boruvka() + >>> g=Graph(8) + >>> g.add_edge(0, 1, 10) + >>> g.add_edge(0, 2, 6) + >>> g.add_edge(0, 3, 5) + >>> g.add_edge(1, 3, 15) + >>> g.add_edge(2, 3, 4) + >>> g.add_edge(3, 4, 8) + >>> g.add_edge(4, 5, 10) + >>> g.add_edge(4, 6, 6) + >>> g.add_edge(4, 7, 5) + >>> g.add_edge(5, 7, 15) + >>> g.add_edge(6, 7, 4) + >>> g.boruvka() {0: 3, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7} Added edge [0 - 3] Added weight: 5 - + {0: 3, 1: 3, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7} Added edge [0 - 1] Added weight: 10 - + {0: 3, 1: 3, 2: 3, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7} Added edge [2 - 3] Added weight: 4 - + {0: 3, 1: 3, 2: 3, 3: 3, 4: 7, 5: 5, 6: 6, 7: 7} Added edge [4 - 7] Added weight: 5 - + {0: 3, 1: 3, 2: 3, 3: 3, 4: 7, 5: 7, 6: 6, 7: 7} Added edge [4 - 5] Added weight: 10 - + {0: 3, 1: 3, 2: 3, 3: 3, 4: 7, 5: 7, 6: 7, 7: 7} Added edge [6 - 7] Added weight: 4 - + {0: 7, 1: 7, 2: 7, 3: 7, 4: 7, 5: 7, 6: 7, 7: 7} Added edge [3 - 4] Added weight: 8 - + The total weight of the minimal spanning tree is: 46 """ From ac6a863eb60470b8b663e381d02f72949561d290 Mon Sep 17 00:00:00 2001 From: P Shiva Rama Krishna Date: Sun, 22 Aug 2021 01:39:21 +0530 Subject: [PATCH 07/14] =?UTF-8?q?Added=20Bor=C5=AFvka's=20algorithm,=20a?= =?UTF-8?q?=20graph=20algorithm=20that=20finds=20the=20minimum=20spanning?= =?UTF-8?q?=20tree.=20Solved=20Test=20Cases=20Errors.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- graphs/boruvka.py | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/graphs/boruvka.py b/graphs/boruvka.py index 39e2beeb6c3f..76fa08825d6f 100644 --- a/graphs/boruvka.py +++ b/graphs/boruvka.py @@ -62,7 +62,7 @@ def set_component(self, u_node: int) -> None: def union(self, component_size: list, u_node: int, v_node: int) -> None: """Union finds the roots of components for two nodes, compares the components in terms of size, - and attaches the smaller one to the larger one to form single component """ + and attaches the smaller one to the larger one to form single component """ if component_size[u_node] <= component_size[v_node]: self.m_component[u_node] = v_node @@ -103,17 +103,23 @@ def boruvka(self) -> None: v_component = self.m_component[v] if u_component != v_component: - """If the current minimum weight edge of component u doesn't exist (is -1), or if - it's greater than the edge we're observing right now, we will assign the value - of the edge we're observing to it. - - If the current minimum weight edge of component v doesn't exist (is -1), or if - it's greater than the edge we're observing right now, we will assign the value - of the edge we're observing to it""" - - if minimum_weight_edge[u_component] == -1 or minimum_weight_edge[u_component][2] > w: + """If the current minimum weight edge of component u doesn't exist (is -1), or if + it's greater than the edge we're observing right now, we will assign the value + of the edge we're observing to it. + + If the current minimum weight edge of component v doesn't exist (is -1), or if + it's greater than the edge we're observing right now, we will assign the value + of the edge we're observing to it""" + + if ( + minimum_weight_edge[u_component] == -1 + or minimum_weight_edge[u_component][2] > w + ): minimum_weight_edge[u_component] = [u, v, w] - if minimum_weight_edge[v_component] == -1 or minimum_weight_edge[v_component][2] > w: + if ( + minimum_weight_edge[v_component] == -1 + or minimum_weight_edge[v_component][2] > w + ): minimum_weight_edge[v_component] = [u, v, w] for node in range(self.m_v): @@ -128,9 +134,16 @@ def boruvka(self) -> None: if u_component != v_component: mst_weight += w self.union(component_size, u_component, v_component) - print("Added edge [" + str(u) + " - " - + str(v) + "]\n" - + "Added weight: " + str(w) + "\n") + print( + "Added edge [" + + str(u) + + " - " + + str(v) + + "]\n" + + "Added weight: " + + str(w) + + "\n" + ) num_of_components -= 1 minimum_weight_edge = [-1] * self.m_v From c01ccb94ba18768027abfe4c16dabfd1cf4b04bf Mon Sep 17 00:00:00 2001 From: P Shiva Rama Krishna Date: Sun, 22 Aug 2021 01:41:38 +0530 Subject: [PATCH 08/14] =?UTF-8?q?Added=20Bor=C5=AFvka's=20algorithm,=20a?= =?UTF-8?q?=20graph=20algorithm=20that=20finds=20the=20minimum=20spanning?= =?UTF-8?q?=20tree.=20Solved=20Test=20Cases=20Errors.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- graphs/boruvka.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/graphs/boruvka.py b/graphs/boruvka.py index 76fa08825d6f..9a7c697a75aa 100644 --- a/graphs/boruvka.py +++ b/graphs/boruvka.py @@ -112,14 +112,14 @@ def boruvka(self) -> None: of the edge we're observing to it""" if ( - minimum_weight_edge[u_component] == -1 - or minimum_weight_edge[u_component][2] > w - ): + minimum_weight_edge[u_component] == -1 + or minimum_weight_edge[u_component][2] > w + ): minimum_weight_edge[u_component] = [u, v, w] if ( - minimum_weight_edge[v_component] == -1 - or minimum_weight_edge[v_component][2] > w - ): + minimum_weight_edge[v_component] == -1 + or minimum_weight_edge[v_component][2] > w + ): minimum_weight_edge[v_component] = [u, v, w] for node in range(self.m_v): From daa532ca8f8665445722abd609330ca8c24bf27a Mon Sep 17 00:00:00 2001 From: P Shiva Rama Krishna Date: Sun, 22 Aug 2021 11:32:16 +0530 Subject: [PATCH 09/14] =?UTF-8?q?Added=20Bor=C5=AFvka's=20algorithm,=20a?= =?UTF-8?q?=20graph=20algorithm=20that=20finds=20the=20minimum=20spanning?= =?UTF-8?q?=20tree.=20Solved=20Test=20Cases=20Errors.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- graphs/boruvka.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/graphs/boruvka.py b/graphs/boruvka.py index 9a7c697a75aa..c051733bac34 100644 --- a/graphs/boruvka.py +++ b/graphs/boruvka.py @@ -62,7 +62,7 @@ def set_component(self, u_node: int) -> None: def union(self, component_size: list, u_node: int, v_node: int) -> None: """Union finds the roots of components for two nodes, compares the components in terms of size, - and attaches the smaller one to the larger one to form single component """ + and attaches the smaller one to the larger one to form single component""" if component_size[u_node] <= component_size[v_node]: self.m_component[u_node] = v_node @@ -104,12 +104,12 @@ def boruvka(self) -> None: if u_component != v_component: """If the current minimum weight edge of component u doesn't exist (is -1), or if - it's greater than the edge we're observing right now, we will assign the value - of the edge we're observing to it. + it's greater than the edge we're observing right now, we will assign the value + of the edge we're observing to it. - If the current minimum weight edge of component v doesn't exist (is -1), or if - it's greater than the edge we're observing right now, we will assign the value - of the edge we're observing to it""" + If the current minimum weight edge of component v doesn't exist (is -1), or if + it's greater than the edge we're observing right now, we will assign the value + of the edge we're observing to it""" if ( minimum_weight_edge[u_component] == -1 @@ -135,15 +135,15 @@ def boruvka(self) -> None: mst_weight += w self.union(component_size, u_component, v_component) print( - "Added edge [" - + str(u) - + " - " - + str(v) - + "]\n" - + "Added weight: " - + str(w) - + "\n" - ) + "Added edge [" + + str(u) + + " - " + + str(v) + + "]\n" + + "Added weight: " + + str(w) + + "\n" + ) num_of_components -= 1 minimum_weight_edge = [-1] * self.m_v From 3265907b0072b1e6bd799e0e68403737963e50a3 Mon Sep 17 00:00:00 2001 From: P Shiva Rama Krishna Date: Sun, 22 Aug 2021 14:10:00 +0530 Subject: [PATCH 10/14] =?UTF-8?q?Added=20Bor=C5=AFvka's=20algorithm,=20a?= =?UTF-8?q?=20graph=20algorithm=20that=20finds=20the=20minimum=20spanning?= =?UTF-8?q?=20tree.=20Solved=20Test=20Cases=20Errors.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- graphs/boruvka.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphs/boruvka.py b/graphs/boruvka.py index c051733bac34..dc76ee145bc0 100644 --- a/graphs/boruvka.py +++ b/graphs/boruvka.py @@ -106,7 +106,7 @@ def boruvka(self) -> None: """If the current minimum weight edge of component u doesn't exist (is -1), or if it's greater than the edge we're observing right now, we will assign the value of the edge we're observing to it. - + If the current minimum weight edge of component v doesn't exist (is -1), or if it's greater than the edge we're observing right now, we will assign the value of the edge we're observing to it""" From 08670920d5cda47bfbe2b594138e9ea3159bdd3c Mon Sep 17 00:00:00 2001 From: P Shiva Rama Krishna Date: Sun, 22 Aug 2021 14:29:05 +0530 Subject: [PATCH 11/14] =?UTF-8?q?Added=20Bor=C5=AFvka's=20algorithm,=20a?= =?UTF-8?q?=20graph=20algorithm=20that=20finds=20the=20minimum=20spanning?= =?UTF-8?q?=20tree.=20Solved=20Test=20Cases=20Errors.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- graphs/boruvka.py | 51 +++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/graphs/boruvka.py b/graphs/boruvka.py index dc76ee145bc0..2bc6e5fc4a2d 100644 --- a/graphs/boruvka.py +++ b/graphs/boruvka.py @@ -1,22 +1,25 @@ """Borůvka's algorithm. Determines the minimum spanning tree(MST) of a graph using the Borůvka's algorithm. - Borůvka's algorithm is a greedy algorithm for finding a minimum spanning tree in a graph, - or a minimum spanning forest in the case of a graph that is not connected. + Borůvka's algorithm is a greedy algorithm for finding a minimum spanning tree in a + graph,or a minimum spanning forest in the case of a graph that is not connected. - The time complexity of this algorithm is O(ELogV), where E represents the number of edges, - while V represents the number of nodes. + The time complexity of this algorithm is O(ELogV), where E represents the number + of edges, while V represents the number of nodes. - The space complexity of this algorithm is O(V + E), since we have to keep a couple of lists whose sizes are equal - to the number of nodes, as well as keep all the edges of a graph inside of the data structure itself. + The space complexity of this algorithm is O(V + E), since we have to keep a couple + of lists whose sizes are equal to the number of nodes, as well as keep all the + edges of a graph inside of the data structure itself. - Borůvka's algorithm gives us pretty much the same result as other MST Algorithms - they all find the minimum spanning - tree, and the time complexity is approximately the same. + Borůvka's algorithm gives us pretty much the same result as other MST Algorithms - + they all find the minimum spanning tree, and the time complexity is approximately + the same. - One advantage that Borůvka's algorithm has compared to the alternatives is that it doesn't - need to presort the edges or maintain a priority queue in order to find the minimum spanning tree. - Even though that doesn't help its complexity, since it still passes the edges logE times, - it is a bit more simple to code. + One advantage that Borůvka's algorithm has compared to the alternatives is that it + doesn't need to presort the edges or maintain a priority queue in order to find the + minimum spanning tree. + Even though that doesn't help its complexity, since it still passes the edges logE + times, it is a bit more simple to code. Details: https://en.wikipedia.org/wiki/Bor%C5%AFvka%27s_algorithm """ @@ -32,7 +35,8 @@ def __init__(self, num_of_nodes: int) -> None: Attributes: m_v - the number of nodes in the graph. m_edges - the list of edges. - m_component - the dictionary which stores the index of the component which a node belongs to. + m_component - the dictionary which stores the index of the component which + a node belongs to. """ self.m_v = num_of_nodes @@ -61,8 +65,9 @@ def set_component(self, u_node: int) -> None: self.m_component[k] = self.find_component(k) def union(self, component_size: list, u_node: int, v_node: int) -> None: - """Union finds the roots of components for two nodes, compares the components in terms of size, - and attaches the smaller one to the larger one to form single component""" + """Union finds the roots of components for two nodes, compares the components + in terms of size, and attaches the smaller one to the larger one to form + single component""" if component_size[u_node] <= component_size[v_node]: self.m_component[u_node] = v_node @@ -103,13 +108,15 @@ def boruvka(self) -> None: v_component = self.m_component[v] if u_component != v_component: - """If the current minimum weight edge of component u doesn't exist (is -1), or if - it's greater than the edge we're observing right now, we will assign the value - of the edge we're observing to it. - - If the current minimum weight edge of component v doesn't exist (is -1), or if - it's greater than the edge we're observing right now, we will assign the value - of the edge we're observing to it""" + """If the current minimum weight edge of component u doesn't + exist (is -1), or if it's greater than the edge we're + observing right now, we will assign the value of the edge + we're observing to it. + + If the current minimum weight edge of component v doesn't + exist (is -1), or if it's greater than the edge we're + observing right now, we will assign the value of the edge + we're observing to it""" if ( minimum_weight_edge[u_component] == -1 From f8125d713dee9386099426af89d5ade1d6de80c5 Mon Sep 17 00:00:00 2001 From: P Shiva Rama Krishna Date: Sun, 22 Aug 2021 15:27:36 +0530 Subject: [PATCH 12/14] =?UTF-8?q?Added=20Bor=C5=AFvka's=20algorithm,=20a?= =?UTF-8?q?=20graph=20algorithm=20that=20finds=20the=20minimum=20spanning?= =?UTF-8?q?=20tree.=20Solved=20Test=20Cases=20Errors.Removed=20WhiteSpaces?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- graphs/boruvka.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphs/boruvka.py b/graphs/boruvka.py index 2bc6e5fc4a2d..b4e6b87f00ca 100644 --- a/graphs/boruvka.py +++ b/graphs/boruvka.py @@ -108,7 +108,7 @@ def boruvka(self) -> None: v_component = self.m_component[v] if u_component != v_component: - """If the current minimum weight edge of component u doesn't + """If the current minimum weight edge of component u doesn't exist (is -1), or if it's greater than the edge we're observing right now, we will assign the value of the edge we're observing to it. From e9af60a586888b9cb46adc0a366f96d7d8157375 Mon Sep 17 00:00:00 2001 From: P Shiva Rama Krishna Date: Mon, 23 Aug 2021 13:14:04 +0530 Subject: [PATCH 13/14] =?UTF-8?q?Added=20Bor=C5=AFvka's=20algorithm,=20a?= =?UTF-8?q?=20graph=20algorithm=20that=20finds=20the=20minimum=20spanning?= =?UTF-8?q?=20tree.=20Code=20Changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- graphs/boruvka.py | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/graphs/boruvka.py b/graphs/boruvka.py index b4e6b87f00ca..70f19eae9dcb 100644 --- a/graphs/boruvka.py +++ b/graphs/boruvka.py @@ -26,8 +26,6 @@ class Graph: - """Class Graph.""" - def __init__(self, num_of_nodes: int) -> None: """ Arguments: @@ -58,9 +56,7 @@ def find_component(self, u_node: int) -> int: def set_component(self, u_node: int) -> None: """Finds the component index of a given node""" - if self.m_component[u_node] == u_node: - return - else: + if self.m_component[u_node] != u_node: for k in self.m_component.keys(): self.m_component[k] = self.find_component(k) @@ -79,8 +75,6 @@ def union(self, component_size: list, u_node: int, v_node: int) -> None: component_size[u_node] += component_size[v_node] self.set_component(v_node) - print(self.m_component) - def boruvka(self) -> None: """Performs Borůvka's algorithm to find MST.""" @@ -98,7 +92,8 @@ def boruvka(self) -> None: num_of_components = self.m_v while num_of_components > 1: - for i in range(len(self.m_edges)): + l_edges = len(self.m_edges) + for i in range(l_edges): u = self.m_edges[i][0] v = self.m_edges[i][1] @@ -119,13 +114,13 @@ def boruvka(self) -> None: we're observing to it""" if ( - minimum_weight_edge[u_component] == -1 - or minimum_weight_edge[u_component][2] > w + minimum_weight_edge[u_component] == -1 + or minimum_weight_edge[u_component][2] > w ): minimum_weight_edge[u_component] = [u, v, w] if ( - minimum_weight_edge[v_component] == -1 - or minimum_weight_edge[v_component][2] > w + minimum_weight_edge[v_component] == -1 + or minimum_weight_edge[v_component][2] > w ): minimum_weight_edge[v_component] = [u, v, w] @@ -172,31 +167,24 @@ def test_vector() -> None: >>> g.add_edge(5, 7, 15) >>> g.add_edge(6, 7, 4) >>> g.boruvka() - {0: 3, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7} Added edge [0 - 3] Added weight: 5 - {0: 3, 1: 3, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7} Added edge [0 - 1] Added weight: 10 - {0: 3, 1: 3, 2: 3, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7} Added edge [2 - 3] Added weight: 4 - {0: 3, 1: 3, 2: 3, 3: 3, 4: 7, 5: 5, 6: 6, 7: 7} Added edge [4 - 7] Added weight: 5 - {0: 3, 1: 3, 2: 3, 3: 3, 4: 7, 5: 7, 6: 6, 7: 7} Added edge [4 - 5] Added weight: 10 - {0: 3, 1: 3, 2: 3, 3: 3, 4: 7, 5: 7, 6: 7, 7: 7} Added edge [6 - 7] Added weight: 4 - {0: 7, 1: 7, 2: 7, 3: 7, 4: 7, 5: 7, 6: 7, 7: 7} Added edge [3 - 4] Added weight: 8 From aba7767abf5a77a70f39da77848b8a8766b942b6 Mon Sep 17 00:00:00 2001 From: P Shiva Rama Krishna Date: Mon, 23 Aug 2021 13:18:06 +0530 Subject: [PATCH 14/14] =?UTF-8?q?Added=20Bor=C5=AFvka's=20algorithm,=20a?= =?UTF-8?q?=20graph=20algorithm=20that=20finds=20the=20minimum=20spanning?= =?UTF-8?q?=20tree.=20Code=20Changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- graphs/boruvka.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/graphs/boruvka.py b/graphs/boruvka.py index 70f19eae9dcb..b95bcc39850e 100644 --- a/graphs/boruvka.py +++ b/graphs/boruvka.py @@ -114,13 +114,13 @@ def boruvka(self) -> None: we're observing to it""" if ( - minimum_weight_edge[u_component] == -1 - or minimum_weight_edge[u_component][2] > w + minimum_weight_edge[u_component] == -1 + or minimum_weight_edge[u_component][2] > w ): minimum_weight_edge[u_component] = [u, v, w] if ( - minimum_weight_edge[v_component] == -1 - or minimum_weight_edge[v_component][2] > w + minimum_weight_edge[v_component] == -1 + or minimum_weight_edge[v_component][2] > w ): minimum_weight_edge[v_component] = [u, v, w]