Commit e8a2652e by Yoann Dufresne

deconvolution start for small instances ok

parent ff1c07d8
 ... ... @@ -2,8 +2,7 @@ import sys import networkx as nx import sys import itertools ... ... @@ -13,7 +12,25 @@ def deconvolve(G,node): # Extract neighbors from the graph 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): ... ... @@ -41,9 +58,18 @@ def get_communities(G): d_graph = compute_d_graph(clq1, clq2, G) if d_graph != None: 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. # 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[0]+d_graph[1] 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. ... ... @@ -63,6 +89,11 @@ def compute_d_graph(clq1, clq2, G): arities2 = {name:0 for name in clq2} 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)) # Compute link arities ... ... @@ -80,14 +111,56 @@ def compute_d_graph(clq1, clq2, G): if sum_edges < min_clq_size * (min_clq_size-1) / 2: return None print(clq1, clq2) print(arities1, arities2, "\n") # print(clq1, clq2) # print(arities1, arities2, "\n") # order lists lst1 = [key for key, value in sorted(arities1.items(), key=lambda tup: -tup[1])] lst2 = [key for key, value in sorted(arities2.items(), key=lambda tup: -tup[1])] # print(min_clq_size) # print(lst1, "\n", lst2, "\n") # Return the 2 halves of the d-graph 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[0], d_graph[1]): 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[0], d_graph[1]): 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[0], d_graph[1]): 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(): # Parsing the input file ... ... @@ -102,9 +175,11 @@ def main(): g_nodes = list(G.nodes()) for node in g_nodes: deconvolve(G,node) exit() # exit() print(len(g_nodes), "->", len(list(G.nodes()))) # nx.write_graphml(G,sys.argv[1]+".deconvolved.graphml") nx.write_graphml(G,sys.argv[1]+".deconvolved.graphml") if __name__ == "__main__": main()
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!