|
6 | 6 | import inspect
|
7 | 7 | import math
|
8 | 8 |
|
9 |
| - |
10 | 9 | class Graph(object):
|
11 | 10 | """Graph object
|
12 | 11 | Creates the graph
|
@@ -37,56 +36,65 @@ def get_code(self):
|
37 | 36 | """
|
38 | 37 | return inspect.getsource(Graph)
|
39 | 38 |
|
40 |
| - |
41 | 39 | class WeightedGraph(object):
|
42 | 40 | """WeightedGraph object
|
43 | 41 | A graph with a numerical value (weight) on edges
|
44 | 42 | """
|
45 | 43 |
|
46 | 44 | def __init__(self):
|
47 |
| -self.edges_weighted = [] |
48 | 45 | self.vertexes = set()
|
49 |
| -self.forest = None |
| 46 | +self.graph = {} |
| 47 | +self._forest = None |
| 48 | + |
| 49 | +def get_weight(self, u, v): |
| 50 | +""" |
| 51 | +Returns the weight of an edge between vertexes u and v. |
| 52 | +If there isnt one: return None. |
| 53 | +""" |
| 54 | +return self.graph.get((u,v), self.graph.get((v,u), None)) |
| 55 | + |
50 | 56 |
|
51 | 57 | def add_edge(self, u, v, weight):
|
52 | 58 | """
|
53 | 59 | :param u: from vertex - type : integer
|
54 | 60 | :param v: to vertex - type : integer
|
55 | 61 | :param weight: weight of the edge - type : numeric
|
56 | 62 | """
|
57 |
| -edge = ((u, v), weight) |
58 |
| -self.edges_weighted.append(edge) |
59 |
| -self.vertexes.update((u, v)) |
| 63 | +if self.get_weight(u, v) != None: |
| 64 | +print("Such edge already exists!") |
| 65 | +else: |
| 66 | +self.vertexes.update((u, v)) |
| 67 | +self.graph[(u,v)] = weight |
60 | 68 |
|
61 | 69 | def print_graph(self):
|
62 | 70 | """
|
63 | 71 | Print the graph
|
64 | 72 | :return: None
|
65 | 73 | """
|
66 |
| -for (u, v), weight in self.edges_weighted: |
67 |
| -print("%d -> %d weight: %d" % (u, v, weight)) |
| 74 | +for (u, v) in self.graph: |
| 75 | +print("%d -> %d weight: %d" % (u, v, self.graph[(u, v)])) |
68 | 76 |
|
69 |
| -def __set_of(self, vertex): |
| 77 | +def _set_of(self, vertex): |
70 | 78 | """
|
71 | 79 | Helper method
|
72 | 80 | :param vertex:
|
73 | 81 | :return:
|
74 | 82 | """
|
75 |
| -for tree in self.forest: |
| 83 | +for tree in self._forest: |
76 | 84 | if vertex in tree:
|
77 | 85 | return tree
|
78 | 86 | return None
|
79 | 87 |
|
80 |
| -def __union(self, u_set, v_set): |
| 88 | +def _union(self, u_set, v_set): |
81 | 89 | """
|
82 | 90 | Helper method
|
83 | 91 | :param u_set:
|
84 | 92 | :param v_set:
|
85 | 93 | :return:
|
86 | 94 | """
|
87 |
| -self.forest.remove(u_set) |
88 |
| -self.forest.remove(v_set) |
89 |
| -self.forest.append(v_set + u_set) |
| 95 | +self._forest.remove(u_set) |
| 96 | +self._forest.remove(v_set) |
| 97 | +self._forest.append(v_set + u_set) |
90 | 98 |
|
91 | 99 | def kruskal_mst(self):
|
92 | 100 | """
|
@@ -96,14 +104,14 @@ def kruskal_mst(self):
|
96 | 104 | Author: Michele De Vita <[email protected]>
|
97 | 105 | """
|
98 | 106 | # sort by weight
|
99 |
| -self.edges_weighted.sort(key=lambda pair: pair[1]) |
| 107 | +self.graph = {k: self.graph[k] for k in sorted(self.graph, key=self.graph.get, reverse=False)} |
100 | 108 | edges_explored = []
|
101 |
| -self.forest = [[v] for v in self.vertexes] |
102 |
| -for (u, v), weight in self.edges_weighted: |
103 |
| -u_set, v_set = self.__set_of(u), self.__set_of(v) |
| 109 | +self._forest = [[v] for v in self.vertexes] |
| 110 | +for (u, v) in self.graph: |
| 111 | +u_set, v_set = self._set_of(u), self._set_of(v) |
104 | 112 | if u_set != v_set:
|
105 |
| -self.__union(u_set, v_set) |
106 |
| -edges_explored.append(((u, v), weight)) |
| 113 | +self._union(u_set, v_set) |
| 114 | +edges_explored.append(((u, v), self.graph[u, v])) |
107 | 115 | return edges_explored
|
108 | 116 |
|
109 | 117 | # TODO: Is this necessary?
|
|
0 commit comments