def _recursive_cutting(g, p, res=[]): """helper function (recursive version)""" k = math.ceil(len(g.nodes()) / p) g_l, g_r = kernighan_lin_bisection(g, weight="rate") for partition in g_l, g_r: if len(partition) > k: _recursive_cutting(g.subgraph(partition), p / 2, res) else: res.append(partition) return res
def partition(self,x_mat): num_samples=x_mat.shape[0] assert(x_mat.shape[1]==self.num_all_labels+1) # the last dim of x_mat gives the id of the label # the other dims give that row of the coocc matrix label_ids=x_mat[:,-1] assert(np.all(label_ids<self.num_all_labels)) adj_mat=x_mat[:,:-1][:,label_ids] # no self edges np.fill_diagonal(adj_mat,0) similarity_graph=nx.from_numpy_matrix(np.matrix(adj_mat)) [p1,p2]=kernighan_lin_bisection(similarity_graph, partition=None, max_iter=self.max_iter, weight='weight') partitions=[p1,p2] return partitions
def detect_communities(M): # Uses the Kernighan Lin bisection for # community detection nx_graph = get_undirected_nx_network(M) # Try out partitions of all sizes for size in range(1, len(M)): partition = get_initial_partition(size) partition = kernighan_lin_bisection(nx_graph, partition=partition, max_iter=100, weight='weight') print "------" print "Size:", size print "Size a:", len(partition[0]) print "Size b:", len(partition[1]) print sorted(partition[0]) print sorted(partition[1]) print convert_community_to_continent(partition[0]) print convert_community_to_continent(partition[1])
def _iterative_cutting(g, p): """helper function (iterative version)""" to_be_processed = [g] K = math.ceil(len(g.nodes()) / p) res = [] while len(to_be_processed) > 0: g = to_be_processed.pop() g_l, g_r = kernighan_lin_bisection(g, weight="rate") for partition in g_l, g_r: if len(partition) > K: to_be_processed.append(g.subgraph(partition)) else: res.append(partition) return res
def getRackOrganization(mySources): G_w = domainConfiguration.G.copy() weightGraph_(G_w, mySources) # racks_=asyn_lpa_communities(G, weight='weight') # print racks_ # k = domainConfiguration.REPLICATIONFACTOR -1 # comp = nx.girvan_newman(G_w) # limited = itertools.takewhile(lambda c: len(c) <= k, comp) # for communities in limited: # pass # print(tuple(sorted(c) for c in communities)) # racks_= kernighan_lin_bisection(G_w) # print racks_ racks_ = kernighan_lin_bisection(G_w, weight='weight') # print racks_ return racks_
def cluster(self, dgraph, weight=None): udgraph = super().to_undirected(dgraph.dgraph) A, B = kernighan_lin_bisection(udgraph, weight=weight) return [A, B]
def partition(virtual, algo="min_cut"): """Iterative min cut algorithm. Iteratively partitions the graph according to the chosen algorithm (either min cut or min bisection) until the size of the partition is under a certain threshold. """ class UnionFind: """Utility Class used by the MinCut algorithm.""" def __init__(self, nodes): self.parents = {u: u for u in nodes} self.ranks = {u: 0 for u in nodes} self.subsets = {u: {u} for u in nodes} def find(self, u): return u if self.parents[u] == u else self.find(self.parents[u]) def union(self, u, v): u_root, v_root = self.find(u), self.find(v) if self.ranks[u_root] < self.ranks[v_root]: self.parents[u_root] = v_root self.subsets[v_root] |= self.subsets[u_root] del self.subsets[u_root] elif self.ranks[u_root] > self.ranks[v_root]: self.parents[v_root] = u_root self.subsets[u_root] |= self.subsets[v_root] del self.subsets[v_root] else: self.parents[v_root] = u_root self.ranks[u_root] += 1 self.subsets[u_root] |= self.subsets[v_root] del self.subsets[v_root] def min_cut(g): """Return a min cut of g. The procedure is based on Karger's algorithm [1]. [1] D. Karger "Global Min-cuts in RNC and Other Ramifications of a Simple Mincut Algorithm". Proc. 4th Annual ACM-SIAM Symposium on Discrete Algorithms 1993. """ edges = [] weights = [] sum_rate = 0 for (u, v) in g.edges(): edges.append((u, v)) rate = g[u][v]["rate"] weights.append(rate) sum_rate += rate n_nodes = len(g.nodes()) uf = UnionFind(g.nodes()) sorted_edges = iter( np.random.choice( np.arange(len(edges)), size=len(edges), replace=False, p=np.array(weights) / sum_rate, )) while n_nodes > 2: u, v = edges[next(sorted_edges)] if uf.find(u) != uf.find(v): n_nodes -= 1 uf.union(u, v) return uf.subsets.values() to_be_processed = [set(virtual.nodes())] partitions = [] root = Node( frozenset(virtual.nodes()), cores=sum(virtual.req_cores(u) for u in virtual.nodes()), memory=sum(virtual.req_memory(u) for u in virtual.nodes()), ) t = Tree(root) # to keep track of the Node associated to each of the partitions partitions_nodes = {frozenset(virtual.nodes()): root} while to_be_processed: p = to_be_processed.pop() if len(p) <= 1: partitions.append(p) else: if algo == "min_cut": p1, p2 = min_cut(virtual.g.subgraph(p)) elif algo == "bisection": p1, p2 = kernighan_lin_bisection(virtual.g.subgraph(p), weight="rate") else: raise ValueError("undefined") # update tree parent = partitions_nodes[frozenset(p)] p1_node = Node( frozenset(p1), cores=sum(virtual.req_cores(u) for u in p1), memory=sum(virtual.req_memory(u) for u in p1), parent=parent, ) p2_node = Node( frozenset(p2), cores=sum(virtual.req_cores(u) for u in p2), memory=sum(virtual.req_memory(u) for u in p2), parent=parent, ) partitions_nodes[frozenset(p)].l = partitions_nodes[frozenset( p1)] = p1_node partitions_nodes[frozenset(p)].r = partitions_nodes[frozenset( p2)] = p2_node to_be_processed.append(p1) to_be_processed.append(p2) return t
wb = Workbook() sheet = wb.active list_performance = [] gg = [] n = 10 start_time_big = time.time() for i in range(0, 1000 + 1): v = n e = random.randint(v, 2 * v) G = nx.gnm_random_graph(v, e) start_time = time.time() kernighan_lin_bisection(G) end_time = time.time() list_performance.append((v, e, end_time - start_time)) gg.append(end_time - start_time) end_time_big = time.time() for row in list_performance: sheet.append(row) filepath = "/content/drive/My Drive/301_Project/" + str(v) + '_' + str(i) wb.save(filepath) t_val = t.ppf(0.95, i) mean = 0 for i in range(len(gg)): mean += gg[i]
def bisect(G): Gp = G.copy() Gp.remove_edges_from([(u, v) for u, v in G.edges() if G[u][v]["weight"] < 0]) partition = kernighan_lin_bisection(Gp) return partition