def kruskal(G) -> "list(namedetuple)": res = [] u = UnionFind() # initialise union-find DS for edge in iter(sorted(G.edges, key=lambda x: x.weight)): # go through all the edges and feed the nodes to the union method # if their roots are not same if u.isConnected(edge.node1, edge.node2): continue u.union(edge.node1, edge.node2) res.append(edge) return res
def kruskal(g): # Initialise la structure d'Union Find uf = UnionFind() # Initialise l'arbre de poids minimum associé à g A = MST(g) # Crée un ensemble singleton pour chaque sommet for node in g.get_nodes(): uf.make_set(node) # Trie les arêtes par poids croissant edges = g.get_edges() edges.sort(key=lambda e: e.get_weight()) # Pour chaque arête for edge in edges: start = edge.get_start() end = edge.get_end() # Si la référence de start et de end sont différent # aka. ils n'appartienent pas au même ensemble if uf.find(start) != uf.find(end): # Ajoute cette arête à arbre. Il n'est pas orienté, on le fait aussi pour son transposé A.add_edge(edge) # Union des 2 ensembles uf.union(start, end) return A
def __init__(self,ewg): self._mst = Queue() self._pq = MinPQ(ewg.edges()) self._uf = UnionFind(ewg.v+1) while not self._pq.isEmpty() and self._mst.size < ewg.v-1: #get minimum weighted ege on the PQ e = self._pq.dequeue() #get the first vertex v = e.either() #get the second w = e.other(v) if (self._uf.connected(v,w)): continue self._uf.union(v,w) self._mst.enqueue(e)
def clustersNeeded(nodes, bitLength): unionSet = UnionFind() unionSet.addNodes(nodes) for node in nodes: one_bit_difference = oneBitVaried(node, bitLength) for u in one_bit_difference: if u in nodes: unionSet.union(node, u) two_bit_difference = oneBitVaried(u, bitLength) for v in two_bit_difference: if v in nodes: unionSet.union(node, v) return unionSet.cardinality, unionSet
def __init__(self, girdNum): self.vtopIndex = girdNum * girdNum self.vbottomIndex = girdNum * girdNum + 1 self.girdNum = girdNum self.girdStat = self.__createGridBlocked(girdNum) # 2 virtual nodes for the convenience of checking the connection of top and bottom self.gird = UnionFind(girdNum * girdNum + 2) for i in range(girdNum): self.gird.union(self.vtopIndex, i) for i in range(girdNum * (girdNum - 1), girdNum * girdNum): self.gird.union(self.vbottomIndex, i)
def __init__(self, graph): self.__G = graph n = self.__G.V() self.__uf = UnionFind(self.__G.E() + n) self.__data = [] self.__mst = [] self.__pq = MiniHeap("weight") self.createMiniHeap(self.__pq) self.__mstWeight = 0 while (self.__pq.isEmpty() == False and len(self.__mst) < n): edge = self.__pq.extractMin() if (self.__uf.isConnected(edge.v(), edge.w())): continue else: #print "insert ,minedge===",edge.v(),edge.w(),edge.weight() self.__mst.append(edge) self.__uf.unionElements(edge.v(), edge.w()) for i in range(len(self.__mst)): self.__mstWeight += self.__mst[i].weight()
class KruskalMST: def __init__(self,ewg): self._mst = Queue() self._pq = MinPQ(ewg.edges()) self._uf = UnionFind(ewg.v+1) while not self._pq.isEmpty() and self._mst.size < ewg.v-1: #get minimum weighted ege on the PQ e = self._pq.dequeue() #get the first vertex v = e.either() #get the second w = e.other(v) if (self._uf.connected(v,w)): continue self._uf.union(v,w) self._mst.enqueue(e) def edges(self): return self._mst
class KruskalMST: def __init__(self, graph): self.__G = graph n = self.__G.V() self.__uf = UnionFind(self.__G.E() + n) self.__data = [] self.__mst = [] self.__pq = MiniHeap("weight") self.createMiniHeap(self.__pq) self.__mstWeight = 0 while (self.__pq.isEmpty() == False and len(self.__mst) < n): edge = self.__pq.extractMin() if (self.__uf.isConnected(edge.v(), edge.w())): continue else: #print "insert ,minedge===",edge.v(),edge.w(),edge.weight() self.__mst.append(edge) self.__uf.unionElements(edge.v(), edge.w()) for i in range(len(self.__mst)): self.__mstWeight += self.__mst[i].weight() def createMiniHeap(self, pq): n = self.__G.V() for i in range(n): adj = self.__G.adjIterator(self.__G, i) edge = adj.begin() while adj.end() == False: if edge.v() < edge.w(): pq.insert(edge) edge = adj.next() def mstEdges(self): return self.__mst def result(self): return self.__mstWeight
class Percolation: # construct a NxN grid to simulate the percolation system def __init__(self, girdNum): self.vtopIndex = girdNum * girdNum self.vbottomIndex = girdNum * girdNum + 1 self.girdNum = girdNum self.girdStat = self.__createGridBlocked(girdNum) # 2 virtual nodes for the convenience of checking the connection of top and bottom self.gird = UnionFind(girdNum * girdNum + 2) for i in range(girdNum): self.gird.union(self.vtopIndex, i) for i in range(girdNum * (girdNum - 1), girdNum * girdNum): self.gird.union(self.vbottomIndex, i) def open(self, row, column): self.girdStat[row][column] = 1 # check the nodes around if they are open. if yes, union with it for node in self.__getNodeListAround(row, column): if self.girdStat[node["row"]][node["column"]] == 1: self.gird.union( self.__getIndexFromGird(row, column), self.__getIndexFromGird(node["row"], node["column"]) ) def isOpen(self, row, column): return self.girdStat[row][column] == 1 def percolates(self): return self.gird.connected(self.vtopIndex, self.vbottomIndex) def __createGridBlocked(self, girdNum): gird = list() for i in range(girdNum): gird.append(list()) for j in range(girdNum): gird[i].append(0) return gird def __getIndexFromGird(self, row, column): return row * self.girdNum + column def __getNodeListAround(self, row, column): nodeList = list() nodeList.append({"row": row, "column": column - 1}) nodeList.append({"row": row, "column": column + 1}) nodeList.append({"row": row - 1, "column": column}) nodeList.append({"row": row + 1, "column": column}) for node in nodeList: if node["row"] < 0 or node["row"] >= self.girdNum or node["column"] < 0 or node["column"] >= self.girdNum: nodeList.remove(node) return nodeList
def max_spacing_kcluster(nodes, edges, k): unionSet = UnionFind() unionSet.addNodes(nodes) edges = sorted(edges, key=itemgetter(2)) i = 0 min_edge = None while not unionSet.cardinality < k: min_edge = edges[i] i += 1 u, v = min_edge[0], min_edge[1] x = unionSet.find(u) y = unionSet.find(v) if x != y: unionSet.union(x, y) return edges[i - 1][2]
def connectedComponentsUF(G): # works on both directed and undirected graphs u = UnionFind() # initialise union-find DS for edge in G.edges: # go through all the edges and feed the nodes to the union method u.union(edge.node1, edge.node2) for node in G.nodes: # go through all nodes and finalize the roots of all the remaining nodes u.find(node) # return the rootMap of the nodes return u.parentsMap
newseq = " ".join(newseq) output = output + [newseq] return output # crappy union thingy -- super slow # def union(a,b): # for key,value in clusters.items(): # if value == b: # clusters[key] = a ## with union find, doesnt quite work... comes out with a few too ## many sets for larger tests from unionFind import UnionFind l = lines4[1:] clusters = set(l) # starting clusters - removes copies from the input uf = UnionFind() for seq in l: uf.union(seq) # everyone in a singleton set for seq in uf: diffs = make1bitdiff(seq) for i in diffs: if i in uf: uf.union(i,seq) for seq in uf.parents.values(): diffs = make1bitdiff(seq) for i in diffs: if i in uf: uf.union(i,seq) ## Brute Force O(n^2)++ time, it works but is too slow to use for
def netCondenseRoutine(graphfile, alpha1, alpha2, edgeScore, timeScore): tempNetwork = TemporalNetwork(graphfile) print("netowrk size is : #node = " + str(tempNetwork.n) + " #time-stamp = " + str(tempNetwork.t)) superNodes = UnionFind(tempNetwork.n) isTimeMerge = True isNodeMerge = True if alpha1 == 0: isNodeMerge = False if alpha2 == 0: isTimeMerge = False timeIndex = 0 nodeIndex = 0 nodeScores = readScores(edgeScore) timeScores = readScores(timeScore) nodeMergeCount = 0 timeMergeCount = 0 isTimeActive = [1] * (tempNetwork.t + 1) print("start merging") while isNodeMerge or isTimeMerge: if (isTimeMerge and isNodeMerge and (nodeScores[nodeIndex][2] <= timeScores[timeIndex][2])) or ( isNodeMerge and not (isTimeMerge)): i = superNodes.find(nodeScores[nodeIndex][0]) j = superNodes.find(nodeScores[nodeIndex][1]) nodeIndex += 1 if (i == j): #print("Same Nodes : "+ str(i)+" and "+ str(j)) continue else: start = timer() superNodes.union(i, j) nodeRemain = superNodes.find(i) nodeOut = j if i == nodeRemain else i #print("remain is "+ str(nodeRemain)) #print("out is "+ str(nodeOut)) for timeStamp in range(1, tempNetwork.t + 1): if (isTimeActive[timeStamp] == 0): continue else: curGraph = tempNetwork.tempGraph[timeStamp] neighborsI = curGraph.neighbors(nodeRemain) neighborsJ = curGraph.neighbors(nodeOut) dic = {} for node in neighborsI: dic[node] = True curGraph[nodeRemain][node]['weight'] = ( curGraph[nodeRemain][node]['weight']) / (2.0) for node in neighborsJ: if node in dic: curGraph[nodeRemain][node]['weight'] = ( curGraph[nodeRemain][node]['weight'] * 2 + curGraph[nodeOut][node]['weight']) / (4.0) else: curGraph.add_edge( nodeRemain, node, weight=(curGraph[nodeOut][node]['weight']) / (2.0)) neighborsI = curGraph.predecessors(nodeRemain) neighborsJ = curGraph.predecessors(nodeOut) dic = {} for node in neighborsI: dic[node] = True curGraph[node][nodeRemain]['weight'] = ( curGraph[node][nodeRemain]['weight']) / (2.0) for node in neighborsJ: if node in dic: curGraph[node][nodeRemain]['weight'] = ( curGraph[node][nodeRemain]['weight'] * 2 + curGraph[node][nodeOut]['weight']) / (4.0) else: curGraph.add_edge( node, nodeRemain, weight=(curGraph[node][nodeOut]['weight']) / (2.0)) curGraph.remove_node(nodeOut) nodeMergeCount += 1 end = timer() print( str(nodeMergeCount) + "nodes merged : time elapsed " + str(end - start)) if (nodeMergeCount >= alpha1 * tempNetwork.n): isNodeMerge = False elif (isTimeMerge and isNodeMerge and (nodeScores[nodeIndex][2] > timeScores[timeIndex][2])) or ( not (isNodeMerge) and isTimeMerge): startT = timer() time1 = timeScores[timeIndex][0] time2 = timeScores[timeIndex][1] while (isTimeActive[time1] != 1): time1 -= 1 Graph1 = tempNetwork.tempGraph[time1] Graph2 = tempNetwork.tempGraph[time2] for edge in Graph1.edges(data=True): if Graph2.has_edge(edge[0], edge[1]): Graph1[edge[0]][edge[1]]['weight'] = ( Graph1[edge[0]][edge[1]]['weight'] + Graph2[edge[0]][edge[1]]['weight']) / 2.0 Graph2.remove_edge(edge[0], edge[1]) else: Graph1[edge[0]][edge[1]]['weight'] /= 2.0 for edge in Graph2.edges(data=True): Graph1.add_edge(edge[0], edge[1], weight=edge[2]['weight'] / 2.0) endT = timer() print('Mering time ' + str(time1) + ' and ' + str(time2) + ' ' + str(timeMergeCount) + "times merged : time elapsed " + str(endT - startT)) isTimeActive[time2] = 0 timeIndex += 1 timeMergeCount += 1 if (timeMergeCount >= alpha2 * tempNetwork.t): isTimeMerge = False superNodesFile = open(graphfile + "_superNodes", 'w') superNodesList = {} for i in range(1, (tempNetwork.n) + 1): sup = superNodes.find(i) if sup not in superNodesList: superNodesList[sup] = [i] else: superNodesList[sup].append(i) for sup in superNodesList: superNodesFile.write(str(sup) + ':\t') for i in superNodesList[sup]: superNodesFile.write(str(i) + ',\t') superNodesFile.write('\n') superNodesFile.close() outFile = open(graphfile + "_edgeList_final", 'w') for i in range(1, tempNetwork.t + 1): if (isTimeActive[i] == 1): curGraph = tempNetwork.tempGraph[i] for line in nx.generate_edgelist(curGraph, data=['weight']): outFile.write(str(i) + '\t' + line + "\n") outFile.close() return tempNetwork
vertexlist = [] for line in data[1:]: node = "".join([el for el in line if el is not " "])[:-1] vertexlist.append(node) return numberNodes, list(set(vertexlist)) numberNodes, vertexlist = graph() hastable = {} for i, ele in enumerate(vertexlist): hastable[ele] = i uf = UnionFind(len(vertexlist)) def generatecloseVertex(vertex): newVertices1 = [] newVertices2 = [] for i in range(len(vertex)): newVertex = (vertex[:i] + str(int(not (int(vertex[i])))) + vertex[i + 1:]) newVertices1.append(newVertex) for i in range(len(vertex) - 1): newVertex = (vertex[:i] + str(int(not (int(vertex[i])))) + vertex[i + 1:]) for j in range(i + 1, len(vertex)): newVertex2 = (newVertex[:j] + str(int(not (int(newVertex[j])))) +
def main(): with open("clustering1.txt", 'r') as f: data = f.readlines() numberNodes = int(data[0]) adjacencyList = [] for line in data[1:]: line = line.split() adjacencyList.append([int(line[0]), int(line[1]), int(line[2])]) adjacencyList = sorted(adjacencyList, key=itemgetter(2), reverse=False) return adjacencyList, numberNodes graph, numberNodes = main() uf = UnionFind(numberNodes) k = len(set(uf.leaders)) for i in graph: if k == 4 and not uf.find(i[0] - 1, i[1] - 1): maxspacing = i[2] print maxspacing break if k != 4 and not uf.find(i[0] - 1, i[1] - 1): uf.union(i[0] - 1, i[1] - 1) k = len(set(uf.leaders))