Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d5247ed

Browse files
committed
Enable descriptive node names
1 parent f71e02c commit d5247ed

File tree

1 file changed

+134
-89
lines changed

1 file changed

+134
-89
lines changed

‎Classes/graph_edge_list.py

Lines changed: 134 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,42 @@
1+
from node import Node
12
class Graph:
23
###################################
34
# Constructor
45
###################################
56
def __init__(self, num_of_nodes, directed=True):
67
self.m_num_of_nodes = num_of_nodes
8+
self.m_nodes = []
79

810
# Define the type of a graph
911
self.m_directed = directed
1012

11-
# Different representations of a graph
13+
# A representation of a graph
1214
# i.e. list of edges
1315
self.m_graph = []
1416

15-
# For Bovurkas
17+
# For Bovurka's algorithm
1618
self.m_components = {}
1719

1820
###################################
1921
# Add edge to a graph
2022
###################################
21-
def add_edge(self, node1, node2, weight=1):
23+
def add_edge(self, node1_name, node2_name, weight=1):
24+
node1 = Node(node1_name)
25+
node2 = Node(node2_name)
26+
if (node1 not in self.m_nodes):
27+
node1_id = len(self.m_nodes)
28+
node1.set_id(node1_id)
29+
self.m_nodes.append(node1)
30+
else:
31+
node1 = self.get_node_by_name(node1_name)
32+
33+
if (node2 not in self.m_nodes):
34+
node2_id = len(self.m_nodes)
35+
node2.set_id(node2_id)
36+
self.m_nodes.append(node2)
37+
else:
38+
node2 = self.get_node_by_name(node2_name)
39+
2240
# Add the edge from node1 to node2
2341
self.m_graph.append([node1, node2, weight])
2442

@@ -37,91 +55,99 @@ def __str__(self):
3755
out += "edge " + str(i+1) + ": " + str(self.m_graph[i]) + "\n"
3856
return out
3957

58+
def get_node_by_name(self, name):
59+
search_node = Node(name)
60+
for node in self.m_nodes:
61+
if node == search_node:
62+
return node
63+
return None
64+
4065
###################################
4166
# Kruskal's MST Algorithm
42-
#### za sada radi samo sa numbered nodes
4367
###################################
44-
# Finds the root node of a subtree containing node `i`
45-
def find_subtree(self, parent, i):
46-
if parent[i] == i:
47-
return i
48-
return self.find_subtree(parent, parent[i])
49-
50-
# Connects subtrees containing nodes `x` and `y`
51-
def connect_subtrees(self, parent, subtree_sizes, x, y):
52-
x_root = self.find_subtree(parent, x)
53-
y_root = self.find_subtree(parent, y)
54-
if subtree_sizes[x_root] < subtree_sizes[y_root]:
55-
parent[x_root] = y_root
56-
elif subtree_sizes[x_root] > subtree_sizes[y_root]:
57-
parent[y_root] = x_root
68+
# Finds the root node of a subtree containing node `node`
69+
def find_subtree(self, parent, node):
70+
if parent[node.get_id()] == node:
71+
return node
72+
return self.find_subtree(parent, parent[node.get_id()])
73+
74+
# Connects subtrees containing nodes `node1` and `node2`
75+
def connect_subtrees(self, parent, subtree_sizes, node1, node2):
76+
node1_root = self.find_subtree(parent, node1)
77+
node1_root_id = node1_root.get_id()
78+
node2_root = self.find_subtree(parent, node2)
79+
node2_root_id = node2_root.get_id()
80+
81+
if subtree_sizes[node1_root_id] < subtree_sizes[node2_root_id]:
82+
parent[node1_root_id] = node2_root
83+
elif subtree_sizes[node1_root_id] > subtree_sizes[node2_root_id]:
84+
parent[node2_root_id] = node1_root
5885
else:
59-
parent[y_root] = x_root
60-
subtree_sizes[x_root] += 1
86+
parent[node2_root_id] = node1_root
87+
subtree_sizes[node1_root_id] += 1
6188

6289
# Applying Kruskal algorithm
6390
def kruskals_mst(self):
6491
result = []
6592
i, e = 0, 0
6693

