def max_spacing_k_clustering_big(graph_set): disjoint_set = DisjointSet.DisjointSet() # Create sets for node in list(graph_set): disjoint_set.makeSet(DisjointSet.Node(node)) # Merge distance 1 nodes for node in list(graph_set): candidates = hamming_distance_1_candidates(node) matches = candidates & graph_set for match in list(matches): n1 = disjoint_set.nodes[match] n2 = disjoint_set.nodes[node] disjoint_set.union(n1, n2) # Merge distance 2 nodes for node in list(graph_set): candidates = hamming_distance_2_candidates(node) matches = candidates & graph_set for match in list(matches): n1 = disjoint_set.nodes[match] n2 = disjoint_set.nodes[node] disjoint_set.union(n1, n2) return disjoint_set.connected_components
def solution(self, root, queries): self.queries = {} self.tree = self.bfs(root) for idx, query in enumerate(queries): if query[0] not in self.queries: self.queries[ query[0] ] = [] if query[1] not in self.queries: self.queries[ query[1] ] = [] self.queries[query[0]].append( (idx,query[1]) ) self.queries[query[1]].append( (idx,query[0]) ) self.result = { } self.dset = DisjointSet() self.lca(root) return self.result.values()
def solution(self, G): edges = [] for node in G.V.values(): for next, weight in node.neighbors: if next.x > node.x: edge = [node.x, next.x, weight] else: edge = [next.x, node.x, weight] edges.append(edge) edges = sorted(edges, cmp=lambda x, y: (x[0] - y[0]) * 100 + (x[1] - y[1]) * 10 + int(x[2] - y[2])) cleared = [edges[0]] prev = edges[0] for edge in edges: if prev == edge: continue else: prev = edge cleared.append(edge) dset = DisjointSet() for node in G.V.values(): dset.makeset(node.x) edges = sorted(cleared, key=lambda x: x[2]) tree = [] for edge in edges: u, v, weight = edge if not dset.findset(u).equals(dset.findset(v)): dset.union(u, v) tree.append(edge) return tree
def __accessVehicles(self): DJSet = DisjointSet.DisjointSet() vehicleThreshold = self.__getMinDistance() * 5 for i in range(self.centers.size // 2): for j in range(self.centers.size // 2): if i == j: continue diff = self.centers[j] - self.centers[i] if (diff[0]**2 + diff[1]**2)**0.5 < vehicleThreshold: DJSet.add(tuple(self.centers[i]), tuple(self.centers[j])) for leader in DJSet.group: if len(DJSet.group[leader]) < 5: continue frame = np.array([leader[0], leader[1], leader[0], leader[1]]) for member in DJSet.group[leader]: if member[0] < frame[0]: frame[0] = member[0] elif member[0] > frame[2]: frame[2] = member[0] if member[1] < frame[1]: frame[1] = member[1] elif member[1] > frame[3]: frame[3] = member[1] if frame[3] - frame[1] == 0 or frame[2] - frame[0] == 0: continue else: self.bufferVehicles.append(frame)
def gen_large_set_data(max_set_size=5, rows=8, cols=10): """Generate boards with larger tile sets that will score higher. Arguments: max_set_size (int): The maximum size of neighboring disjoint sets. If the max size changes randomly (and favors lower set sizes), the board will be more realistic. rows (int): The number of rows on the SuperBall board. cols (int): The number of cols on the SuperBall board. Returns: np.chararray: An array representing the different tile values. """ board = np.chararray((80), unicode=True) djSet = dj.DisjointSet(rows * cols) # Determine possible places for unions of sets randomly set_divisions = set() for r in range(rows - 1): for c in range(cols): cell_index = r * cols + c coin_flip = np.random.binomial(1, 0.5, 1)[0] if (coin_flip == 1): set_divisions.add(cell_index) for r in range(rows): for c in range(cols - 1): cell_index = (r * cols + c) + (rows * cols) coin_flip = np.random.binomial(1, 0.5, 1)[0] if (coin_flip == 1): set_divisions.add(cell_index) # Union the sets if both neighbors are less than max_set_size # TODO --> Change max_set_size randomly to get more realistic boards # TODO --> Probably favor lower set sizes with max_set_size for s in set_divisions: if (s < rows * cols): size1 = djSet.getSetSize(s) size2 = djSet.getSetSize(s + cols) if (size1 < max_set_size and size2 < max_set_size): djSet.union(s, s + cols) else: size1 = djSet.getSetSize(s - rows * cols) size2 = djSet.getSetSize(s - rows * cols + 1) if (size1 < max_set_size and size2 < max_set_size): djSet.union(s - rows * cols, s - rows * cols + 1) # Choose a color for each disjoint set and fill in board set_colors = {} for r in range(rows): for c in range(cols): index = r * cols + c setID = djSet.getSetID(index) if setID not in set_colors: tile_index = np.random.randint(len(tiles)) set_colors[setID] = tiles[tile_index] board[index] = set_colors[setID] return board
def max_spacing_k_clustering(graph, k): disjoint_set = DisjointSet.DisjointSet() # Create sets for edge in graph: disjoint_set.makeSet(DisjointSet.Node(edge[1])) disjoint_set.makeSet(DisjointSet.Node(edge[2])) # Union until there's k sets for edge in graph: distance = edge[0] n1 = disjoint_set.nodes[edge[1]] n2 = disjoint_set.nodes[edge[2]] disjoint_set.union(n1, n2) if disjoint_set.connected_components == k - 1: break return distance
def solution(self, G): edges = [] for node in G.V.values(): for next,weight in node.neighbors: if next.x > node.x: edge = [node.x, next.x, weight] else: edge = [next.x, node.x, weight] edges.append(edge) edges = sorted(edges, cmp = lambda x,y : (x[0] - y[0]) * 100 + (x[1]-y[1])*10 + int(x[2] - y[2])) cleared = [edges[0]] prev = edges[0] for edge in edges: if prev == edge: continue else: prev = edge cleared.append(edge) dset = DisjointSet() for node in G.V.values(): dset.makeset(node.x) edges = sorted(cleared, key= lambda x:x[2]) tree = [] for edge in edges: u, v, weight = edge if not dset.findset(u).equals( dset.findset(v) ): dset.union(u,v) tree.append( edge ) return tree
def get_mst_kruskal(self): disjoint_set = DisjointSet.DisjointSet(self.vertices) # sort edges by weight sorted_edges = sorted(graph.edges, key = lambda edge: self.edges[edge]) mst_edges = [] for edge in sorted_edges: if disjoint_set.unify(edge[0], edge[1]): mst_edges.append(edge) return mst_edges
def kruskalAlgo(self): i, e = 0, 0 ds = dst.DisjointSet(self.nodes) self.graph = sorted(self.graph, key=lambda item: item[2]) while e < self.V - 1: s, d, w = self.graph[i] i += 1 x = ds.find(s) y = ds.find(d) if x != y: e += 1 self.MST.append([s, d, w]) ds.union(x, y) self.printSol(s, d, w)
def kruskals(edges): edges.sort(key=lambda x: x[2]) # sort according to weight vertices = set() for e in edges: vertices.add(e[0]) vertices.add(e[1]) res, total_length = [], 0 # creating a disjoint set of all vertices dj = DS.DisjointSet(list(vertices)) for e in edges: if dj.union(e[0], e[1]): res.append((e[0], e[1])) total_length += e[2] return res, total_length
def FindNegativeCircle(G): ''' 有向图G 返回一个负圈 ''' V = G.V E = G.Adjlist #--------------------------------------------- #采用寻找圈方法 Ds = DisjointSet(V) for u in E.keys(): curList = E[u] curNode = curList.head while curNode!=0: v = curNode.data parentU = Ds.find(u) parentV = Ds.find(v) if parentU == parentV: #生成环,找v->u的所有路径的权重 findPath(v,u,V,E,curNode.weight) else: #在不同的树中,这条边不会产生环 Ds.union(parentU,parentV) curNode = curNode.next
def spanning_tree(nodes, edges, randstream): """Given a list of edges, calculate a minimal spanning tree out of them.""" num_nodes = len(nodes) tree = [] partitions = DisjointSet() for i in range(num_nodes): # create a disjoint set where each node is a singleton partition partitions.add(i) for edge in edges: a, b = edge if partitions.find(a) != partitions.find(b): # partitions were unconnected: bridge them together tree.append(edge) partitions.union(a, b) if len(tree) == num_nodes - 1: # minimal spanning tree acquired break return tree
class C21_3_OfflineLCA(BaseSolution): def __init__(self): BaseSolution.__init__(self) self.push_test( params = (TreeNode.deserialize("{1,2,3,4,5,6,7}"), [[5,4],[4,6], [5,3],[4,2]],), expects = [2,1,1,2] ) self.push_test( params = (TreeNode.deserialize("{1,2,3,4,5,6,7,#,#,8,9,#,#,10,#,#,11,12,#,13,14}"), [[1,4],[2,3],[5,6],[11,12],[12,7],[6,14]],), expects = [1,1,1,5,1,3] ) def solution(self, root, queries): self.queries = {} self.tree = self.bfs(root) for idx, query in enumerate(queries): if query[0] not in self.queries: self.queries[ query[0] ] = [] if query[1] not in self.queries: self.queries[ query[1] ] = [] self.queries[query[0]].append( (idx,query[1]) ) self.queries[query[1]].append( (idx,query[0]) ) self.result = { } self.dset = DisjointSet() self.lca(root) return self.result.values() def bfs(self,root): tree = {} queue = [root] while len(queue) > 0: top = queue.pop(0) if not top: continue tree[top.val] = top if top.left: queue.append(top.left) if top.right: queue.append(top.right) return tree def lca(self,root): u = self.dset.makeset( root.val ) self.dset.findset(root.val).ancestor = u for node in (root.left, root.right): if not node: continue self.lca(node) self.dset.union( root.val, node.val) self.dset.findset(root.val).ancestor = u root.state = 2 if root.val in self.queries: for idx,other in self.queries[ root.val ]: if self.tree[other].state == 2: self.result[idx] = self.dset.findset( other ).ancestor.val
def spanning_tree(nodes, edges, randstream): """Given a list of edges, calculate a minimal spanning tree out of them.""" num_nodes = len(nodes) tree = [] partitions = DisjointSet() for i in range(num_nodes): # create a disjoint set where each node is a singleton partition partitions.add(i) for edge in edges: a, b = edge if partitions.find(a) != partitions.find(b): # partitions were unconnected: bridge them together tree.append(edge) partitions.union(a, b) if len(tree) == num_nodes-1: # minimal spanning tree acquired break return tree
def getDJSet(self): djSet = DisjointSet.DisjointSet(self.numTiles) # union vertically for r in range(1, self.numRows): for c in range(0, self.numCols): index = r * self.numCols + c upIndex = (r - 1) * self.numCols + c if (self.board[index] == self.board[upIndex]): djSet.union(index, upIndex) # union horizontally for c in range(1, self.numCols): for r in range(0, self.numRows): index = r * self.numCols + c leftIndex = index - 1 if (self.board[index] == self.board[leftIndex]): djSet.union(index, leftIndex) return djSet
def single_linkage_union(tree,threshold,support): leaves = prep(tree,support) clusters = list() # find closest leaf below (dist,leaf) for node in tree.traverse_postorder(): if node.is_leaf(): node.min_below = (0,node.label) else: node.min_below = min((c.min_below[0]+c.edge_length,c.min_below[1]) for c in node.children) # find closest leaf above (dist,leaf) for node in tree.traverse_preorder(): node.min_above = (float('inf'),None) if node.is_root(): continue # min distance through sibling for c in node.parent.children: if c != node: dist = node.edge_length + c.edge_length + c.min_below[0] if dist < node.min_above[0]: node.min_above = (dist,c.min_below[1]) # min distance through grandparent if not c.parent.is_root(): dist = node.edge_length + node.parent.min_above[0] if dist < node.min_above[0]: node.min_above = (dist,node.parent.min_above[1]) # set up Disjoint Set ds = DisjointSet(leaves) for node in tree.traverse_preorder(leaves=False): # children to min above for c in node.children: if c.min_below[0] + c.edge_length + node.min_above[0] <= threshold: ds.union(c.min_below[1], node.min_above[1]) for i in range(len(node.children)-1): c1 = node.children[i] for j in range(i+1, len(node.children)): c2 = node.children[j] if c1.min_below[0] + c1.edge_length + c2.min_below[0] + c2.edge_length <= threshold: ds.union(c1.min_below[1], c2.min_below[1]) return [list(s) for s in ds.sets()]
def main(): ds = DisjointSet(1, 2, 3, 'a', 'b', 'c') print(ds) ds.connect(1, 'b') print(ds) ds.connect('b', 'c') print(ds) ds.connect(2, 3) ds.connect('a', 2) ds.connect('a', 'c') print(ds) print(ds.isConnected('c', 2))
def analyze_board(board, goals=default_goals, nRows=8, nCols=10, mss=5): score_pos = (-1, -1) djSet = DisjointSet.DisjointSet(nRows * nCols) for row in range(1, nRows): for col in range(0, nCols): index = row * nCols + col up_index = (row - 1) * nCols + col if (board[index] == board[up_index]): setID1 = djSet.getSetID(index) setID2 = djSet.getSetID(up_index) if (setID1 != setID2): djSet.union(index, up_index) for row in range(0, nRows): for col in range(1, nCols): index = row * nCols + col left_index = row * nCols + (col - 1) if (board[index] == board[left_index]): setID1 = djSet.getSetID(index) setID2 = djSet.getSetID(left_index) if (setID1 != setID2): djSet.union(index, left_index) scoringSets = {} nearScoringSets = {} nonScoringSets = {} for row in range(0, nRows): for col in range(0, nCols): index = row * nCols + col s = {} s['setID'] = djSet.getSetID(index) s['size'] = djSet.getSetSize(index) s['color'] = board[index] s['rootRow'] = row s['rootCol'] = col # Goal cells if (goals[index] and s['size'] >= mss): scoringSets[s['setID']] = s elif (goals[index] and s['size'] >= 3): nearScoringSets[s['setID']] = s else: nonScoringSets[s['setID']] = s score = 0 maxSize = 0 numSets = 0 numScorableTiles = 0 scoringSetScore = 0 nearScoringSetScore = 0 nonScoringSetScore = 0 adjacencyScore = 0 positioningScore = 0 for s in scoringSets: size = scoringSets[s]['size'] rootRow = scoringSets[s]['rootRow'] rootCol = scoringSets[s]['rootCol'] scoringSetScore += pow(size, 2) numScorableTiles += size if (size > maxSize): maxSize = size score_pos = (rootRow, rootCol) for s in nearScoringSets: nearScoringSetScore += pow(nearScoringSets[s]['size'], 2) for s in nonScoringSets: nonScoringSetScore += pow(nonScoringSets[s]['size'], 2) # Ignore adjacency score and positioning score for now numSets = len(scoringSets) score = (numSets + numScorableTiles / 3) * 8000 \ + (scoringSetScore * 1.3 + nearScoringSetScore * 1.3 + nonScoringSetScore * 1.1) * 100 \ + (adjacencyScore * 20 + positioningScore) * 10 return score, score_pos
from DisjointSet import * print("Criando o conjunto com subconjuntos disjuntos") myDS = DisjointSet() print("Criando uns subconjuntos") for i in range(5): myDS.makeset(i) print("Printando os conjuntos") myDS.print() print("Unindo R conjuntos 1 e 2") myDS.uniaoR(1, 2) myDS.print() print("Unindo R conjuntos 1 e 3") myDS.uniaoR(1, 3) myDS.print() print("Unindo R conjuntos 0 e 1") myDS.uniaoR(0, 1) myDS.print() print("Retornando o representante dos elementos") for i in range(5): print(str(i) + "-->" + str(myDS.find(i))) print("Verificando se 1 e 2 fazem parte do mesmo conjunto") print(myDS.mesmo(1, 2)) print("Verificando se 1 e 4 fazem parte do mesmo conjunto") print(myDS.mesmo(1, 4)) print("União E de 1 e 4") myDS.print() myDS.uniaoE(1, 4) myDS.print()