1
1
"""Borůvka's algorithm.
2
2
3
- Determines the minimum spanning tree(MST) of a graph using the Borůvka's algorithm.
3
+ Determines the minimum spanning tree (MST) of a graph using the Borůvka's algorithm.
4
4
Borůvka's algorithm is a greedy algorithm for finding a minimum spanning tree in a
5
- graph,or a minimum spanning forest in the case of a graph that is not connected.
5
+ connected graph, or a minimum spanning forest if a graph that is not connected.
6
6
7
7
The time complexity of this algorithm is O(ELogV), where E represents the number
8
8
of edges, while V represents the number of nodes.
9
+ O(number_of_edges Log number_of_nodes)
9
10
10
11
The space complexity of this algorithm is O(V + E), since we have to keep a couple
11
12
of lists whose sizes are equal to the number of nodes, as well as keep all the
19
20
doesn't need to presort the edges or maintain a priority queue in order to find the
20
21
minimum spanning tree.
21
22
Even though that doesn't help its complexity, since it still passes the edges logE
22
- times, it is a bit more simple to code.
23
+ times, it is a bit simpler to code.
23
24
24
25
Details: https://en.wikipedia.org/wiki/Bor%C5%AFvka%27s_algorithm
25
26
"""
@@ -31,13 +32,13 @@ def __init__(self, num_of_nodes: int) -> None:
31
32
Arguments:
32
33
num_of_nodes - the number of nodes in the graph
33
34
Attributes:
34
- m_v - the number of nodes in the graph.
35
+ m_num_of_nodes - the number of nodes in the graph.
35
36
m_edges - the list of edges.
36
37
m_component - the dictionary which stores the index of the component which
37
38
a node belongs to.
38
39
"""
39
40
40
- self .m_v = num_of_nodes
41
+ self .m_num_of_nodes = num_of_nodes
41
42
self .m_edges = []
42
43
self .m_component = {}
43
44
@@ -57,7 +58,7 @@ def set_component(self, u_node: int) -> None:
57
58
"""Finds the component index of a given node"""
58
59
59
60
if self .m_component [u_node ] != u_node :
60
- for k in self .m_component . keys () :
61
+ for k in self .m_component :
61
62
self .m_component [k ] = self .find_component (k )
62
63
63
64
def union (self , component_size : list , u_node : int , v_node : int ) -> None :
@@ -82,22 +83,18 @@ def boruvka(self) -> None:
82
83
component_size = []
83
84
mst_weight = 0
84
85
85
- minimum_weight_edge = [- 1 ] * self .m_v
86
+ minimum_weight_edge = [- 1 ] * self .m_num_of_nodes
86
87
87
88
# A list of components (initialized to all of the nodes)
88
- for node in range (self .m_v ):
89
+ for node in range (self .m_num_of_nodes ):
89
90
self .m_component .update ({node : node })
90
91
component_size .append (1 )
91
92
92
- num_of_components = self .m_v
93
+ num_of_components = self .m_num_of_nodes
93
94
94
95
while num_of_components > 1 :
95
- l_edges = len (self .m_edges )
96
- for i in range (l_edges ):
97
-
98
- u = self .m_edges [i ][0 ]
99
- v = self .m_edges [i ][1 ]
100
- w = self .m_edges [i ][2 ]
96
+ for edge in self .m_edges :
97
+ u , v , w = edge
101
98
102
99
u_component = self .m_component [u ]
103
100
v_component = self .m_component [v ]
@@ -113,59 +110,36 @@ def boruvka(self) -> None:
113
110
observing right now, we will assign the value of the edge
114
111
we're observing to it"""
115
112
116
- if (
117
- minimum_weight_edge [u_component ] == - 1
118
- or minimum_weight_edge [u_component ][2 ] > w
119
- ):
120
- minimum_weight_edge [u_component ] = [u , v , w ]
121
- if (
122
- minimum_weight_edge [v_component ] == - 1
123
- or minimum_weight_edge [v_component ][2 ] > w
124
- ):
125
- minimum_weight_edge [v_component ] = [u , v , w ]
126
-
127
- for node in range (self .m_v ):
128
- if minimum_weight_edge [node ] != - 1 :
129
- u = minimum_weight_edge [node ][0 ]
130
- v = minimum_weight_edge [node ][1 ]
131
- w = minimum_weight_edge [node ][2 ]
113
+ for component in (u_component , v_component ):
114
+ if (
115
+ minimum_weight_edge [component ] == - 1
116
+ or minimum_weight_edge [component ][2 ] > w
117
+ ):
118
+ minimum_weight_edge [component ] = [u , v , w ]
119
+
120
+ for edge in minimum_weight_edge :
121
+ if edge != - 1 :
122
+ u , v , w = edge
132
123
133
124
u_component = self .m_component [u ]
134
125
v_component = self .m_component [v ]
135
126
136
127
if u_component != v_component :
137
128
mst_weight += w
138
129
self .union (component_size , u_component , v_component )
139
- print (
140
- "Added edge ["
141
- + str (u )
142
- + " - "
143
- + str (v )
144
- + "]\n "
145
- + "Added weight: "
146
- + str (w )
147
- + "\n "
148
- )
130
+ print (f"Added edge [{ u } - { v } ]\n Added weight: { w } \n " )
149
131
num_of_components -= 1
150
132
151
- minimum_weight_edge = [- 1 ] * self .m_v
152
- print ("The total weight of the minimal spanning tree is: " + str ( mst_weight ) )
133
+ minimum_weight_edge = [- 1 ] * self .m_num_of_nodes
134
+ print (f "The total weight of the minimal spanning tree is: { mst_weight } " )
153
135
154
136
155
137
def test_vector () -> None :
156
138
"""
157
- >>> g=Graph(8)
158
- >>> g.add_edge(0, 1, 10)
159
- >>> g.add_edge(0, 2, 6)
160
- >>> g.add_edge(0, 3, 5)
161
- >>> g.add_edge(1, 3, 15)
162
- >>> g.add_edge(2, 3, 4)
163
- >>> g.add_edge(3, 4, 8)
164
- >>> g.add_edge(4, 5, 10)
165
- >>> g.add_edge(4, 6, 6)
166
- >>> g.add_edge(4, 7, 5)
167
- >>> g.add_edge(5, 7, 15)
168
- >>> g.add_edge(6, 7, 4)
139
+ >>> g = Graph(8)
140
+ >>> for u_v_w in ((0, 1, 10), (0, 2, 6), (0, 3, 5), (1, 3, 15), (2, 3, 4),
141
+ ... (3, 4, 8), (4, 5, 10), (4, 6, 6), (4, 7, 5), (5, 7, 15), (6, 7, 4)):
142
+ ... g.add_edge(*u_v_w)
169
143
>>> g.boruvka()
170
144
Added edge [0 - 3]
171
145
Added weight: 5
0 commit comments