67-
# Sort edges by weight
68-
sorted_graph = sorted(self.m_graph, key=lambda item: item[2])
69-
parent = []
70-
subtree_sizes = []
71-
72-
# `node` je broj od 0 do numOfNodes -> {0, 1, ..., numOfNodes-1}
73-
# dodajemo tu vrednost na `parent` niz
74-
# dodajemo nulu na `subtree_sizes`
75-
# => inicijalizujemo `parent` i `subtree_sizes`
76-
for node in range(self.m_num_of_nodes):
77-
parent.append(node)
78-
subtree_sizes.append(0)
79-
# parent = [0, 1, 2, ... , numOfNodes-1]
94+
parent = [-1 for i in range(self.m_num_of_nodes)]
95+
subtree_sizes = [0 for i in range(self.m_num_of_nodes)]
8096

97+
# `node` is the number form 0 to num_of_nodes -> {0, 1, ..., num_of_nodes-1}
98+
# Add that number to the `parent` array
99+
# Add zero to the `subtree_sizes` array
100+
# => initialize `parent` and `subtree_sizes`
101+
for node in self.m_nodes:
102+
print(str(node) + " id is " + str(node.get_id()))
103+
parent[node.get_id()] = node
104+
# subtree_sizes.append(0)
81105

82-
# broj grana je jednak broju cvorova -1
83-
# vazno svojstvo msta
106+
# Sort edges by weight
107+
sorted_graph = sorted(self.m_graph, key=lambda item: item[2])
108+
109+
# Important property of any MST
110+
# the number of edges is equal to the number of nodes minus 1
84111
while e < (self.m_num_of_nodes - 1):
85-
# Uzimamo granu sa trenutno najmanjom tezinom
112+
# Pick an edge with the minimum weight at the moment
113+
# print(str(i) + ": " + str(sorted_graph[i]))
86114
node1, node2, weight = sorted_graph[i]
87115
i = i + 1
88-
116+
print(node1, node1.get_id())
89117
x = self.find_subtree(parent, node1)
90118
y = self.find_subtree(parent, node2)
91119
if x != y:
92120
e = e + 1
93-
result.append([node, node2, weight])
121+
result.append([node1, node2, weight])
94122
self.connect_subtrees(parent, subtree_sizes, x, y)
95123

96124
print("Kruskal's MST:")
97125
for node1, node2, weight in result:
98-
print("%d - %d: %d" % (node1, node2, weight))
126+
print("%s - %s: %d" % (node1, node2, weight))
99127

100128
###################################
101129
# Borůvka's MST Algorithm
102130
###################################
103-
def find_component(self, u):
104-
if self.m_components[u] == u:
105-
return u
106-
return self.find_component(self.m_components[u])
131+
def find_component(self, node):
132+
if self.m_components[node] == node:
133+
return node
134+
return self.find_component(self.m_components[node])
107135

108-
def set_component(self, u):
109-
if self.m_components[u] == u:
136+
def set_component(self, node):
137+
if self.m_components[node] == node:
110138
return
111139
else:
112140
for k in self.m_components.keys():
113141
self.m_components[k] = self.find_component(k)
114142

143+
def union(self, component_size, node1, node2):
144+
if component_size[node1] <= component_size[node2]:
145+
self.m_components[node1] = node2
146+
component_size[node2] += component_size[node1]
115147

116-
117-
def union(self, component_size, u, v):
118-
if component_size[u] <= component_size[v]:
119-
self.m_components[u] = v
120-
component_size[v] += component_size[u]
121-
122-
elif component_size[u] >= component_size[v]:
123-
self.m_components[v] = self.find_component(u)
124-
component_size[u] += component_size[v]
148+
elif component_size[node1] >= component_size[node2]:
149+
self.m_components[node2] = self.find_component(node1)
150+
component_size[node1] += component_size[node2]
125151

126152
print(self.m_components)
127153

@@ -141,38 +167,38 @@ def boruvkas_mst(self):
141167
while num_of_components > 1:
142168
for i in range(len(self.m_graph)):
143169

144-
u = self.m_graph[i][0]
145-
v = self.m_graph[i][1]
146-
w = self.m_graph[i][2]
170+
node1 = self.m_graph[i][0]
171+
node2 = self.m_graph[i][1]
172+
weight = self.m_graph[i][2]
147173

148-
self.set_component(u)
149-
self.set_component(v)
174+
self.set_component(node1)
175+
self.set_component(node2)
150176

151-
u_component = self.m_components[u]
152-
v_component = self.m_components[v]
177+
node1_component = self.m_components[node1]
178+
node2_component = self.m_components[node2]
153179

