def __find_k_cliques(G, k): rcl = nx.find_cliques_recursive(G) k_cliques_list = [] while True: edge_list = [] try: clique_list = next(rcl) if len(clique_list) != k: continue else: for i in range(len(clique_list)): for j in range(i + 1, len(clique_list)): edge_list.append( G.has_edge(clique_list[i], clique_list[j])) edge_list.append( G.has_edge(clique_list[j], clique_list[i])) if all(has_edge is True for has_edge in edge_list): k_cliques_list.append(clique_list) except StopIteration: break if len(k_cliques_list) == 0: return None else: return k_cliques_list
def test_selfloops(self): self.G.add_edge(1,1) cl=list(nx.find_cliques(self.G)) rcl=nx.find_cliques_recursive(self.G) assert_equal(sorted(map(sorted,cl)), sorted(map(sorted,rcl))) assert_equal(cl, [[2, 6, 1, 3], [2, 6, 4], [5, 4, 7], [8, 9], [10, 11]])
def test_selfloops(self): self.G.add_edge(1, 1) cl = list(nx.find_cliques(self.G)) rcl = list(nx.find_cliques_recursive(self.G)) assert set(map(frozenset, cl)) == set(map(frozenset, rcl)) answer = [{2, 6, 1, 3}, {2, 6, 4}, {5, 4, 7}, {8, 9}, {10, 11}] assert len(answer) == len(cl) assert all(set(c) in answer for c in cl)
def local_standard_weight_clique_rank_filtration(G,IR_weight_cutoff=None,verbose=False): if IR_weight_cutoff==None: IR_weight_cutoff=np.min(nx.get_edge_attributes(G,'weight').values()); print('Preliminary scan of edge weights to define filtration steps...'); edge_weights=nx.get_edge_attributes(G,'weight'); weight_edge = {} for e,w in edge_weights.items(): if w not in weight_edge: weight_edge[w] = [] weight_edge[w].append(e); edge_weights=list(set(edge_weights.values())); edge_weights=sorted(edge_weights, reverse=True); max_index=len(edge_weights); # Define the clique dictionary Clique_dictionary={}; print('Constructing filtration...'); #Beginning of filtration construction G_supplementary=nx.Graph(); #the max index will be used for the persistent homology computation max_index=0; current_nodes = [] for index,thr in enumerate(edge_weights): new_nodes = []; if thr>=IR_weight_cutoff: G_supplementary.add_edges_from(weight_edge[thr]); [new_nodes.extend(edge) for edge in weight_edge[thr]]; new_nodes = list(set(new_nodes)); ## clique detection in partial graph, where there cliques are found only on the ## new nodes. relevant_nodes = [] [relevant_nodes.extend(G_supplementary.neighbors(n)) for n in new_nodes]; relevant_nodes = list(set(relevant_nodes)); G_supp_supp = nx.subgraph(G_supplementary,relevant_nodes); cliques=nx.find_cliques_recursive(G_supp_supp); # adding cliques to the filtration for clique in cliques: #loop on new clique clique.sort(); for k in range(1,len(clique)+1): #loop on clique dimension to find missed faces of simplex for subclique in itertools.combinations(clique,k): if str(list(subclique)) not in Clique_dictionary: Clique_dictionary[str(list(subclique))]=[]; Clique_dictionary[str(list(subclique))].append(str(index)); Clique_dictionary[str(list(subclique))].append(str(thr)) max_index=index; print('Max filtration value: '+str(max_index)); print('Clique dictionary created.'); return Clique_dictionary;
def _remove_clique_edges(networkx_graph): """ Return 3 vertex clique removed graph Parameters ---------- networkx_graph : Networkx graph graph to remove cliques from Returns ------- networkx_graph: Networkx graph graph with 3 vertex clique edges removed Notes ------ Removes the longest edge in a 3 Vertex cliques, Special case edges are the edges with equal lengths that form the 3 vertex clique. Doesn't deal with any other cliques """ start = time.time() cliques = nx.find_cliques_recursive(networkx_graph) # all the nodes/vertices of 3 cliques three_vertex_cliques = [clq for clq in cliques if len(clq) == 3] if len(list(three_vertex_cliques)) != 0: combination_edges = [list(itertools.combinations(clique, 2)) for clique in three_vertex_cliques] subgraph_edge_lengths = [] # different combination of edges in the cliques and their lengths for combinationEdge in combination_edges: subgraph_edge_lengths.append([np.sum((np.array(item[0]) - np.array(item[1])) ** 2) for item in combinationEdge]) clique_edges = [] # clique edges to be removed are collected here # the edges with maximum edge length for main_dim, item in enumerate(subgraph_edge_lengths): if len(set(item)) != 1: for sub_dim, length in enumerate(item): if length == max(item): clique_edges.append(combination_edges[main_dim][sub_dim]) else: special_case = combination_edges[main_dim] diff_of_edges = [] for num_spcl_edges in range(0, 3): source = list(special_case[num_spcl_edges][0]) target = list(special_case[num_spcl_edges][1]) diff_of_edges.append([i - j for i, j in zip(source, target)]) for index, val in enumerate(diff_of_edges): if val[0] == 0: sub_dim = index clique_edges.append(combination_edges[main_dim][sub_dim]) break networkx_graph.remove_edges_from(clique_edges) print("time taken to remove cliques is %0.2f seconds" % (time.time() - start)) return networkx_graph
def standard_weight_clique_rank_filtration(G, IR_weight_cutoff=None, verbose=False): if IR_weight_cutoff == None: ### MODIFIED TO WORK IN PYTHON 3! It has to be cast to a list IR_weight_cutoff = np.min( list(nx.get_edge_attributes(G, 'weight').values())) print('Preliminary scan of edge weights to define filtration steps...') edge_weights = list(nx.get_edge_attributes(G, 'weight').values()) edge_weights = list(set(edge_weights)) edge_weights = sorted(edge_weights, reverse=True) max_index = len(edge_weights) # Define the clique dictionary Clique_dictionary = {} print('Constructing filtration...') #Beginning of filtration construction G_supplementary = nx.Graph() #the max index will be used for the persistent homology computation max_index = 0 for index, thr in enumerate(edge_weights): if thr >= IR_weight_cutoff: #print "Index: "+str(index)+". IR_weight_cutoffeshold: "+str(IR_weight_cutoff); for edge in G.edges(data=True): if edge[2]['weight'] >= thr: G_supplementary.add_edge(edge[0], edge[1]) #clique detection in partial graph cliques = nx.find_cliques_recursive(G_supplementary) # adding cliques to the filtration for clique in cliques: #loop on new clique clique.sort() for k in range( 1, len(clique) + 1 ): #loop on clique dimension to find missed faces of simplex for subclique in itertools.combinations(clique, k): if str(list(subclique)) not in Clique_dictionary: Clique_dictionary[str(list(subclique))] = [] Clique_dictionary[str(list(subclique))].append( str(index)) Clique_dictionary[str(list(subclique))].append( str(thr)) max_index = index print(('Max filtration value: ' + str(max_index))) print('Clique dictionary created.') return Clique_dictionary
def _get_cliques_of_size(networkx_graph, clique_size): """ Return cliques of size "clique_size" in networkx_graph Parameters ---------- networkx_graph : Networkx graph graph to obtain cliques from Returns ------- list list of edges forming 3 vertex cliques """ cliques = nx.find_cliques_recursive(networkx_graph) # all the nodes/vertices of 3 cliques return [clique for clique in cliques if len(clique) == clique_size]
def standard_weight_clique_rank_filtration(G,IR_weight_cutoff=None,verbose=False): if verbose==True: print index, thr; if IR_weight_cutoff==None: IR_weight_cutoff=np.min(nx.get_edge_attributes(G,'weight')); print('Preliminary scan of edge weights to define filtration steps...'); edge_weights=nx.get_edge_attributes(G,'weight').values(); edge_weights=list(set(edge_weights)); edge_weights=sorted(edge_weights, reverse=True); max_index=len(edge_weights); # Define the clique dictionary Clique_dictionary={}; print('Constructing filtration...'); #Beginning of filtration construction G_supplementary=nx.Graph(); #the max index will be used for the persistent homology computation max_index=0; for index,thr in enumerate(edge_weights): if thr>=IR_weight_cutoff: #print "Index: "+str(index)+". IR_weight_cutoffeshold: "+str(IR_weight_cutoff); for edge in G.edges(data=True): if edge[2]['weight']>=thr: G_supplementary.add_edge(edge[0],edge[1]); #clique detection in partial graph cliques=nx.find_cliques_recursive(G_supplementary); # adding cliques to the filtration for clique in cliques: #loop on new clique clique.sort(); for k in range(1,len(clique)+1): #loop on clique dimension to find missed faces of simplex for subclique in itertools.combinations(clique,k): if str(list(subclique)) not in Clique_dictionary: Clique_dictionary[str(list(subclique))]=[]; Clique_dictionary[str(list(subclique))].append(str(index)); Clique_dictionary[str(list(subclique))].append(str(thr)) max_index=index; print('Max filtration value: '+str(max_index)); print('Clique dictionary created.'); return Clique_dictionary;
def upward_weight_clique_rank_filtration(G,UV_weight_cutoff=None,verbose=False): if UV_weight_cutoff==None: UV_weight_cutoff=np.max(nx.get_edge_attributes(G,'weight').values()); print('Preliminary scan of edge weights to define filtration steps...'); edge_weights=nx.get_edge_attributes(G,'weight').values(); edge_weights=list(set(edge_weights)); edge_weights=sorted(edge_weights); max_index=len(edge_weights); # Define the clique dictionary Clique_dictionary={}; print('Constructing filtration...'); #Beginning of filtration construction G_supplementary=nx.Graph(); #the max index will be used for the persistent homology computation max_index=0; for index,thr in enumerate(edge_weights): if verbose==True: print(index, thr) if thr<=UV_weight_cutoff: #print "Index: "+str(index)+". IR_weight_cutoffeshold: "+str(IR_weight_cutoff); for edge in G.edges(data=True): if edge[2]['weight']<=thr: G_supplementary.add_edge(edge[0],edge[1]); #clique detection in partial graph cliques=nx.find_cliques_recursive(G_supplementary); # adding cliques to the filtration for clique in cliques: #loop on new clique clique.sort(); for k in range(1,len(clique)+1): #loop on clique dimension to find missed faces of simplex for subclique in itertools.combinations(clique,k): if str(list(subclique)) not in Clique_dictionary: Clique_dictionary[str(list(subclique))]=[]; Clique_dictionary[str(list(subclique))].append(str(index)); Clique_dictionary[str(list(subclique))].append(str(thr)) max_index=index; print('Max filtration value: '+str(max_index)); print('Clique dictionary created.'); return Clique_dictionary;
def find_cliques(graph: networkx.Graph, logger=None) -> (networkx.Graph, list): """ :param graph: graph to which it is necessary to call the cliques for. :param logger: optional logger for the function Wrapper for the BronKerbosch algorithm, which returns the maximal cliques in the graph. It is the new interface for the BronKerbosch function, which is not called directly from outside this class any longer. The "inters" keyword provides the function used to determine whether two vertices are connected or not in the graph. """ if logger is None: logger = create_null_logger() logger.debug("Creating cliques for %s", logger.name) cliques = [frozenset(x) for x in networkx.find_cliques_recursive(graph)] logger.debug("Created %d cliques for %s", len(cliques), logger.name) return cliques
def test_find_cliques1(self): cl=list(nx.find_cliques(self.G)) rcl=nx.find_cliques_recursive(self.G) expected = [[2, 6, 1, 3], [2, 6, 4], [5, 4, 7], [8, 9], [10, 11]] assert_equal(sorted(map(sorted,cl)), sorted(map(sorted,rcl))) assert_equal(sorted(map(sorted,cl)), sorted(map(sorted, expected)))
del randi; #clique filtration and homology sys.path.append('../') import Holes as ho import imp betti_dict = {} for i in range(num_iter): randi = open(dir+dataset_tag+'_random%d.pck' %i,'r') G_rand = pk.load(randi) nx.write_edgelist(G_rand, dir+dataset_tag+'_random%d.edges' %i) G_rand=nx.read_edgelist(dir+dataset_tag+'_random%d.edges' %i,delimiter=' ',nodetype=float); #clique detection in partial graph cliques=nx.find_cliques_recursive(G_rand); Clique_dictionary = {} # adding cliques to the filtration for clique in cliques: #loop on new clique clique.sort(); for k in range(1,len(clique)+1): #loop on clique dimension # to find missed faces of simplex for subclique in itertools.combinations(clique,k): if str(list(subclique)) not in Clique_dictionary: Clique_dictionary[str(list(subclique))]=[]; Clique_dictionary[str(list(subclique))].append(str(1)); Clique_dictionary[str(list(subclique))].append(str(1)) # output of the filtration file in a hopefully matlab compliant form fname=dir+dataset_tag+'_random%d_clique_filtration.pck' %i
def get_clique(self): return nx.find_cliques_recursive(self.G)
def _remove_clique_edges(networkx_graph): """ Return 3 vertex clique removed graph Parameters ---------- networkx_graph : Networkx graph graph to remove cliques from Returns ------- networkx_graph: Networkx graph graph with 3 vertex clique edges removed Notes ------ Removes the longest edge in a 3 Vertex cliques, Special case edges are the edges with equal lengths that form the 3 vertex clique. Doesn't deal with any other cliques """ start = time.time() cliques = nx.find_cliques_recursive(networkx_graph) # all the nodes/vertices of 3 cliques three_vertex_cliques = [clq for clq in cliques if len(clq) == 3] if len(list(three_vertex_cliques)) != 0: combination_edges = [ list(itertools.combinations(clique, 2)) for clique in three_vertex_cliques ] subgraph_edge_lengths = [] # different combination of edges in the cliques and their lengths for combinationEdge in combination_edges: subgraph_edge_lengths.append([ np.sum((np.array(item[0]) - np.array(item[1]))**2) for item in combinationEdge ]) clique_edges = [] # clique edges to be removed are collected here # the edges with maximum edge length for main_dim, item in enumerate(subgraph_edge_lengths): if len(set(item)) != 1: for sub_dim, length in enumerate(item): if length == max(item): clique_edges.append( combination_edges[main_dim][sub_dim]) else: special_case = combination_edges[main_dim] diff_of_edges = [] for num_spcl_edges in range(0, 3): source = list(special_case[num_spcl_edges][0]) target = list(special_case[num_spcl_edges][1]) diff_of_edges.append( [i - j for i, j in zip(source, target)]) for index, val in enumerate(diff_of_edges): if val[0] == 0: sub_dim = index clique_edges.append( combination_edges[main_dim][sub_dim]) break networkx_graph.remove_edges_from(clique_edges) print("time taken to remove cliques is %0.2f seconds" % (time.time() - start)) return networkx_graph
def test_find_cliques1(self): cl=list(nx.find_cliques(self.G)) rcl=nx.find_cliques_recursive(self.G) assert_equal(sorted(map(sorted,cl)), sorted(map(sorted,rcl))) assert_equal(cl, [[2, 6, 1, 3], [2, 6, 4], [5, 4, 7], [8, 9], [10, 11]])
partition[p].append(labels[n]) return list(partition.values()) def pc(): import random Y=[random.randint(1,30) for x in range(10) ] print Y print distance.squareform(Y) Z=hierarchy.complete(Y) # Creates HC using farthest point linkage # This partition selection is arbitrary, for illustrive purposes print Z membership=list(hierarchy.fcluster(Z,1)) # Create collection of lists for blockmodel print 'membership',membership partition=defaultdict(list) for n,p in zip(list(range(10)),membership): partition[p].append(n) return list(partition.values()) if __name__=='__main__': g=nx.generators.small.krackhardt_kite_graph() nx.draw(g,with_labels = True,pos=nx.spring_layout(g)) r=nx.find_cliques_recursive(g) r=create_hc(g) print pc() plt.show()
def test_find_cliques1(self): cl = list(nx.find_cliques(self.G)) rcl = nx.find_cliques_recursive(self.G) expected = [[2, 6, 1, 3], [2, 6, 4], [5, 4, 7], [8, 9], [10, 11]] assert sorted(map(sorted, cl)) == sorted(map(sorted, rcl)) assert sorted(map(sorted, cl)) == sorted(map(sorted, expected))
original_graph=sys.argv[1]; dir=sys.argv[2]; dataset_tag = sys.argv[3]; else: print('Input is required as:\n 1) full edgelist filename \n 2) name of output directory \n 3) name tag for output files'); sys.exit(); if not os.path.exists(dir): os.makedirs(dir) G=nx.Graph(); G=nx.read_edgelist(original_graph,delimiter=' ',nodetype=float); cliques=nx.find_cliques_recursive(G); Clique_dictionary = {} # adding cliques to the filtration for clique in cliques: #loop on new clique clique.sort(); for k in range(1,len(clique)+1): #loop on clique dimension # to find missed faces of simplex for subclique in itertools.combinations(clique,k): if str(list(subclique)) not in Clique_dictionary: Clique_dictionary[str(list(subclique))]=[]; Clique_dictionary[str(list(subclique))].append(str(1)); Clique_dictionary[str(list(subclique))].append(str(1)) fname=dir+dataset_tag+'_clique_filtration.pck' filtration_file=open(fname,'w');
def reid_daid_hurley(graph, k, cliques=None, logger=None): """ Implementation of the Reid-Daid-Hurley algorithm for clique percolation published in http://arxiv.org/pdf/1205.0038.pdf :param graph: :type graph: networkx.Graph :param k: :param cliques: :param logger: optional logger for the function :return: """ if k < 2: raise networkx.NetworkXError("k=%d, k must be greater than 1." % k) if cliques is None: cliques = [ frozenset(x) for x in networkx.find_cliques_recursive(graph) ] if logger is None: logger = create_null_logger("null") nodes_to_clique_dict = defaultdict(set) # Create the dictionary that links each node to its clique logger.debug("Creating the node dictionary") cliques = [_ for _ in cliques if len(_) >= k] for clique in cliques: for node in clique: nodes_to_clique_dict[node].add(clique) if len(nodes_to_clique_dict) > 100 or len(cliques) > 500: logger.debug( "Complex locus at %s, with %d nodes and %d cliques with length >= %d", logger.name, len(nodes_to_clique_dict), len(cliques), k) current_component = 0 logger.debug("Starting to explore the clique graph") cliques_to_components_dict = dict() counter = 0 for clique in cliques: # visited = set() counter += 1 logger.debug("Exploring clique %d out of %d", counter, len(cliques)) if clique not in cliques_to_components_dict: current_component += 1 cliques_to_components_dict[clique] = current_component frontier = set() frontier.add(clique) cycle = 0 while len(frontier) > 0: current_clique = frontier.pop() # if current_clique in visited_cliques: # continue cycle += 1 logger.debug("Cycle %d for clique %d with %d nodes", cycle, counter, len(current_clique)) for neighbour in _get_unvisited_neighbours( current_clique, nodes_to_clique_dict): if len(frozenset.intersection(current_clique, neighbour)) >= (k - 1): cliques_to_components_dict[ neighbour] = current_component frontier.add(neighbour) for node in neighbour: nodes_to_clique_dict[node].remove(neighbour) logger.debug("Found %d neighbours of clique %d in cycle %d", len(frontier), counter, cycle) logger.debug("Finished exploring the clique graph") communities = dict() for clique in cliques_to_components_dict: if cliques_to_components_dict[clique] not in communities: communities[cliques_to_components_dict[clique]] = set() communities[cliques_to_components_dict[clique]].update(set(clique)) logger.debug("Reporting the results") result = [frozenset(x) for x in communities.values()] for element in set.difference(set(graph.nodes()), set(chain(*result[:]))): result.append(frozenset([element])) return set(result)
def reid_daid_hurley(graph, k, cliques=None, logger=None): """ Implementation of the Reid-Daid-Hurley algorithm for clique percolation published in http://arxiv.org/pdf/1205.0038.pdf :param graph: :type graph: networkx.Graph :param k: :param cliques: :param logger: optional logger for the function :return: """ if k < 2: raise networkx.NetworkXError("k=%d, k must be greater than 1." % k) if cliques is None: cliques = [frozenset(x) for x in networkx.find_cliques_recursive(graph)] if logger is None: logger = create_null_logger("null") nodes_to_clique_dict = defaultdict(set) # Create the dictionary that links each node to its clique logger.debug("Creating the node dictionary") cliques = [_ for _ in cliques if len(_) >= k] for clique in cliques: for node in clique: nodes_to_clique_dict[node].add(clique) if len(nodes_to_clique_dict) > 100 or len(cliques) > 500: logger.debug("Complex locus at %s, with %d nodes and %d cliques with length >= %d", logger.name, len(nodes_to_clique_dict), len(cliques), k) current_component = 0 logger.debug("Starting to explore the clique graph") cliques_to_components_dict = dict() counter = 0 for clique in cliques: # visited = set() counter += 1 logger.debug("Exploring clique %d out of %d", counter, len(cliques)) if clique not in cliques_to_components_dict: current_component += 1 cliques_to_components_dict[clique] = current_component frontier = set() frontier.add(clique) cycle = 0 while len(frontier) > 0: current_clique = frontier.pop() # if current_clique in visited_cliques: # continue cycle += 1 logger.debug("Cycle %d for clique %d with %d nodes", cycle, counter, len(current_clique)) for neighbour in _get_unvisited_neighbours(current_clique, nodes_to_clique_dict): if len(frozenset.intersection(current_clique, neighbour)) >= (k-1): cliques_to_components_dict[neighbour] = current_component frontier.add(neighbour) for node in neighbour: nodes_to_clique_dict[node].remove(neighbour) logger.debug("Found %d neighbours of clique %d in cycle %d", len(frontier), counter, cycle) logger.debug("Finished exploring the clique graph") communities = dict() for clique in cliques_to_components_dict: if cliques_to_components_dict[clique] not in communities: communities[cliques_to_components_dict[clique]] = set() communities[cliques_to_components_dict[clique]].update(set(clique)) logger.debug("Reporting the results") result = [frozenset(x) for x in communities.values()] for element in set.difference(set(graph.nodes()), set(chain(*result[:]))): result.append(frozenset([element])) return set(result)
#Beginning of filtration construction G_supplementary=nx.Graph(); max_index=0; #the max index will be used # for the persistent homology computation for index,thr in enumerate(edge_weights): if thr>IR_weight_cutoff: print "Index: "+str(index)+". Threshold: "+str(thr); for n,nbrs in G.adjacency_iter(): for nbr,eattr in nbrs.items(): data=eattr['weight'] if data>=thr: edge=[n,nbr]; edge.sort(); G_supplementary.add_edge(edge[0],edge[1]); #clique detection in partial graph cliques=nx.find_cliques_recursive(G_supplementary); # adding cliques to the filtration for clique in cliques: #loop on new clique clique.sort(); for k in range(1,len(clique)+1): #loop on clique dimension # to find missed faces of simplex for subclique in itertools.combinations(clique,k): if str(list(subclique)) not in Clique_dictionary: Clique_dictionary[str(list(subclique))]=[]; Clique_dictionary[str(list(subclique))].append(str(index)); Clique_dictionary[str(list(subclique))].append(str(thr)) max_index=index; del cliques