def MinimumSpanningTree(self): """ Return the minimum spanning tree of an undirected graph . self.graph should be represented in such a way that self.graph[u][v] gives the length of edge u,v, self.graph[u] should give the list of the neighbours, and self.graph[u][v] should always equal self.graph[v][u]. self.graph should be a dictionary where each key is a vertex in the graph and each value is a dictionary of destination:weight pairs The tree is returned as a list of edge tuples. Should adapt to use Numpy? """ # Kruskal's algorithm: sort edges by weight, and add them one at a time. # We use Kruskal's algorithm, first because it is very simple to # implement once UnionFind exists, and second, because the only slow # part (the sort) is sped up by being built in to Python. subtrees = UnionFind() tree = [] # edges are found on initialization self.edges.sort() #print self.edges for W,u,v in self.edges: if self.verbose: print subtrees if subtrees[u] != subtrees[v]: tree.append((u,v)) subtrees.union(u,v) self.m_s_tree = tree
def __init__(self, parent, pairs): """Set up to find LCAs of pairs in tree defined by parent. LCA of any given pair x,y can then be found by self[x][y]. However unlike the online LCA structure we can not find LCAs of pairs that are not supplied to us at startup time. """ # set up dictionary where answers get stored dict.__init__(self) for u, v in pairs: self.setdefault(u, {})[v] = self.setdefault(v, {})[u] = None # set up data structure for finding node ancestor on search path # self.descendants forms a collection of disjoint sets, # one set for the descendants of each search path node. # self.ancestors maps disjoint set ids to the ancestors themselves. self.descendants = UnionFind() self.ancestors = {} # invert the parent relationship so we can traverse the tree self.children = {} for x, px in parent.iteritems(): self.children.setdefault(px, []).append(x) root = [x for x in self.children if x not in parent] if len(root) != 1: raise ValueError("LCA input is not a tree") # initiate depth first traversal self.visited = Set() self.traverse(root[0])
def MinimumSpanningTree(graph, weights): """ Return the minimum spanning tree of an undirected graph G. G should be represented in such a way that iter(G) lists its vertices, iter(G[u]) lists the neighbors of u, G[u][v] gives the length of edge u,v, and G[u][v] should always equal G[v][u]. The tree is returned as a list of edges. """ if not isinstance(graph, UndirectedGraph): raise ValueError("Provided graph is not an UndirectedGraph.") for vertex in range(graph.n_vertices): for child in graph.adjacency_list[vertex]: if weights[vertex, child] != weights[child, vertex]: raise ValueError("Assymetric weights provided.") # Kruskal's algorithm: sort edges by weight, and add them one at a time. # We use Kruskal's algorithm, first because it is very simple to # implement once UnionFind exists, and second, because the only slow # part (the sort) is sped up by being built in to Python. subtrees = UnionFind() tree = [] for W, u, v in sorted((weights[u][v], u, v) for u in range(graph.n_vertices) for v in graph.adjacency_list[u]): if subtrees[u] != subtrees[v]: tree.append((u, v)) subtrees.union(u, v) return tree
def connectedComponentOutsidePermittedRegionBlacken(img, vstart, vend): labels = UnionFind() # pass 1 labeled = set() for currentPoint in iterImg(img): y, x = currentPoint if sum(img[y, x]) <= 100: # black continue labeled.add(currentPoint) neighbors = getSurrounding1(img, y, x) # if all 4 neighbors are black or unlabeled (ie, 0 labeled white neighbors), assign new label # if only 1 neighbor is white, assign its label to current point # if more than 1 of the neighbors are white, assign one of their labels to the current point, and note equivalence labeled_white_neighbors = [ neighbor for neighbor in neighbors if sum(img[neighbor]) > 100 and neighbor in labeled ] if len(labeled_white_neighbors) == 0: # assign new label z = labels[currentPoint] else: for neighbor in labeled_white_neighbors: labels.union(neighbor, currentPoint) # now blacklist all sets st they have a child that is in the forbidden region blacklist = set() for currentPoint in labeled: y, x = currentPoint if y < vstart or y > vend: blacklist.add(labels[currentPoint]) # pass 2 - blacken blacklisted components for currentPoint in labeled: y, x = currentPoint curset = labels[currentPoint] if curset in blacklist: img[y, x] = (0, 0, 0)
def merge_cliques(m_parameters, upper_bound, rand): """ Merge cliques """ dis_set = UnionFind() [dis_set[i] for i in range(m_parameters.num_maximal_cliques)] final_edges = [] # m_parameters.edges_list.sort(key=lambda e: -e[3]) while m_parameters.edges_list and m_parameters.num_edges < upper_bound: (a, b, sep, omega), index = rand.next_element(m_parameters.edges_list) # (a, b, sep, omega), index = m_parameters.edges_list[0], 0 del m_parameters.edges_list[index] i = dis_set[a] j = dis_set[b] edges_a = m_parameters.cardinality_array[i] - omega edges_b = m_parameters.cardinality_array[j] - omega if m_parameters.num_edges + (edges_a * edges_b) <= upper_bound: dis_set.union(a, b) m_parameters.cliques[i].update(m_parameters.cliques[j]) m_parameters.cardinality_array[i] = edges_b + edges_a + omega m_parameters.cliques[j] = set() m_parameters.cardinality_array[j] = 0 m_parameters.num_edges += edges_b * edges_a m_parameters.num_maximal_cliques -= 1 else: final_edges.append((a, b, sep, omega)) m_parameters.edges_list.extend(final_edges) for i, (start, end, sep, weight) in enumerate(m_parameters.edges_list): m_parameters.edges_list[i] = (dis_set[start], dis_set[end], sep, weight)
def compute(self): #subsetList = [SubSet(i,0) for i in xrange(self.V)] uf = UnionFind(self.V, self.E) for edge in self.graph: if self.checkCycle(uf,edge): self.mst.append(edge) uf.union(edge.src,edge.dest)
def MinimumSpanningTree(V,E,W): """ Return the minimum spanning tree of an undirected graph G=(V,E) with total its cost. W is a weights dictionary containing weight w of edge (u,v) as the dict entry W[(u,v)] = W[(v,u)] = w (W should be symmetric). The tree is returned as a list of edges. Notes: Kruskal's algorithm for minimum spanning Adpated from D. Eppstein' implementation (April 2006 version). """ from UnionFind import UnionFind # used for forests manipulation # Kruskal's algorithm: sort edges by weight, and add them one at a time. # We use Kruskal's algorithm, first because it is very simple to # implement once UnionFind exists, and second, because the only slow # part (the sort) is sped up by being built in to Python. subtrees = UnionFind() tree = [] #edges = [(G[u][v],u,v) for u in G for v in G[u]] edges = [(W[(u,v)],u,v) for (u,v) in E] edges.sort() cost = 0.0 for w,u,v in edges: if subtrees[u] != subtrees[v]: tree.append((u,v)) subtrees.union(u,v) cost+=w return (tree,cost)
def testFind(self): elements = [1,2,3,4,5,6,7] uf = UnionFind(elements) self.assertEqual(uf.find(1), 1) self.assertEqual(uf.find(6), 6) self.assertNotEqual(uf.find(7), 5)
def KruskalMST(graph:EdgeWeightedGraph): MST = [] EdgeSequence=[] UF = UnionFind(graph.numVertices()) #Pre-processing the edges PQ = [] for item in graph.adj: PQ += graph.adj[item] heapq.heapify(PQ) while (len(PQ)>0) & (len(MST) < graph.numVertices()-1): e = heapq.heappop(PQ) v = e.either() w = e.other(v) if (UF.connected(v,w)): continue else: UF.union(v,w) heapq.heappush(MST, e) EdgeSequence.append(e) cluster = set() for item in UF.id: cluster.add(item) print ("cluster:", cluster, len(cluster)) print (e.weight) return MST
def __getTree(self): # Sort edges by decreasing pheromone levels self.edgeInfos.sort(key=geteiPheromoneLevel, reverse=True) start = 0 # Current edges that will be inspected C = [] # Data structure for Kruskal's algorithm subtrees = UnionFind() solution = [] degrees = defaultdict(int) # Map of degrees for each vertice # While we don't have n-1 edges in our solution while len(solution) != self.n - 1: # Pick the the next nCanditates edges C = self.edgeInfos[start:start + self.nCandiates] # Sort the edge selection by increasing cost C.sort(key=geteiCost) start += self.nCandiates for ei in C: u, v = ei.u, ei.v # Test if edge can be added to the current solution if subtrees[u] != subtrees[v] and \ degrees[u] < self.d and degrees[v] < self.d: # Check constraint solution.append(ei) # Increment degrees of vertices of the added edge degrees[u] += 1 degrees[v] += 1 # Update subtrees subtrees.union(u, v) return solution
def test(self): uf = UnionFind() uf.union('alpha', 'bravo', 'charlie', 'delta') uf.consolidate(mysql_db, mysql_table, role='player', type='individual') for el in self._select_star(): self.assertSetEqual( set(['role', 'type', '_id', 'parent', 'weight']), set(el.keys())) self.assertEqual(el['role'], 'player') self.assertEqual(el['type'], 'individual') uf = UnionFind(mysql_db, mysql_table, 'mysql', role='player', type='organization') uf.union('adams', 'boston', 'chicago') for el in self._select_star(): if el['type'] == 'organization': self.assertIn(el['_id'], ['adams', 'boston', 'chicago']) elif el['type'] == 'individual': self.assertIn(el['_id'], ['alpha', 'bravo', 'charlie', 'delta']) else: raise self.failureException
def foodHeuristic(state, problem): position, foodGrid = state "*** YOUR CODE HERE ***" nodes = foodGrid.asList() nodes.append(position) G = {} for p1 in nodes: for p2 in nodes: dist1 = p1,p2 dist2 = p2,p1 if p1<p2: if dist1 in problem.heuristicInfo: dist = problem.heuristicInfo[dist1] elif dist2 in problem.heuristicInfo: dist = problem.heuristicInfo[dist2] else: dist = mazeDistanceAStar(p1, p2, problem.getStartingGameState()) #dist = manDistance(p1, p2) problem.heuristicInfo[p1,p2] = dist G[p1,p2] = G[p2,p1] = dist if p1 == p2: G[p1,p2] = 0 subtrees = UnionFind() edges = [(G[p1,p2],p1,p2) for p1 in nodes for p2 in nodes ] edges.sort() hDistance = 0 for W,u,v in edges: if subtrees[u] != subtrees[v]: hDistance += W subtrees.union(u,v) return hDistance
def get_connected_components(img): components = cc.get_connected_components(img) components = scale_components(components) connected = UnionFind() for comp1 in components: for comp2 in components: if overlaps(comp1, comp2): connected.union((comp1[0].start, comp1[0].stop, comp1[1].start, comp1[1].stop), (comp2[0].start, comp2[0].stop, comp2[1].start, comp2[1].stop)) connected_sets = {} for child, parent in connected.parents.iteritems(): if parent not in connected_sets: connected_sets[parent] = [] connected_sets[parent].append(child) connected_comps = [] for a, comps in connected_sets.iteritems(): min_y = min(comps, key=lambda item: item[0])[0] max_y = max(comps, key=lambda item: item[1])[1] min_x = min(comps, key=lambda item: item[2])[2] max_x = max(comps, key=lambda item: item[3])[3] connected_comps.append((slice(min_y, max_y), slice(min_x, max_x))) return connected_comps
def __getTree(self): # Sort edges by decreasing pheromone levels self.edgeInfos.sort(key=geteiPheromoneLevel, reverse=True) start = 0 # Current edges that will be inspected C = [] # Data structure for Kruskal's algorithm subtrees = UnionFind() solution = [] degrees = defaultdict(int) # Map of degrees for each vertice # While we don't have n-1 edges in our solution while len(solution) != self.n - 1: # Pick the the next nCanditates edges C = self.edgeInfos[start : start + self.nCandiates] # Sort the edge selection by increasing cost C.sort(key=geteiCost) start += self.nCandiates for ei in C: u, v = ei.u, ei.v # Test if edge can be added to the current solution if subtrees[u] != subtrees[v] and \ degrees[u] < self.d and degrees[v] < self.d: # Check constraint solution.append(ei) # Increment degrees of vertices of the added edge degrees[u] += 1 degrees[v] += 1 # Update subtrees subtrees.union(u, v) return solution
def kcluster(nodeset, edgeset, num_clusters, k):#WRONG """ Standard Algorithm """ #TODO: Validate Edgecase when k> len(nodeset) or len(edgeset) # Sort edgeset by Cost sorted_edges = sorted(edgeset, key=lambda x: x[2]) # Add each node to nodeset into UnionFind S uf = UnionFind() for node in nodeset: uf[node] # For each edge (u,v) in edgeset for edge in sorted_edges: #print 'Num Clusters {0}'.format(uf.size()) head, tail, wt = edge if num_clusters == k: print "STOP {0}".format(edge) max_crossing = wt return (uf , wt) if uf[head] != uf[tail]: uf.union(head, tail) num_clusters -=1 return (uf , wt)
def MinimumSpanningTree(G): """ Return the minimum spanning tree of an undirected graph G. G should be represented in such a way that iter(G) lists its vertices, iter(G[u]) lists the neighbors of u, G[u][v] gives the length of edge u,v, and G[u][v] should always equal G[v][u]. The tree is returned as a list of edges. """ if not isUndirected(G): raise ValueError("MinimumSpanningTree: input is not undirected") for u in G: for v in G[u]: if G[u][v] != G[v][u]: raise ValueError("MinimumSpanningTree: asymmetric weights") # Kruskal's algorithm: sort edges by weight, and add them one at a time. # We use Kruskal's algorithm, first because it is very simple to # implement once UnionFind exists, and second, because the only slow # part (the sort) is sped up by being built in to Python. subtrees = UnionFind() tree = [] for W, u, v in sorted((G[u][v], u, v) for u in G for v in G[u]): if subtrees[u] != subtrees[v]: tree.append((u, v)) subtrees.union(u, v) return tree
def approx(nodes, tracepoint_pipe: Pipe, solution_pipe: Pipe): start_time = time.process_time() # Get start time in seconds n = len(nodes) # Cache the number of nodes # Construct a list of edges sorted by cost edge_list = [] for i in range(n): for j in range(i + 1, n): # Construct an edge e = Edge(nodes[i], nodes[j]) bisect.insort(edge_list, e) m = len(edge_list) # Cache the number of edges union_find = UnionFind() for i in range(n): set = UnionFindSet(nodes[i]) union_find.add_set(set) solution = mst_approx(union_find, nodes, edge_list) solution_pipe.send(solution) tracepoint_pipe.send( Tracepoint(time.process_time() - start_time, solution.quality)) exit(0) # Exit the process
def connectedComponentOutsidePermittedRegionBlacken(img, vstart, vend): labels = UnionFind() # pass 1 labeled = set() for currentPoint in iterImg(img): y,x = currentPoint if sum(img[y,x]) <= 100: # black continue labeled.add(currentPoint) neighbors = getSurrounding1(img, y, x) # if all 4 neighbors are black or unlabeled (ie, 0 labeled white neighbors), assign new label # if only 1 neighbor is white, assign its label to current point # if more than 1 of the neighbors are white, assign one of their labels to the current point, and note equivalence labeled_white_neighbors = [neighbor for neighbor in neighbors if sum(img[neighbor]) > 100 and neighbor in labeled] if len(labeled_white_neighbors) == 0: # assign new label z = labels[currentPoint] else: for neighbor in labeled_white_neighbors: labels.union(neighbor, currentPoint) # now blacklist all sets st they have a child that is in the forbidden region blacklist = set() for currentPoint in labeled: y,x = currentPoint if y < vstart or y > vend: blacklist.add(labels[currentPoint]) # pass 2 - blacken blacklisted components for currentPoint in labeled: y,x = currentPoint curset = labels[currentPoint] if curset in blacklist: img[y,x] = (0,0,0)
class KruskalMST: def __init__(self, graph): self.graph = graph self.mst = [] self.minh = MinHeap() self.Uf = UnionFind(graph.V()) #将所有的边推入到最小堆中,由于是无向图,剔除掉重复的边,复杂度O(Elog(E)) for i in range(graph.V()): it = graph.adj(i) #由于是无向图,所以会有重复的边,用E.v() < E.w()来剔除另一半重复的边 for E in it: if E.v() < E.w(): self.minh.add(E) #当最小堆为空,或是所有的点都已经遍历完时,结束 #所有的边取出来且判断一下其是否形成环,复杂度,O(Elog(V)) while not self.minh.isEmpty() and len(self.mst) < self.graph.V(): minE = self.minh.extractMin() if not self.Uf.isConnected(minE.v(), minE.w()): self.mst.append(minE) self.Uf.union(minE.v(), minE.w()) def mstEdges(self): return self.mst def mstWeight(self): mstw = [] for E in self.mst: mstw.append(E.wt()) return mstw # 返回最小生成树的权值 def minWeight(self): mstw = self.mstWeight() return sum(mstw)
def test_getitem_returns_proper_root(self): union_find = UnionFind() union_find.union('parent', 'first_child') union_find.union('first_child', 'last_child') self.assertEqual(union_find['parent'], 'parent') self.assertEqual(union_find['first_child'], 'parent') self.assertEqual(union_find['last_child'], 'parent')
def read_nodes(filename): clusters = UnionFind() all_nodes = [] with open(filename) as inputfile: next(inputfile) for line in inputfile: clusters.make_set(int(line.rstrip().replace(' ', ''), 2)) all_nodes.append(int(line.rstrip().replace(' ', ''), 2)) return clusters, all_nodes
def __init__(self, width, threshold, k): self.width = width self.unionfind = UnionFind() self.signer = MinHashSignature(width) self.hasher = LSH(width, threshold) self.hashmaps = [ defaultdict(list) for _ in range(self.hasher.get_n_bands()) ] self.k = k
def __init__(self, file_list, file_path, error_path, id_list_file, save_path): self._id_list = np.array(pd.read_csv(id_list_file)['p_id']) self._file_list = file_list self._uf_set = UnionFind(self._id_list) self._file_path = file_path self._error_path = error_path self._error_id_list = [] self._save_path = save_path self._break_point = -1
def load_break_point(self, load_data, break_point): new_uf = UnionFind([key for key in data]) for key in load_data: for cor_id in load_data[key]: new_uf.union(key, cor_id) self._uf_set = new_uf self._break_point = break_point self._error_id_list = list(pd.read_csv(self._error_path + "/error_id_list.csv")['p_id'])
def _cargar_estructuras(self): self.uf_fuegos = UnionFind(len(self.focos)) for foco in self.focos: if foco.fecha not in self.dias: self.dias[foco.fecha] = list() #agrupo por dias self.dias[foco.fecha].append(foco) self.dias = self.dias.values() self.dias = sorted(self.dias, key=lambda dia: dia[0].fecha)
def kruskal(edges, num_vertex): uft = UnionFind(num_vertex) cost_sum = 0 # 最小全域木のコストの総和 edges = sorted(edges, key = lambda x: x[2]) for e in edges: if not uft.find(e[0], e[1]): uft.union(e[0], e[1]) cost_sum += e[2] return cost_sum
def Kruskal(Adj): subtree = UnionFind() tree = [] for e, u, v in sorted((Adj[u][v], u, v) for u in Adj for v in Adj[u]): for u in Adj: for v in Adj[u]: if subtree[u] != subtree[v]: tree.append((u, v)) subtree.union(u, v) print tree
def minimumSpanningTree(edges): subtrees = UnionFind() tree = [] for e in edges: if subtrees[e.v1] != subtrees[e.v2]: tree.append(e) subtrees.union(e.v1,e.v2) e.v1.degree += 1 e.v2.degree += 1 return tree
def max_spacing_k_clustering(G, V, k): ''' Apply a variant of Kruskal's MST algorithm to max-spacing k-clustering problems. Return the maximum spacing of k-clustering. G is a list which represents a graph. Each value of G, G[i], is a tuple (u,v,edge_cost) which represents two vertices of an edge and the cost of that edge. V is a list of vertices. k is the number of clusters. ''' # use Union-Find data structure to represent clusters unionfind=UnionFind() heap=[] # edges for u,v,cost in G: heappush(heap,(cost,u,v)) n=len(V) # number of vertices i=0 while i<n-k: # An MST has n-1 edges. Stops early by k-1 steps to produce a k-clustering. cost,u,v=heappop(heap) # pop the edge with least cost # check cycle. No cycles if either vertex has not be added to any cluster or they belong to different clusters. if unionfind.find(u) is None or unionfind.find(v) is None or unionfind.find(u)!=unionfind.find(v): # add the edge. unionfind.union(u,v) i+=1 # unionfind.getNumGroups() # in case that vertices of next edges has been added to the same cluster. while True: cost,u,v=heappop(heap) if unionfind.find(u) is None or unionfind.find(v) is None or unionfind.find(u)!=unionfind.find(v): return cost
def Kruskal(SetOfPoints, type): """Kruskal's Algorithm Sorts edges by weight, and adds them one at a time to the tree while avoiding cycles Takes any set of Point instances and converts to a dictionary via edge crawling Takes the dictionary and iterates through each level to discover neighbors and weights Takes list of point index pairs and converts to list of Lines then returns """ for i in xrange(0, len(SetOfPoints)): SetOfPoints[i].reset() for i in xrange(0, len(SetOfPoints)): for j in xrange(i, len(SetOfPoints)): if i != j: if type == "R": dist = (abs(SetOfPoints[i].x - SetOfPoints[j].x) + abs(SetOfPoints[i].y - SetOfPoints[j].y)) elif type == "G": dist = math.sqrt( pow((SetOfPoints[i].x - SetOfPoints[j].x), 2) + pow((SetOfPoints[i].y - SetOfPoints[j].y), 2)) else: "All of the Errors!" line = Line(SetOfPoints[i], SetOfPoints[j], dist) SetOfPoints[i].update(line) SetOfPoints[j].update(line) else: dist = 100000 line = Line(SetOfPoints[i], SetOfPoints[j], dist) SetOfPoints[i].update(line) G = {} for i in xrange(0, len(SetOfPoints)): off = 0 subset = {} for j in xrange(0, len(SetOfPoints[i].edges)): subset[j] = SetOfPoints[i].edges[j].w G[i] = subset subtrees = UnionFind() tree = [] for W, u, v in sorted((G[u][v], u, v) for u in G for v in G[u]): if subtrees[u] != subtrees[v]: tree.append([u, v]) subtrees.union(u, v) MST = [] for i in xrange(0, len(tree)): point1 = SetOfPoints[tree[i][0]] point2 = SetOfPoints[tree[i][1]] for j in xrange(0, len(point1.edges)): if point2 == point1.edges[j].getOther(point1).get(): point1.MSTupdate(point1.edges[j]) point2.MSTupdate(point1.edges[j]) MST.append(point1.edges[j]) return MST
def GetMinimumSpanningTree(graph): subtrees = UnionFind() spanningTree = WeightedGraph() sorted_weighted_edges_list = sorted([(u, v, graph[u][v]) for u in graph for v in graph[u]], key=lambda item: item[-1]) for u, v, w in sorted_weighted_edges_list: if subtrees[u] != subtrees[v]: spanningTree.AddEdge(u, v, w) subtrees.union(u, v) return spanningTree
def __init__(self, data): (nodes, self.bits) = map(int, data.pop(0).split()) self.uf = UnionFind() for n in range(nodes): self.uf.makeSet(n) # END for self.hammingData = defaultdict(list) for n in range(nodes): s = data[n].replace(' ', '') self.hammingData[s].append(n)
def testUnionNotIntegers(self): elements = ["bye", "a", "80", "cat"] uf = UnionFind(elements) uf.union("a", "80") uf.union("80", "cat") self.assertFalse(uf.find("bye") in set(["80", "a", "cat"])) self.assertTrue(uf.find("a") in set(["80", "a", "cat"])) self.assertTrue(uf.find("cat") in set(["80", "a", "cat"])) self.assertTrue(uf.find("80") in set(["80", "a", "cat"]))
def GetMinimumSpanningTree(graph): subtrees = UnionFind() spanningTree = WeightedGraph() sorted_weighted_edges_list = sorted( [(u, v, graph[u][v]) for u in graph for v in graph[u]], key=lambda item: item[-1] ) for u, v, w in sorted_weighted_edges_list: if subtrees[u] != subtrees[v]: spanningTree.AddEdge(u, v, w) subtrees.union(u, v) return spanningTree
def kruskalsMST(self): edges = self.sortedGraph uf = UnionFind() T = [] total_cost = 0 for cost,source,target in edges: s1,s2 = uf[source],uf[target] if s1 != s2 : uf.union(s1,s2) T.append((source,target)) total_cost += cost return total_cost
def MinimumSpanningTree(G): for u in G: for v in G[u]: if G[u][v] != G[v][u]: raise ValueError("MinimumSpanningTree: asymmetric weights") subtrees = UnionFind() tree = [] for W,u,v in sorted((G[u][v],u,v) for u in G for v in G[u]): if subtrees[u] != subtrees[v]: tree.append((u,v)) subtrees.union(u,v) return tree
def importGraph(filename = 'clustering2.txt'): """Imports pairs of endpoints into an adjancey list graph representation. Keep track of both edges and vertices.""" f = open(filename) (totalnodes, bits) = [int(x) for x in f.readline().split()] nodecount = 0 nodes = {} for line in f: nodes[nodecount] = [int(x) for x in line.split()] nodecount += 1 f.close() count = 0 buckets = {} # prep buckets for i in range(0, bits - 1): for j in range(i + 1, bits): buckets[(i, j)] = {} # print i, j count += 1 print count count = 0 for nkey, nval in nodes.items(): count += 1 if count % 1000 == 0: print count for i in range(0, bits - 1): for j in range(i + 1, bits): nvalminustwo = tuple(nval[0:i] + nval[i+ 1:j] + nval[j+1: bits]) if not buckets[(i, j)].has_key(nvalminustwo): buckets[(i, j)][nvalminustwo] = [nkey] else: buckets[(i, j)][nvalminustwo].append(nkey) uf = UnionFind() for n in xrange(len(nodes)): uf[n] count = 0 for key in buckets.keys(): for valkey in buckets[key]: count += 1 if count % 1000000 == 0: print count uf.union(*buckets[key][valkey]) return uf
class Kruskal: def __init__(self, data): nodes = int(data[0].split()[0]) self.ufSet = UnionFind() for n in range(nodes): self.ufSet.makeSet(n) # END for self.edges = [] for k in data[1:]: row = map(int, k.strip().split()) self.edges.append((row[0] - 1, row[1] - 1, row[2])) # END for self.edges.sort(key=itemgetter(2)) # END __init__ def mstKruskal(self): mst = [] l = 0 for edge in self.edges: s1 = self.ufSet.find(edge[0]) s2 = self.ufSet.find(edge[1]) if s1 == s2: continue # END if self.ufSet.union(edge[0], edge[1]) mst.append(edge) l += edge[2] # END for self.mst = mst return l # END mstKruskal def clusterKruskal(self, k): print "Running Clustering, k={0}".format(k) done = False for edge in self.edges: s1 = self.ufSet.find(edge[0]) s2 = self.ufSet.find(edge[1]) if s1 == s2: continue # END if if not done: self.ufSet.union(edge[0], edge[1]) else: print "Smallest unallocated edge: {0}".format(edge) return edge[2] # END if if self.ufSet.countGroups() == k: done = True
def k_means_clustering(k, num_nodes, edges): print edges U = UnionFind(num_nodes) X = [] cluster_count = num_nodes for everyedge in edges: p = everyedge[1] - 1 q = everyedge[2] - 1 if cluster_count == k: break if U.root(p) != U.root(q): X.append(everyedge) U.union(p, q) cluster_count = cluster_count - 1 print U i = 0 k_min_spacing = float('inf') while (i < len(edges)): w, p, q = edges[i] if U.root(p - 1) != U.root(q - 1): print p, q, w k_min_spacing = w if w < k_min_spacing else k_min_spacing i = i + 1 return k_min_spacing
def validTreeUF2(self, n, edges): """ :type n: int :type edges: List[List[int]] :rtype: bool """ # if len(edges) != n - 1: # return False uf = UnionFind(n) for i, j in edges: uf.union(i, j) print(uf.parent) return uf.group == 1
def __init__(self, data): nodes = int(data[0].split()[0]) self.ufSet = UnionFind() for n in range(nodes): self.ufSet.makeSet(n) # END for self.edges = [] for k in data[1:]: row = map(int, k.strip().split()) self.edges.append((row[0] - 1, row[1] - 1, row[2])) # END for self.edges.sort(key=itemgetter(2))
def Kruskal(SetOfPoints, type): for i in xrange(0, len(SetOfPoints)): SetOfPoints[i].reset() for i in xrange(0, len(SetOfPoints)): for j in xrange(i, len(SetOfPoints)): if i != j: if type == "R": dist = (abs(SetOfPoints[i].x - SetOfPoints[j].x) + abs(SetOfPoints[i].y - SetOfPoints[j].y)) elif type == "G": dist = math.sqrt( pow((SetOfPoints[i].x - SetOfPoints[j].x), 2) + pow((SetOfPoints[i].y - SetOfPoints[j].y), 2)) else: "All of the Errors!" line = Line(SetOfPoints[i], SetOfPoints[j], dist) SetOfPoints[i].update(line) SetOfPoints[j].update(line) else: dist = 100000 line = Line(SetOfPoints[i], SetOfPoints[j], dist) SetOfPoints[i].update(line) G = {} for i in xrange(0, len(SetOfPoints)): off = 0 subset = {} for j in xrange(0, len(SetOfPoints[i].edges)): subset[j] = SetOfPoints[i].edges[j].w G[i] = subset subtrees = UnionFind() tree = [] for W, u, v in sorted((G[u][v], u, v) for u in G for v in G[u]): if subtrees[u] != subtrees[v]: tree.append([u, v]) subtrees.union(u, v) MST = [] for i in xrange(0, len(tree)): point1 = SetOfPoints[tree[i][0]] point2 = SetOfPoints[tree[i][1]] for j in xrange(0, len(point1.edges)): if point2 == point1.edges[j].getOther(point1).get(): point1.MSTupdate(point1.edges[j]) point2.MSTupdate(point1.edges[j]) MST.append(point1.edges[j]) return MST
def init(arguments): # taille # contient la taille du plateau # plateau # plateau de jeu où l'on stocke le joueur (0, 1 ou 2) associé à chaque cellule # gs # socket connectée à l'autre joueur # monTour # booléen True ssi c'est à mon tour de jouer # numJoueur # contient mon numéro (1 ou 2) de joueur # uf # structure Union-Find pour déterminer les cellules connectées # couleurs # contient les couleurs utilisées sur le plateau de l'interface graphique hv.couleurs = ['white', 'red', 'blue'] if arguments["ip"] != None: # on est le client initClient(arguments) else: # on est le serveur initServeur(arguments) # initialisation du plateau et de la structure union-find # le plateau est un dictionnaire; il pourrait être un tableau hv.plateau = {} for i in range(hv.taille): for j in range(hv.taille): hv.plateau[i, j] = 0 hv.uf = UnionFind() hv.uf.union((1, "haut"), *[(-1, i) for i in range(hv.taille)]) hv.uf.union((1, "bas"), *[(hv.taille, i) for i in range(hv.taille)]) hv.uf.union((2, "haut"), *[(i, -1) for i in range(hv.taille)]) hv.uf.union((2, "bas"), *[(i, hv.taille) for i in range(hv.taille)]) # queue pour gérer les messages de fin de connexion entre thread Aurevoir.Messages = Queue() print("--- Initialisation terminée. La partie commence.")
def __init__(self,parent,pairs): """Set up to find LCAs of pairs in tree defined by parent. LCA of any given pair x,y can then be found by self[x][y]. However unlike the online LCA structure we can not find LCAs of pairs that are not supplied to us at startup time. """ # set up dictionary where answers get stored dict.__init__(self) for u,v in pairs: self.setdefault(u,{})[v] = self.setdefault(v,{})[u] = None # set up data structure for finding node ancestor on search path # self.descendants forms a collection of disjoint sets, # one set for the descendants of each search path node. # self.ancestors maps disjoint set ids to the ancestors themselves. self.descendants = UnionFind() self.ancestors = {} # invert the parent relationship so we can traverse the tree self.children = {} for x,px in parent.iteritems(): self.children.setdefault(px,[]).append(x) root = [x for x in self.children if x not in parent] if len(root) != 1: raise ValueError("LCA input is not a tree") # initiate depth first traversal self.visited = Set() self.traverse(root[0])
def run(self): L = self.L R = self.R percolates = False union = UF(L * L + 2) # bottom for i in range(1, L + 1): union.union(i, 0) # top for i in range(L * L - L + 1, L * L + 1): union.union(i, L * L + 1) particles = set() edges = set() while len(particles) != self.N: if percolates: break p = random.randrange(L, L * L - L) particles.add(p) current_vertice = self.g.vertex(p) self.vertices_color[current_vertice] = [0, 1, 0, 1] x, y = self._get_pos(p) for i in range(max(0, x - R), min(L, x + R + 1)): if percolates: break for j in range(max(0, y - R), min(L, y + R + 1)): if (i, j) == (x, y): continue if self._sqrdist((i, j), (x, y)) > R * R: continue if i <= x: from_, to_ = i * L + j, p else: from_, to_ = p, i * L + j if i * L + j in particles or i == 0 or i == L - 1: union.union(from_ + 1, to_ + 1) edges.add((from_, to_)) if union.connected(L * L + 1, 0): percolates = True for edge in edges: if union.connected(0, edge[0] + 1): current_edge = self.g.add_edge(self.vertices[edge[0]], self.vertices[edge[1]]) self.pen[current_edge] = 3 if percolates: self.edge_color[current_edge] = [0, 0, 1, 1] else: self.edge_color[current_edge] = [1, 0, 0, 1] if percolates: self.tests.append(len(particles)) return percolates
def kcluster2(nodeset,edgeset,num_clusters,k): #CORRECT sorted_edges = sorted(edgeset, key=lambda x: x[2]) # Add each node to nodeset into UnionFind S uf = UnionFind() for node in nodeset: uf[node] while num_clusters > k: head, tail, wt = sorted_edges.pop(0) while uf[head] == uf[tail]: head, tail, wt = sorted_edges.pop(0) uf.union(head, tail) num_clusters-=1 head, tail, wt = sorted_edges.pop(0) while uf[head] == uf[tail]: head, tail, wt = sorted_edges.pop(0) return head, tail, wt
class OfflineLCA(defaultdict): """Find LCAs of all pairs in a given sequence, using Union-Find.""" def __init__(self,parent,pairs): """Set up to find LCAs of pairs in tree defined by parent. LCA of any given pair x,y can then be found by self[x][y]. However unlike the online LCA structure we can not find LCAs of pairs that are not supplied to us at startup time. """ # set up dictionary where answers get stored defaultdict.__init__(self,dict) for u,v in pairs: self[u][v] = self[v][u] = None # set up data structure for finding node ancestor on search path # self.descendants forms a collection of disjoint sets, # one set for the descendants of each search path node. # self.ancestors maps disjoint set ids to the ancestors themselves. self.descendants = UnionFind() self.ancestors = {} # invert the parent relationship so we can traverse the tree self.children = defaultdict(list) for x,px in parent.items(): self.children[px].append(x) root = [x for x in self.children if x not in parent] if len(root) != 1: raise ValueError("LCA input is not a tree") # initiate depth first traversal self.visited = set() self.traverse(root[0]) def traverse(self,node): """Perform depth first traversal of tree.""" self.ancestors[self.descendants[node]] = node for child in self.children[node]: self.traverse(child) self.descendants.union(child,node) self.ancestors[self.descendants[node]] = node self.visited.add(node) for query in self[node]: if query in self.visited: lca = self.ancestors[self.descendants[query]] self[node][query] = self[query][node] = lca
class hamClusters : def __init__(self,file): self.file = file self.hamm=[0]*300 self.hamcode() self.points = [0]*pow(2,24) self.clusters = 0 self.index = {} self.uf = UnionFind() self.process_data() def spacing(self): for node in self.index.keys(): self.cluster_neighbors(node) return self.clusters def process_data(self): with open(self.file) as f: next(f) cluster=1 for line in f: curindex=int(line.replace(' ',''), base = 2) self.points[curindex] = cluster self.index[curindex] = True cluster += 1 self.clusters = len(self.index) print 'size=', self.clusters, len(self.points) def hamcode(self): #computing simple numbers k=0 for i in range(24): for j in range(i,24): mask=1 << i mask2 = 1 << j self.hamm[k]=mask|mask2 k=k+1 def cluster_neighbors(self,node): for i in self.hamm: if self.points[node^i] !=0: s1 = self.uf[node] s2 = self.uf[node^i] if s1 != s2: self.uf.union(s1,s2) self.clusters -= 1
def k_clustering(self): edges = self.sortedGraph uf = UnionFind() size = 500 cluster_size = 4 spacing = 0 for spacing,source,target in edges: s1,s2 = uf[source],uf[target] # enough clusters, return the spacing if size <= cluster_size: if s1 != s2: return spacing # if in different clsuters, join them reducing one cluster if s1 != s2 : uf.union(s1,s2) size -= 1 return spacing
def __init__(self,file): self.file = file self.hamm=[0]*300 self.hamcode() self.points = [0]*pow(2,24) self.clusters = 0 self.index = {} self.uf = UnionFind() self.process_data()
class UFGraphBasedSegment: def __init__(self, size, tau_k, root_dict): self.uf = UnionFind(size, root_dict) self.tau_k = tau_k ''' Merge two components. @param id1 : component id to merge @param id2 : component id to merge @param edge_value : difference value of intertested edge @return bool : TRUE if merging two components, else FALSE ''' def merge(self, id1, id2, edge_value): root_node1 = self.uf.get_root(id1) root_node2 = self.uf.get_root(id2) if edge_value < self.mint(root_node1, root_node2): self.uf.union(id1=id1, id2=id2, edge_value=edge_value) ''' Calculate the minimum internal difference between two components. @param id1 : One of two components to calculate minimum internal difference of boundary @param id2 : One of two components to calculate minimum internal difference of boundary @param mcl : Merged Component List @return float : minimum internal difference between two components ''' def mint(self, r1, r2): return min(r1.get_min_dif()+self.tau(r1), r2.get_min_dif()+self.tau(r2)) ''' Calculate threashold based on the size of the component. @param mc : merged component to calculate the threashold @return float : threashold based on the size of the component ''' def tau(self, root): return float(self.tau_k / root.get_size()) ''' Get union find. @return UnionFind : union find tree ''' def get_union_find(self): return self.uf
def __init__(self, N): self.uf = UnionFind() [self.uf[(n,m)] for n in range(N) for m in range(N)] self.grid = {(n,m):0 for n in range(N) for m in range(N)} self.N = N #setup virtual cells on top and bottom self.vtop = (-1,-1) self.grid[self.vtop] = 1 self.vbot = (self.N,self.N) self.grid[self.vbot] = 1
def kruskalMST(myGraph): T = [] #T is defined to be the empty set #2. For each vertex v of G, make the empty set out of v; edges = [] for v1 in range(0, len(myGraph)): for v2 in range(v1+1, len(myGraph)): newEdge = [v1, v2, distanceC2C(myGraph[v1], myGraph[v2])] edges.append(newEdge) edges = sorted(edges, key=getKey) #Sort edges in ascending order subtrees = UnionFind() for edge in edges: #For each edge from sorted list if (subtrees[edge[0]] != subtrees[edge[1]]): #If u and v belong to different sets T.append(edge) #Add edge to T subtrees.union(edge[0], edge[1]) #Get u and v in one single set return T
def MinimumSpanningTree(G): """ Return the minimum spanning tree of an undirected graph G. G should be represented in such a way that G[u][v] gives the length of edge u,v, and G[u][v] should always equal G[v][u]. The tree is returned as a list of edges. """ # Kruskal's algorithm: sort edges by weight, and add them one at a time. # We use Kruskal's algorithm, first because it is very simple to # implement once UnionFind exists, and second, because the only slow # part (the sort) is sped up by being built in to Python. subtrees = UnionFind() tree = [] edges = [(G[u][v],u,v) for u in G for v in G[u]] edges.sort() for W,u,v in edges: if subtrees[u] != subtrees[v]: tree.append((u,v)) subtrees.union(u,v) return tree
def krusal(nodeset, edgeset): # Sort edgeset by Cost edgelist=sorted(edgeset, key=lambda x:x[2]) # Add each node to nodeset into UnionFind S uf = UnionFind() for node in nodeset: uf[node] # Initialize T to empty set ([]) mst = set([]) # For each edge (u,v) in edgeset for edge in edgelist: head,tail,_ = edge # If u or v creates a cycle in T then continue (e.g. is S[u] == S[v]) if uf[head] != uf[tail]: # else Add (u,v) to T AND S.union(u, v). mst.add(edge) uf.union(head,tail) return mst
def connectedComponentLabel(img): labels = UnionFind() labeled = set() # pass 1 for surroundingPoints in iterImgSurrounding1(img): currentPoint = surroundingPoints[0] y,x = currentPoint if sum(img[y,x]) <= 100: # black continue labeled.add(currentPoint) neighbors = surroundingPoints[1:] # if all 4 neighbors are black or unlabeled (ie, 0 labeled white neighbors), assign new label # if only 1 neighbor is white, assign its label to current point # if more than 1 of the neighbors are white, assign one of their labels to the current point, and note equivalence labeled_white_neighbors = [neighbor for neighbor in neighbors if sum(img[neighbor]) > 100 and neighbor in labeled] if len(labeled_white_neighbors) == 0: # assign new label z = labels[currentPoint] else: label = labels[labeled_white_neighbors[0]] labels.union(label, currentPoint) for neighbor in labeled_white_neighbors[1:]: labels.union(label, neighbor) # pass 2 set_num = 1 set_to_num = {} outimg = CreateImage((img.width, img.height), 8, 3) for currentPoint in iterImg(img): y,x = currentPoint if sum(img[y,x]) <= 100: # black outimg[y,x] = (0,0,0) continue curset = labels[currentPoint] #print curset if curset not in set_to_num: set_to_num[curset] = encodeNumAsColor(set_num) set_num += 1 #print set_num outimg[y,x] = set_to_num[curset] return outimg
def kerger_UF(Edges,n): cut = 0 uf = UnionFind() random.shuffle(Edges) i = 0; # Populate the clusters of UF till there are 2 nodes left. while n > 2: e1,e2 = Edges[i] i += 1 s1 = uf[e1] s2 = uf[e2] if s1 != s2: uf.union(s1,s2) n -= 1 # Check for edges that cross the clusters, which are mincut edges for e1,e2 in Edges: s1 = uf[e1] s2 = uf[e2] if s1 != s2: cut += 1 return cut
def MinimumSpanningTree(prob,InputWords): """ Return the minimum spanning tree of an undirected graph G. G should be represented in such a way that G[u][v] gives the length of edge u,v, and G[u][v] should always equal G[v][u]. The tree is returned as a list of edges. """ # Kruskal's algorithm: sort edges by weight, and add them one at a time. # We use Kruskal's algorithm, first because it is very simple to # implement once UnionFind exists, and second, because the only slow # part (the sort) is sped up by being built in to Python. #print "MST" subtrees = UnionFind() dictionary = {} tree = [] edges = [(prob[InputWords.index(u)][InputWords.index(v)],u,v) for u in InputWords for v in InputWords] edges.sort() edges.reverse() for W,u,v in edges: if subtrees[u] != subtrees[v]: if u not in dictionary: tNode = TreeNode.TreeNode(u) dictionary[u] = tNode tNode.appendChild((v, W)) else: tNode = dictionary[u] tNode.appendChild((v,W)) if v not in dictionary: forParentNode = TreeNode.TreeNode(v) dictionary[v] = forParentNode forParentNode.appendParent((u, W)) else: forParentNode = dictionary[v] forParentNode.appendParent((u,W)) tree.append((u,v,W)) subtrees.union(u,v) return tree,dictionary