class Tree: def __init__(self, directed=False, weighted=False): self.directed = directed self.weighted = weighted self.tree = {} self.vertex_num = 0 self.vertex = [] self.components = UnionFind() def add_edge(self, origin, destiny, weight=0): def add_vertex(self, vertex): if not vertex in self.tree.keys(): self.components.add(vertex) self.tree[vertex] = {} self.vertex_num += 1 self.vertex.append(vertex) if not origin in self.tree.keys(): add_vertex(self, origin) if not destiny in self.tree.keys(): add_vertex(self, destiny) if self.components.connected(origin, destiny): raise Exception("Cannot add edge, would create a cicle") self.tree[origin][destiny] = weight if not self.directed: self.tree[destiny][origin] = weight self.components.union(origin, destiny)
def findCircleNum(self, M): """ :type M: List[List[int]] :rtype: int """ length =len(M) uf = UnionFind(length) for i in range(length): for j in range(i): if M[i][j] == 1: uf.add(i,j) return uf.componentsNum()
def test_union(self): u = UnionFind() foo = Node("foo") u.add(foo) bar = Node("bar") u.add(bar) self.assertEqual(foo, u.find(foo)) self.assertEqual(bar, u.find(bar)) u.union(foo, bar) self.assertEqual(bar, u.find(foo)) self.assertEqual(bar, u.find(bar))
def hammond_distances(file_path): file_stream = open(file_path) line_one = file_stream.readline().split(' ') count_edges, count_bits = int(line_one[0]), int(line_one[1]) uf = UnionFind([]) for i in range(count_edges): code = file_stream.readline() code = code.replace(' ', '').replace('\n', '') uf.add(code) update_singles(uf, code, count_bits) update_doubles(uf, code, count_bits) file_stream.close() clusters = set() for k in uf._node_titles.keys(): clusters.add(uf.find(k)) return len(clusters)
def cluster(edges, start_at): uf = UnionFind() sortede = sorted(edges, key=lambda x: x[3]) for k in range(1, 501): uf.add(k) for _, u, v, w in sortede: if len(list(uf.components())) == 4: break elif not uf.connected(u, v): uf.union(u, v) find_minimal(uf, edges)
def test_add_node(self): u = UnionFind() foo = Node("foo") bar = Node("bar") baz = Node("baz") u.add(foo) u.add(bar) u.add(baz) self.assertEqual(3, len(u.leader)) self.assertEqual(foo, u.leader[foo]) self.assertEqual(bar, u.leader[bar]) self.assertEqual(baz, u.leader[baz]) self.assertEqual(3, len(u.followers)) self.assertEqual(set(), u.followers[foo]) self.assertEqual(set(), u.followers[bar]) self.assertEqual(set(), u.followers[baz])
def cluster(nodes): uf = UnionFind() one_diff, two_diff = one_two_away() for v in nodes: uf.add(v) for vindex, v in enumerate(nodes): # squash all the nodes with distance 1 away into me od = [(v ^ i) for i in one_diff] td = [(v ^ i) for i in two_diff] for d in od + td: if d in nodes and not uf.connected(v, d): uf.union(v, d) print("smashed", v, d) print(len(list(uf.components())))
def cluster(vertices, radix): V = frozenset(vertices) u = UnionFind() for v in V: u.add(v) print "Starting with {} clusters".format(u.clusters) i = 0.0 for v in V: if i % 100 == 0: p = 100*( i / len(vertices)) sys.stdout.write("\r%f%% (%d)" % (p, len(V))) sys.stdout.flush() potential = hamming_neighbours(v, radix=radix, dist=2) for p in potential: if p in V: neighbour = p u.union(v, neighbour) i += 1 sys.stdout.write("\n") return u
def persistence(f): def mergeF(a, b): m, e = max((a['max'], a['elder']), (b['max'], b['elder'])) return {'max': m, 'elder': e} fi = sorted(list(zip(f, range(len(f)))), reverse=True) uf = UnionFind(mergeF) pairs = [] for v, i in fi: uf.add(i, {'max': v, 'elder': i}) if i - 1 in uf.V and i + 1 in uf.V: a = uf.getData(i - 1) b = uf.getData(i + 1) d, j = min((a['max'], a['elder']), (b['max'], b['elder'])) pairs.append((d - v, i, j)) if i - 1 in uf.V: uf.merge(i - 1, i) if i + 1 in uf.V: uf.merge(i, i + 1) pairs.append((float('inf'), None, fi[0][1])) return pairs
def cluster(graph, k): edges = heapify(graph.edges) u = UnionFind() [u.add(node) for node in graph.nodes.values()] while u.clusters > k: cost, edge = heappop(edges) if cycle(u, edge): #print "skipping {}".format(edge) pass else: u.union(u.find(edge.v0), u.find(edge.v1)) mindist = get_mindist(u, edges) return mindist, u.followers
class Map: # cities = {} # _loops = [] # _borders = [] # loops = UnionFind() # _print: bool = False def __init__(self, cities_data, data_limit: int = 0, print: bool = False): self.cities = {} self._loops = [] self._borders = [] self.loops = UnionFind() limit = data_limit self._print = print df = pd.read_csv(cities_data) upper = len(df) if limit != 0: upper = limit df = df[0:upper] for row in df.iterrows(): city = City(row[1].CityId, row[1].X, row[1].Y) self.cities[city.id] = city self._create_loops() def _create_loops(self): points = [] g_cities = nx.DiGraph() for city in self.cities: city = self.cities.get(city) g_cities.add_node('f-' + str(city.id), bipartite=0) g_cities.add_node('t-' + str(city.id), bipartite=1) points.append([city.x, city.y]) points = np.array(points) vor = Voronoi(points, incremental=True) for point in vor.ridge_points: self.cities[point[0]].add_neighbor(self.cities[point[1]]) self.cities[point[1]].add_neighbor(self.cities[point[0]]) g_cities.add_edge('f-' + str(self.cities[point[0]]), 't-' + str(self.cities[point[1]])) g_cities.add_edge('f-' + str(self.cities[point[1]]), 't-' + str(self.cities[point[0]])) temp = bipartite.maximum_matching(g_cities) print(temp) del g_cities islands = nx.DiGraph() i = 0 for key, value in temp.items(): # connect cities ... self.cities[int(key[2:])].connect_to(self.cities[int(value[2:])]) islands.add_edge(self.cities[int(key[2:])], self.cities[int(value[2:])]) i += 1 if (i >= temp.__len__() / 2): break for i, c in enumerate(nx.recursive_simple_cycles(islands)): # for i, c in enumerate(nx.simple_cycles(islands)): loop = Loop(c, i) self._loops.append(loop) self.loops.add(i) # plt.subplot(121) # nx.draw(islands, with_labels=True) # plt.savefig('temp_diagram.png') # plt.show() def loops_borders(self): temp_h = [] n = len(self.loops) for i in range(n): for j in range(i + 1, n): temp_h = self._loops[i].find_border(self._loops[j], temp_h) return temp_h def merge_loops(self): city_pairs = self.loops_borders() while (city_pairs.__len__() > 0): cp = hq.heappop(city_pairs) if (not (self.loops.connected(cp[1].loop_id, cp[2].loop_id))): # connect loops if (self.merge_node(cp[1], cp[2])): self.loops.union(cp[1].loop_id, cp[2].loop_id) def merge_node(self, c1: City, c2: City): p = c1 q = c2 if (self.is_revers(c1, c2)): p = c2 q = c1 self.connect(q.prev, p.next) self.connect(p, q) return True def connect(self, p: City, q: City) -> bool: p.next = q q.prev = p if (self._print): print(str(p.id) + ' --> ' + str(q.id)) def is_revers(self, c1: City, c2: City): dist_12 = c2.prev.sqr_dist_to(c1.next) dist_21 = c1.prev.sqr_dist_to(c2.next) return dist_12 > dist_21 def print_loops(self): print('loops ...') for loop in self._loops: print('------------') for vertex in loop.cities: print( str(loop.cities.get(vertex)) + '\tEnergy: ' + str(loop.cities.get(vertex).energy)) def print_path(self): current_city = self.cities[0] current_energy = 10 dist = 0 min_enrg = 10 while True: d = current_city.dist_to(current_city.next) if (min_enrg > current_energy): min_enrg = current_energy if (current_energy <= 0): d = d * 1.1 dist += d print(str(current_city.id)) # print(str(current_city.id)+'\tE: '+str(current_energy)) current_city = current_city.next if (current_city.next == self.cities[0]): print(current_city.id) break current_energy += -1 if (current_city.is_prime): current_energy = 10 print('Distance: ' + str(dist)) print('Minimum Energy:' + str(min_enrg)) def save_path(self, file_name: str = "myFile.csv"): f = open(file_name, "w") f.write('Path\n') current_city = self.cities[0] while True: f.write(str(current_city.id) + '\n') current_city = current_city.next if (current_city.next == self.cities[0]): f.write(str(current_city.id) + '\n') break f.write('0\n') def save_paths(self, file_name: str = "myFile.csv"): f = open(file_name, "w") f.write('Path\n') current_city = self.cities[0] current_energy = 10 dist = 0 min_enrg = 10 while True: d = current_city.dist_to(current_city.next) if (min_enrg > current_energy): min_enrg = current_energy if (current_energy <= 0): d = d * 1.1 dist += d f.write(str(current_city.id) + '\n') current_city = current_city.next if (current_city.next == self.cities[0]): f.write(str(current_city.id) + '\n') break current_energy += -1 if (current_city.is_prime): current_energy = 10 f.write('0\n') print('Distance: ' + str(dist)) return {'totalDist': dist, 'minEnergy': min_enrg}
def test_find(self): u = UnionFind() foo = Node("foo") u.add(foo) self.assertEqual(foo, u.find(foo))