154-
if u_component != v_component:
155-
if cheapest_edge[u_component] == -1 or cheapest_edge[u_component][2] > w:
156-
cheapest_edge[u_component] = [u, v, w]
157-
if cheapest_edge[v_component] == -1 or cheapest_edge[v_component][2] > w:
158-
cheapest_edge[v_component] = [u, v, w]
180+
if node1_component != node2_component:
181+
if cheapest_edge[node1_component] == -1 or cheapest_edge[node1_component][2] > weight:
182+
cheapest_edge[node1_component] = [node1, node2, weight]
183+
if cheapest_edge[node2_component] == -1 or cheapest_edge[node2_component][2] > weight:
184+
cheapest_edge[node2_component] = [node1, node2, weight]
159185

160186
for vertex in range(self.m_num_of_nodes):
161187
if cheapest_edge[vertex] != -1:
162-
u = cheapest_edge[vertex][0]
163-
v = cheapest_edge[vertex][1]
164-
w = cheapest_edge[vertex][2]
188+
node1 = cheapest_edge[vertex][0]
189+
node2 = cheapest_edge[vertex][1]
190+
weight = cheapest_edge[vertex][2]
165191

166-
self.set_component(u)
167-
self.set_component(v)
192+
self.set_component(node1)
193+
self.set_component(node2)
168194

169-
u_component = self.m_components[u]
170-
v_component = self.m_components[v]
195+
node1_component = self.m_components[node1]
196+
node2_component = self.m_components[node2]
171197

172-
if u_component != v_component:
173-
mst_weight += w
174-
self.union(component_size, u_component, v_component)
175-
print("Edge " + str(u) + " - " + str(v) + " with weight " + str(w) + " is included in MST.")
198+
if node1_component != node2_component:
199+
mst_weight += weight
200+
self.union(component_size, node1_component, node2_component)
201+
print("Edge " + str(node1) + " - " + str(node2) + " with weight " + str(weight) + " is included in MST.")
176202

177203
num_of_components -= 1
178204

@@ -186,25 +212,44 @@ def boruvkas_mst(self):
186212

187213

188214

189-
graph = Graph(5)
215+
# graph = Graph(5)
190216

191-
# graph.add_edge('1', 'A', 25)
217+
# graph.add_edge('A', 'A', 25)
192218
# graph.add_edge('A', 'B', 5)
193219
# graph.add_edge('A', 'C', 3)
194220
# graph.add_edge('B', 'D', 1)
195221
# graph.add_edge('B', 'E', 15)
196222
# graph.add_edge('E', 'C', 7)
197223
# graph.add_edge('E', 'D', 11)
198-
graph.add_edge(0, 0, 25)
199-
graph.add_edge(0, 1, 5)
200-
graph.add_edge(0, 2, 3)
201-
graph.add_edge(1, 3, 1)
202-
graph.add_edge(1, 4, 15)
203-
graph.add_edge(4, 2, 7)
204-
graph.add_edge(4, 3, 11)
205-
206-
print(graph)
207224

208-
graph.boruvkas_mst()
225+
# graph.add_edge(0, 0, 25)
226+
# graph.add_edge(0, 1, 5)
227+
# graph.add_edge(0, 2, 3)
228+
# graph.add_edge(1, 3, 1)
229+
# graph.add_edge(1, 4, 15)
230+
# graph.add_edge(4, 2, 7)
231+
# graph.add_edge(4, 3, 11)
232+
233+
graph = Graph(9)
234+
graph.add_edge("A", "B", 4)
235+
graph.add_edge("A", "C", 7)
236+
graph.add_edge("B", "C", 11)
237+
graph.add_edge("B", "D", 9)
238+
graph.add_edge("B", "F", 20)
239+
graph.add_edge("C", "F", 1)
240+
graph.add_edge("D", "G", 6)
241+
graph.add_edge("D", "E", 2)
242+
graph.add_edge("E", "G", 10)
243+
graph.add_edge("E", "I", 15)
244+
graph.add_edge("E", "H", 5)
245+
graph.add_edge("E", "F", 1)
246+
graph.add_edge("F", "H", 3)
247+
graph.add_edge("G", "I", 5)
248+
graph.add_edge("H", "I", 12)
249+
250+
251+
# print(graph)
252+
253+
graph.kruskals_mst()
209254

210255

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /