### deconvolution start for small instances ok

parent ff1c07d8
 ... @@ -2,8 +2,7 @@ ... @@ -2,8 +2,7 @@ import sys import sys import networkx as nx import networkx as nx import itertools import sys ... @@ -13,7 +12,25 @@ def deconvolve(G,node): ... @@ -13,7 +12,25 @@ def deconvolve(G,node): # Extract neighbors from the graph # Extract neighbors from the graph G_neighbors = nx.Graph(G.subgraph(neighbors)) G_neighbors = nx.Graph(G.subgraph(neighbors)) get_communities(G_neighbors) communities = get_communities(G_neighbors) # Continue only if something need to be splited. if len(communities) == 1: return # Split communities for idx, community in enumerate(communities): # Add community center node_name = f"{node}_{idx}" G.add_node(node_name) # Add links from the center to the community for neighbor in community: G.add_edge(node_name, neighbor) # Remove old node G.remove_node(node) print("splitted into", len(communities), "parts\n") def get_communities(G): def get_communities(G): ... @@ -41,9 +58,18 @@ def get_communities(G): ... @@ -41,9 +58,18 @@ def get_communities(G): d_graph = compute_d_graph(clq1, clq2, G) d_graph = compute_d_graph(clq1, clq2, G) if d_graph != None: if d_graph != None: candidate_d_graphs.append(d_graph) candidate_d_graphs.append(d_graph) # print(clq1, clq2, is_d_graph(clq1, clq2, G)) # Extract communites from all the possible d-graphes in the neighborood. # Extract communites from all the possible d-graphes in the neighborood. # This is a minimal covering d_graph algorithm. minimal_d_graphes = filter_d_graphs(candidate_d_graphs) # If no community detected, return one big. if len(minimal_d_graphes) == 0: return [list(G.nodes())] # TODO : !!! Concatenation not possible if the same node can be in both side communites = [d_graph+d_graph for d_graph in minimal_d_graphes] return communites """ This function take two cliques in the graph G and try to find if they are 2 halfes of a d-graph. """ This function take two cliques in the graph G and try to find if they are 2 halfes of a d-graph. ... @@ -63,6 +89,11 @@ def compute_d_graph(clq1, clq2, G): ... @@ -63,6 +89,11 @@ def compute_d_graph(clq1, clq2, G): arities2 = {name:0 for name in clq2} arities2 = {name:0 for name in clq2} sum_edges = 0 sum_edges = 0 # TODO : Remove this part and improve the detection if len(clq1) != len(clq2): return None # /TODO min_clq_size = min(len(clq1), len(clq2)) min_clq_size = min(len(clq1), len(clq2)) # Compute link arities # Compute link arities ... @@ -80,14 +111,56 @@ def compute_d_graph(clq1, clq2, G): ... @@ -80,14 +111,56 @@ def compute_d_graph(clq1, clq2, G): if sum_edges < min_clq_size * (min_clq_size-1) / 2: if sum_edges < min_clq_size * (min_clq_size-1) / 2: return None return None print(clq1, clq2) # print(clq1, clq2) print(arities1, arities2, "\n") # print(arities1, arities2, "\n") # order lists lst1 = [key for key, value in sorted(arities1.items(), key=lambda tup: -tup)] lst1 = [key for key, value in sorted(arities1.items(), key=lambda tup: -tup)] lst2 = [key for key, value in sorted(arities2.items(), key=lambda tup: -tup)] lst2 = [key for key, value in sorted(arities2.items(), key=lambda tup: -tup)] # print(min_clq_size) # print(lst1, "\n", lst2, "\n") # Return the 2 halves of the d-graph return lst1, lst2 return lst1, lst2 """ Filter the candiates regarding their compatibilities """ def filter_d_graphs(candidates): # Count for each node the number of their apparition counts = {} for d_graph in candidates: for node in itertools.chain(d_graph, d_graph): if not node in counts: counts[node] = 0 counts[node] += 1 # take d_graphes with nodes that appears only once filtered = [] selected = {node:False for node in counts.keys()} for d_graph in candidates: for node in itertools.chain(d_graph, d_graph): if counts[node] == 1: # Add the d_graph to the selection filtered.append(d_graph) # register selection of the nodes for node in itertools.chain(d_graph, d_graph): selected[node] = True # Over for this d-graph break # TODO : improve performances when there are no uniq solution for val in selected.values(): if not val: # print(min(counts.values()), counts) return [] # print(len(filtered)) return filtered def main(): def main(): # Parsing the input file # Parsing the input file ... @@ -102,9 +175,11 @@ def main(): ... @@ -102,9 +175,11 @@ def main(): g_nodes = list(G.nodes()) g_nodes = list(G.nodes()) for node in g_nodes: for node in g_nodes: deconvolve(G,node) deconvolve(G,node) exit() # exit() print(len(g_nodes), "->", len(list(G.nodes()))) # nx.write_graphml(G,sys.argv+".deconvolved.graphml") nx.write_graphml(G,sys.argv+".deconvolved.graphml") if __name__ == "__main__": if __name__ == "__main__": main() main()
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment