Skip to content

boruvka.py: A few simplifications and f-strings #4660

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
* [Peak Signal To Noise Ratio](https://github.com/TheAlgorithms/Python/blob/master/compression/peak_signal_to_noise_ratio.py)

## Computer Vision
* [Cnn Classification](https://github.com/TheAlgorithms/Python/blob/master/computer_vision/cnn_classification.py)
* [Harris Corner](https://github.com/TheAlgorithms/Python/blob/master/computer_vision/harris_corner.py)
* [Mean Threshold](https://github.com/TheAlgorithms/Python/blob/master/computer_vision/mean_threshold.py)

Expand Down Expand Up @@ -300,6 +301,7 @@
* [Bfs Zero One Shortest Path](https://github.com/TheAlgorithms/Python/blob/master/graphs/bfs_zero_one_shortest_path.py)
* [Bidirectional A Star](https://github.com/TheAlgorithms/Python/blob/master/graphs/bidirectional_a_star.py)
* [Bidirectional Breadth First Search](https://github.com/TheAlgorithms/Python/blob/master/graphs/bidirectional_breadth_first_search.py)
* [Boruvka](https://github.com/TheAlgorithms/Python/blob/master/graphs/boruvka.py)
* [Breadth First Search](https://github.com/TheAlgorithms/Python/blob/master/graphs/breadth_first_search.py)
* [Breadth First Search 2](https://github.com/TheAlgorithms/Python/blob/master/graphs/breadth_first_search_2.py)
* [Breadth First Search Shortest Path](https://github.com/TheAlgorithms/Python/blob/master/graphs/breadth_first_search_shortest_path.py)
Expand Down Expand Up @@ -349,6 +351,7 @@
* [Djb2](https://github.com/TheAlgorithms/Python/blob/master/hashes/djb2.py)
* [Enigma Machine](https://github.com/TheAlgorithms/Python/blob/master/hashes/enigma_machine.py)
* [Hamming Code](https://github.com/TheAlgorithms/Python/blob/master/hashes/hamming_code.py)
* [Luhn](https://github.com/TheAlgorithms/Python/blob/master/hashes/luhn.py)
* [Md5](https://github.com/TheAlgorithms/Python/blob/master/hashes/md5.py)
* [Sdbm](https://github.com/TheAlgorithms/Python/blob/master/hashes/sdbm.py)
* [Sha1](https://github.com/TheAlgorithms/Python/blob/master/hashes/sha1.py)
Expand Down Expand Up @@ -421,10 +424,12 @@
* [Binomial Distribution](https://github.com/TheAlgorithms/Python/blob/master/maths/binomial_distribution.py)
* [Bisection](https://github.com/TheAlgorithms/Python/blob/master/maths/bisection.py)
* [Ceil](https://github.com/TheAlgorithms/Python/blob/master/maths/ceil.py)
* [Check Valid Ip Address](https://github.com/TheAlgorithms/Python/blob/master/maths/check_valid_ip_address.py)
* [Chudnovsky Algorithm](https://github.com/TheAlgorithms/Python/blob/master/maths/chudnovsky_algorithm.py)
* [Collatz Sequence](https://github.com/TheAlgorithms/Python/blob/master/maths/collatz_sequence.py)
* [Combinations](https://github.com/TheAlgorithms/Python/blob/master/maths/combinations.py)
* [Decimal Isolate](https://github.com/TheAlgorithms/Python/blob/master/maths/decimal_isolate.py)
* [Double Factorial Recursive](https://github.com/TheAlgorithms/Python/blob/master/maths/double_factorial_recursive.py)
* [Entropy](https://github.com/TheAlgorithms/Python/blob/master/maths/entropy.py)
* [Euclidean Distance](https://github.com/TheAlgorithms/Python/blob/master/maths/euclidean_distance.py)
* [Euclidean Gcd](https://github.com/TheAlgorithms/Python/blob/master/maths/euclidean_gcd.py)
Expand Down Expand Up @@ -539,6 +544,7 @@

## Other
* [Activity Selection](https://github.com/TheAlgorithms/Python/blob/master/other/activity_selection.py)
* [Date To Weekday](https://github.com/TheAlgorithms/Python/blob/master/other/date_to_weekday.py)
* [Davis–Putnam–Logemann–Loveland](https://github.com/TheAlgorithms/Python/blob/master/other/davis–putnam–logemann–loveland.py)
* [Dijkstra Bankers Algorithm](https://github.com/TheAlgorithms/Python/blob/master/other/dijkstra_bankers_algorithm.py)
* [Doomsday](https://github.com/TheAlgorithms/Python/blob/master/other/doomsday.py)
Expand Down Expand Up @@ -854,6 +860,7 @@
* [Counting Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/counting_sort.py)
* [Cycle Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/cycle_sort.py)
* [Double Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/double_sort.py)
* [Exchange Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/exchange_sort.py)
* [External Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/external_sort.py)
* [Gnome Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/gnome_sort.py)
* [Heap Sort](https://github.com/TheAlgorithms/Python/blob/master/sorts/heap_sort.py)
Expand Down Expand Up @@ -893,6 +900,7 @@

## Strings
* [Aho Corasick](https://github.com/TheAlgorithms/Python/blob/master/strings/aho_corasick.py)
* [Alternative String Arrange](https://github.com/TheAlgorithms/Python/blob/master/strings/alternative_string_arrange.py)
* [Anagrams](https://github.com/TheAlgorithms/Python/blob/master/strings/anagrams.py)
* [Autocomplete Using Trie](https://github.com/TheAlgorithms/Python/blob/master/strings/autocomplete_using_trie.py)
* [Boyer Moore Search](https://github.com/TheAlgorithms/Python/blob/master/strings/boyer_moore_search.py)
Expand All @@ -902,6 +910,7 @@
* [Check Pangram](https://github.com/TheAlgorithms/Python/blob/master/strings/check_pangram.py)
* [Detecting English Programmatically](https://github.com/TheAlgorithms/Python/blob/master/strings/detecting_english_programmatically.py)
* [Frequency Finder](https://github.com/TheAlgorithms/Python/blob/master/strings/frequency_finder.py)
* [Indian Phone Validator](https://github.com/TheAlgorithms/Python/blob/master/strings/indian_phone_validator.py)
* [Is Palindrome](https://github.com/TheAlgorithms/Python/blob/master/strings/is_palindrome.py)
* [Jaro Winkler](https://github.com/TheAlgorithms/Python/blob/master/strings/jaro_winkler.py)
* [Knuth Morris Pratt](https://github.com/TheAlgorithms/Python/blob/master/strings/knuth_morris_pratt.py)
Expand Down Expand Up @@ -941,6 +950,7 @@
* [Instagram Crawler](https://github.com/TheAlgorithms/Python/blob/master/web_programming/instagram_crawler.py)
* [Instagram Pic](https://github.com/TheAlgorithms/Python/blob/master/web_programming/instagram_pic.py)
* [Instagram Video](https://github.com/TheAlgorithms/Python/blob/master/web_programming/instagram_video.py)
* [Random Anime Character](https://github.com/TheAlgorithms/Python/blob/master/web_programming/random_anime_character.py)
* [Recaptcha Verification](https://github.com/TheAlgorithms/Python/blob/master/web_programming/recaptcha_verification.py)
* [Slack Message](https://github.com/TheAlgorithms/Python/blob/master/web_programming/slack_message.py)
* [Test Fetch Github Info](https://github.com/TheAlgorithms/Python/blob/master/web_programming/test_fetch_github_info.py)
Expand Down
84 changes: 29 additions & 55 deletions graphs/boruvka.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
"""Borůvka's algorithm.

Determines the minimum spanning tree(MST) of a graph using the 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.
connected graph, or a minimum spanning forest if 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.
O(number_of_edges Log 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
Expand All @@ -19,7 +20,7 @@
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.
times, it is a bit simpler to code.

Details: https://en.wikipedia.org/wiki/Bor%C5%AFvka%27s_algorithm
"""
Expand All @@ -31,13 +32,13 @@ def __init__(self, num_of_nodes: int) -> None:
Arguments:
num_of_nodes - the number of nodes in the graph
Attributes:
m_v - the number of nodes in the graph.
m_num_of_nodes - 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_num_of_nodes = num_of_nodes
self.m_edges = []
self.m_component = {}

Expand All @@ -57,7 +58,7 @@ def set_component(self, u_node: int) -> None:
"""Finds the component index of a given node"""

if self.m_component[u_node] != u_node:
for k in self.m_component.keys():
for k in self.m_component:
self.m_component[k] = self.find_component(k)

def union(self, component_size: list, u_node: int, v_node: int) -> None:
Expand All @@ -82,22 +83,18 @@ def boruvka(self) -> None:
component_size = []
mst_weight = 0

minimum_weight_edge = [-1] * self.m_v
minimum_weight_edge = [-1] * self.m_num_of_nodes

# A list of components (initialized to all of the nodes)
for node in range(self.m_v):
for node in range(self.m_num_of_nodes):
self.m_component.update({node: node})
component_size.append(1)

num_of_components = self.m_v
num_of_components = self.m_num_of_nodes

while num_of_components > 1:
l_edges = len(self.m_edges)
for i in range(l_edges):

u = self.m_edges[i][0]
v = self.m_edges[i][1]
w = self.m_edges[i][2]
for edge in self.m_edges:
u, v, w = edge

u_component = self.m_component[u]
v_component = self.m_component[v]
Expand All @@ -113,59 +110,36 @@ def boruvka(self) -> None:
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]
for component in (u_component, v_component):
if (
minimum_weight_edge[component] == -1
or minimum_weight_edge[component][2] > w
):
minimum_weight_edge[component] = [u, v, w]

for edge in minimum_weight_edge:
if edge != -1:
u, v, w = edge

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"
)
print(f"Added edge [{u} - {v}]\nAdded weight: {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))
minimum_weight_edge = [-1] * self.m_num_of_nodes
print(f"The total weight of the minimal spanning tree is: {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(6, 7, 4)
>>> g = Graph(8)
>>> for u_v_w in ((0, 1, 10), (0, 2, 6), (0, 3, 5), (1, 3, 15), (2, 3, 4),
... (3, 4, 8), (4, 5, 10), (4, 6, 6), (4, 7, 5), (5, 7, 15), (6, 7, 4)):
... g.add_edge(*u_v_w)
>>> g.boruvka()
Added edge [0 - 3]
Added weight: 5
Expand Down