def upper_bound(G, k, H): ''' the upper bound of size of k-plex of H in G ''' # upper_bound_by_deg = min([nx.degree(G, node) for node in H]) + k # upper_bound_by_deg = 100 subg = nx.subgraph(G, H) validate_neighbors = {node for node in neighbors(G, H) if len(set(G.neighbors(node)).intersection(H)) >= len(H)+1-k} strict_nodes = [node for node in H if len(subg[node]) == len(H)-k] if len(strict_nodes) > 0: avaliable_nodes = {node for node in G.neighbors(strict_nodes[0]) if node not in H} for i in range(1, len(strict_nodes)): avaliable_nodes.intersection_update({node for node in G.neighbors(strict_nodes[i]) if node not in H}) avaliable_nodes.intersection_update(validate_neighbors) return len(H)+len(avaliable_nodes) else: min_d = float('inf') for node in H: nbrs = neighbors(G, [node]) nbrs.intersection_update(validate_neighbors) num_non_nbrs = k-1-(subg.number_of_nodes() - nx.degree(subg, node)) min_d = min(min_d, len(nbrs)+num_non_nbrs) return min_d
def cand_gen(G, k, a, c, cores=None): ''' generate all the branch given a k-plex a a: current k-plex c: the block ''' b = neighbors(G, a) b.difference_update(c) # the strict nodes subg = G.subgraph(a) strict_nodes = {node for node in a if nx.degree(subg, node) == len(a)-k } for node in strict_nodes: b.intersection_update(G.neighbors(node)) # always reshape by optimal if cores is None: b = {node for node in list(b) if nx.degree(G, node) >= len(optimal)-k} else: b = {node for node in list(b) if cores[node]>=len(optimal)-k} # calculate the valid candidates b = {node for node in b if len(set(G.neighbors(node)).intersection(a)) >= len(a)+1-k } # sort the candidate list b = list(b) # b.sort(key = lambda x: len(set(G.neighbors(x)).intersection(a)), reverse=True) return b