def get_unit(self, selection): """ Gets the UNIT name corresponding to a selection. Helpful when matching ligands that may have a residue name different from unit name since the average user doesn't know what a unit name is when creating a library. This isn't as efficient as it could be because it is called infrequently, on ligands only. Args: selection (VMD atomsel): Selection to check molid (int): VMD molecule ID to look in Returns: (str) The unit name, or None if there was no match """ rgraph = self.parse_vmd_graph(selection)[0] # First try to short-circuit if the name already matches a unit resname = selection.resname[0] if resname in self.known_res.keys(): graph = self.known_res[resname] matcher = isomorphism.GraphMatcher( rgraph, graph, node_match=self._check_atom_match) if matcher.is_isomorphic(): return resname for matchname in self.known_res.keys(): graph = self.known_res[matchname] matcher = isomorphism.GraphMatcher( rgraph, graph, node_match=self._check_atom_match) if matcher.is_isomorphic(): return matchname return None
def get_names(self, selection, print_warning=False): """ Obtains a name mapping for the current selection Args: selection (VMD atomsel): Selection to set names for print_warning (bool): Whether or not to print matching suggestions if matching fails. Set to false if you'll try patches later. Returns: (dict int->str) Atom index to resname matched (dict int->str) Atom index to atom name matched up Raises: KeyError: if no matching possible """ resname = selection.resname[0] rgraph, _ = self.parse_vmd_graph(selection) # First check against matching residue names if resname in self.known_res.keys(): graph = self.known_res.get(resname) matcher = isomorphism.GraphMatcher( rgraph, graph, node_match=self._check_atom_match) if matcher.is_isomorphic(): return self._get_names_from_match(graph, next(matcher.match())) # If that didn't work, loop through all known residues for matchname in self.known_res.keys(): graph = self.known_res[matchname] matcher = isomorphism.GraphMatcher( rgraph, graph, node_match=self._check_atom_match) if matcher.is_isomorphic(): return self._get_names_from_match(graph, next(matcher.match())) # Try to print out a helpful error message here if matching failed if print_warning: print( "\nERROR: Couldn't find a topological match for resname '%s'" % resname) if self.known_res.get(resname): print( " I found a residue definition with the same name, but " "it didn't match up") print( " That definition had %d atoms, and your residue had " "%d atoms" % (len(self.known_res[resname]), len(selection))) print(" If that's the same, check the connectivity") print(" If it's not, check your hydrogens") else: print( " I couldn't find any residues with that name. Did you " "forget to provide a topology file?") print("\tDumping debug information as 'nomatch.dot'") self.write_dot(graph, "nomatch.dot") return (None, None)
def VF2(GG,TG): ''' this function is used to find the subgraph isomorphism ''' b = 0 start = time.time() for G in GG: for T in TG: GM = isomorphism.GraphMatcher(G,T) GM1 = isomorphism.GraphMatcher(T,G) if GM.subgraph_is_isomorphic(): print "GM there are isomorphism:" print GM.mapping print "++++++++++++++++++++++++" print G.edges() print T.edges() b = b + 1 break else: print "GM is not isomorphic!" if GM1.subgraph_is_isomorphic(): print "GM1 is isomorphism:" print GM1.mapping #b = b + 1 print "************************" print G.edges() print T.edges() break else: print "GM1 is not isomorphic!" print "every iterate~" print str(time.time() - start) if int(time.time()-start) > 5: print "*******" print "***********" print "times up" break print "every circile" elapse = time.time() - start print elapse print "===============================" print "*******************************" print time.time() - start return b
def find_type_match(T, graphlet_list): """ Given graph 'T', find an isomorphism with one of the canonical graphs from 'graphlet_list'. Return index of the corresponding graph from 'graphlet_list' and a match dictionary. The match dictionary has format {u_i: v_i}, 'u_i' are nodes from 'T' and 'v_i' are nodes from canonical graph. """ nodes = T.nodes() n = len(nodes) if n == 1: return (0, {u: 0 for u in T.nodes()}) if n == 2: return (0, {u: i for i, u in enumerate(T.nodes())}) if n == 3: if T.number_of_edges() == 2: u0 = next((node for node in nodes if T.degree(node) == 2)) (u1, u2) = (node for node in T.neighbors(u0)) return (0, {u0: 0, u1: 1, u2: 2}) if T.number_of_edges() == 3: return (1, {u: i for i, u in enumerate(nodes)}) if n == 4: e_num = T.number_of_edges() max_degree = max((T.degree(node) for node in nodes)) if e_num == 3 and max_degree == 3: u3 = next((node for node in nodes if T.degree(node) == 3)) (u0, u1, u2) = tuple(T.neighbors(u3)) return (0, {u0: 0, u1: 1, u2: 2, u3: 3}) if e_num == 3 and max_degree == 2: (u0, u1) = (node for node in nodes if T.degree(node) == 2) u2 = next((node for node in T.neighbors(u1) if node != u0)) u3 = next((node for node in T.neighbors(u0) if node != u1)) return (1, {u0: 0, u1: 1, u2: 2, u3: 3}) if e_num == 4 and max_degree == 3: u3 = next((node for node in nodes if T.degree(node) == 3)) (u1, u2) = (node for node in nodes if T.degree(node) == 2) u0 = next((node for node in nodes if T.degree(node) == 1)) return (2, {u0: 0, u1: 1, u2: 2, u3: 3}) if e_num == 4 and max_degree == 2: u0 = next((node for node in nodes)) (u1, u3) = tuple(T.neighbors(u0)) u2 = next((node for node in T.neighbors(u1) if node != u0)) return (3, {u0: 0, u1: 1, u2: 2, u3: 3}) if e_num == 5: (u0, u2) = (node for node in nodes if T.degree(node) == 3) (u1, u3) = (node for node in nodes if T.degree(node) == 2) return (4, {u0: 0, u1: 1, u2: 2, u3: 3}) if e_num == 6: (u0, u1, u2, u3) = tuple(nodes) return (5, {u0: 0, u1: 1, u2: 2, u3: 3}) raise ValueError("wrong graphlet format") # Improve matching procedure here for n>4. GM = next((i, iso.GraphMatcher(T, T_)) for (i, T_) in enumerate(graphlet_list) if iso.GraphMatcher(T, T_).is_isomorphic()) assert GM[1].is_isomorphic() return (GM[0], GM[1].mapping)
def is_isomorphic(graph1, graph2, ignore_active_bonds=False, timeout=5): """Check whether two NX graphs are isomorphic. Contains a timeout because the gm.is_isomorphic() method occasionally gets stuck Arguments: graph1 (nx.Graph): graph 1 graph2 (nx.Graph): graph 2 Keyword Arguments: ignore_active_bonds (bool): timeout (float): Timeout in seconds Returns: (bool): if the graphs are isomorphic """ if ignore_active_bonds: graph1, graph2 = get_graphs_ignoring_active_edges(graph1, graph2) if not isomorphism.faster_could_be_isomorphic(graph1, graph2): return False # Always match on atom types node_match = isomorphism.categorical_node_match('atom_label', 'C') if ignore_active_bonds: gm = isomorphism.GraphMatcher(graph1, graph2, node_match=node_match) else: # Also match on edges edge_match = isomorphism.categorical_edge_match('active', False) gm = isomorphism.GraphMatcher(graph1, graph2, node_match=node_match, edge_match=edge_match) # NX can hang here for not very large graphs, so kill after a timeout def handler(signum, frame): raise TimeoutError signal.signal(signal.SIGALRM, handler) signal.alarm(int(timeout)) try: result = gm.is_isomorphic() # Cancel the timer signal.alarm(0) return result except TimeoutError: logger.error('NX graph matching hanging') return False
def __fit_graph(self, model): if self.get_bin_step() != 0: gm = iso.GraphMatcher(self._PharmacophoreBase__g, model, node_match=self.__nm, edge_match=self.__em) else: gm = iso.GraphMatcher(self._PharmacophoreBase__g, model, node_match=self.__nm, edge_match=iso.numerical_edge_match( 'dist', 0, atol=0.75)) return gm
def test_isomorphism_iter2(): # Path for L in range(2, 10): g1 = nx.path_graph(L) gm = iso.GraphMatcher(g1, g1) s = len(list(gm.isomorphisms_iter())) assert s == 2 # Cycle for L in range(3, 10): g1 = nx.cycle_graph(L) gm = iso.GraphMatcher(g1, g1) s = len(list(gm.isomorphisms_iter())) assert s == 2 * L
def count_graphlets_helper(inp): i, query, target, method, node_anchored, anchor_or_none = inp # NOTE: removing self loops!! query = query.copy() query.remove_edges_from(nx.selfloop_edges(query)) #if node_anchored and method == "bin": # n_chances_left = sum([len(g) for g in targets]) if method == "freq": ismags = nx.isomorphism.ISMAGS(query, query) n_symmetries = len(list(ismags.isomorphisms_iter(symmetry=False))) #print(n_symmetries, "symmetries") n, n_bin = 0, 0 target = target.copy() target.remove_edges_from(nx.selfloop_edges(target)) #print(i, j, len(target), n / n_symmetries) #matcher = nx.isomorphism.ISMAGS(target, query) if method == "bin": if node_anchored: for anchor in (target.nodes if anchor_or_none is None else [anchor_or_none]): #if random.random() > 0.1: continue nx.set_node_attributes(target, 0, name="anchor") target.nodes[anchor]["anchor"] = 1 matcher = iso.GraphMatcher( target, query, node_match=iso.categorical_node_match(["anchor"], [0])) if matcher.subgraph_is_isomorphic(): n += 1 #else: #n_chances_left -= 1 #if n_chances_left < min_count: # return i, -1 else: matcher = iso.GraphMatcher(target, query) n += int(matcher.subgraph_is_isomorphic()) elif method == "freq": matcher = iso.GraphMatcher(target, query) n += len(list(matcher.subgraph_isomorphisms_iter())) / n_symmetries else: print("counting method not understood") #n_matches.append(n / n_symmetries) #print(i, n / n_symmetries) count = n # / n_symmetries #if include_bin: # count = (count, n_bin) #print(i, count) return i, count
def find_type_match(T): n = T.number_of_nodes() if n == 1: return ((0, {u: 0 for u in T.nodes()})) if n == 2: return ((0, {u: i for i, u in enumerate(T.nodes())})) if n == 3: if T.number_of_edges() == 2: u0 = next((node for node in T.nodes() if T.degree(node) == 2)) (u1, u2) = (node for node in T.neighbors(u0)) return ((0, {u0: 0, u1: 1, u2: 2})) if T.number_of_edges() == 3: return ((1, {u: i for i, u in enumerate(T.nodes())})) if n == 4: e_num = T.number_of_edges() max_degree = max((T.degree(node) for node in T.nodes())) if e_num == 3 and max_degree == 3: u3 = next((node for node in T.nodes() if T.degree(node) == 3)) (u0, u1, u2) = (node for node in T.neighbors(u3)) return ((0, {u0: 0, u1: 1, u2: 2, u3: 3})) if e_num == 3 and max_degree == 2: (u0, u1) = (node for node in T.nodes() if T.degree(node) == 2) u2 = next((node for node in T.neighbors(u1) if node != u0)) u3 = next((node for node in T.neighbors(u0) if node != u1)) return ((1, {u0: 0, u1: 1, u2: 2, u3: 3})) if e_num == 4 and max_degree == 3: u3 = next((node for node in T.nodes() if T.degree(node) == 3)) (u1, u2) = (node for node in T.nodes() if T.degree(node) == 2) u0 = next((node for node in T.nodes() if T.degree(node) == 1)) return ((2, {u0: 0, u1: 1, u2: 2, u3: 3})) if e_num == 4 and max_degree == 2: u0 = next((node for node in T.nodes())) (u1, u3) = (node for node in T.neighbors(u0)) u2 = next((node for node in T.neighbors(u1) if node != u0)) return ((3, {u0: 0, u1: 1, u2: 2, u3: 3})) if e_num == 5: (u0, u2) = (node for node in T.nodes() if T.degree(node) == 3) (u1, u3) = (node for node in T.nodes() if T.degree(node) == 2) return ((4, {u0: 0, u1: 1, u2: 2, u3: 3})) if e_num == 6: (u0, u1, u2, u3) = (node for node in T.nodes()) return ((5, {u0: 0, u1: 1, u2: 2, u3: 3})) # Improve matching procedure here for n>4. GM = next((i, iso.GraphMatcher(T, T_)) for (i, T_) in enumerate(cached_graphlet_list[n]) if iso.GraphMatcher(T, T_).is_isomorphic()) assert GM[1].is_isomorphic() return ((GM[0], GM[1].mapping))
def find_subgraph(G1, G2): GM = isomorphism.GraphMatcher(G1, G2, node_match=node_match) subgraphs = list(GM.subgraph_isomorphisms_iter()) assert len(subgraphs) > 0 if len(subgraphs) == 1: return subgraphs[0] ref_sg = G1.subgraph(subgraphs[0].keys()) ref_bonds = bond_dict(ref_sg) g2_bonds = bond_dict(G2) diffs = np.zeros(len(subgraphs)) for i, map_ in enumerate(subgraphs): def translate_edge(i, j): print("translate", i, j) return (map_[i], map_[j]) for edge, length in ref_bonds.items(): # Not all bonds from the reference geometry may be present. try: edge_ = translate_edge(*edge) diffs[i] += abs(g2_bonds[edge_] - length) except KeyError: pass return subgraphs[diffs.argmin()]
def test_selfloop_mono(): # Simple test for graphs with selfloops edges0 = [ (0, 1), (0, 2), (1, 2), (1, 3), (2, 4), (3, 1), (3, 2), (4, 2), (4, 5), (5, 4), ] edges = edges0 + [(2, 2)] nodes = list(range(6)) for g1 in [nx.Graph(), nx.DiGraph()]: g1.add_edges_from(edges) for _ in range(100): new_nodes = list(nodes) random.shuffle(new_nodes) d = dict(zip(nodes, new_nodes)) g2 = nx.relabel_nodes(g1, d) g2.remove_edges_from(nx.selfloop_edges(g2)) if not g1.is_directed(): gm = iso.GraphMatcher(g2, g1) else: gm = iso.DiGraphMatcher(g2, g1) assert not gm.subgraph_is_monomorphic()
def find_type(T): n = T.number_of_nodes() if n == 1: return 0 if n == 2: return 0 if n == 3: if T.number_of_edges() == 2: return 0 if T.number_of_edges() == 3: return 1 if n == 4: e_num = T.number_of_edges() max_degree = max((T.degree(node) for node in T.nodes())) if e_num == 3 and max_degree == 3: return 0 if e_num == 3 and max_degree == 2: return 1 if e_num == 4 and max_degree == 3: return 2 if e_num == 4 and max_degree == 2: return 3 if e_num == 5: return 4 if e_num == 6: return 5 # Improve matching procedure here at least for n=4. GM = next((i for (i, T_) in enumerate(cached_graphlet_list[n]) if iso.GraphMatcher(T, T_).is_isomorphic())) return GM
def vf2(graph1, graph2): GM = isomorphism.GraphMatcher(graph1, graph2) if GM.is_isomorphic(): print('Graphs are isomorphic') print(GM.mapping) else: print('Graphs are not isomorphic')
def subgraphIsomorphismCheck(self, G1, G2): """ Checks whether G1 contains a subgraph isomorphic to G2 by using Whitney isomorphism theorem. Parameters: G1 (NetworkX graph): The bigger graph. G2 (NetworkX graph): The smaller graph. Returns: bool: Is graph G2 isomorphic to a subgraph in G1. isomorphism.GraphMatcher: Graph matcher object with parameters. """ # transform graphs into line graphs and check for subgraph isomorphism # isomorphism.GraphMatcher tries to find an induced subgraph of G1, such that it is isomorphic to G2. # Consequently, if G2 is non-induced subgraph of G1, the algorithm will return False GM = isomorphism.GraphMatcher(nx.line_graph(G1), nx.line_graph(G2)) subgraph_is_iso = GM.subgraph_is_isomorphic() # check for exceptions # e.g. line graphs of K_3 triangle graph and K_1,3 claw graph are isomorphic, but the original graphs are not if subgraph_is_iso: edgeListG1 = [] edgeListG2 = [] for edgeMaping in GM.mapping.items(): edgeListG1.append(edgeMaping[0]) edgeListG2.append(edgeMaping[1]) # let's construct the graphs the algorithm thinks are isomorphic and check them for a quick isomorphism.is_isomorphic testG1 = nx.Graph(edgeListG1) testG2 = nx.Graph(edgeListG2) subgraph_is_iso = isomorphism.is_isomorphic(testG1, testG2) return subgraph_is_iso, GM
def isomorphism(pattern, target, nx_structures): """ Uses the NetworkX isomorphism algorithm to check if the pattern graph and the target graph are isomorphic. The faster_could_be_isomorphic method is used to discount two structures if they could not be isomorphic. :param pattern: a molecule object which is to be tested for isomorphism :param target: a molecule object which pattern graph is to be compared against :return: None if the graphs are not isomorphic :return: a dictionary which maps the indices of the two NetworkX graphs together if they are isomorphic """ if pattern not in nx_structures: nx_structures[pattern] = create_nx_graph(pattern, nx_structures) if target not in nx_structures: nx_structures[target] = create_nx_graph(target, nx_structures) if not nx.faster_could_be_isomorphic(nx_structures[pattern], nx_structures[target]): # Graphs are definitely not isomorphic return None #print pattern, target # Ensures the isomorphism considers the vertex label and edge type matcher = iso.GraphMatcher( nx_structures[pattern], nx_structures[target], node_match=iso.categorical_node_match('label', 'C'), edge_match=iso.categorical_edge_match('type', 'single')) if matcher.is_isomorphic(): return matcher.mapping
def test_subgraph_mono(self): g1 = nx.Graph() g2 = nx.Graph() g1.add_edges_from(self.g1edges) g2.add_edges_from([[1, 2], [2, 3], [3, 4]]) gm = iso.GraphMatcher(g1, g2) assert gm.subgraph_is_monomorphic()
def test_circ2graph(filename='inst_2x2_7_0.txt'): """ This function tests direct reading of circuits to graphs. It should be noted that graphs can not to be used in place of buckets yet, since the information about transpositions of tensors (denoted by edges) is not kept during node relabelling """ import networkx as nx nq, circuit = ops.read_circuit_file(filename) graph = gm.circ2graph(nq, circuit) n_qubits, circuit = ops.read_circuit_file(filename) buckets_original, _, bra_vars, ket_vars = opt.circ2buckets( n_qubits, circuit) graph_original = gm.buckets2graph( buckets_original, ignore_variables=bra_vars+ket_vars) from networkx.algorithms import isomorphism GM = isomorphism.GraphMatcher(graph, graph_original) print('Isomorphic? : {}'.format(GM.is_isomorphic())) graph = nx.relabel_nodes(graph, GM.mapping, copy=True) if not GM.is_isomorphic(): gm.draw_graph(graph, 'new_graph.png') gm.draw_graph(graph_original, 'orig_graph.png') return GM.is_isomorphic()
def subgraph_is_isomorphic(graph, subgraph): """ determines whether main graph contains a subgraph which is isomorphic to input subgraph :param graph: main graph :param subgraph: a subgraph to be searched in main graph :return: boolean """ graph_gspan = networkx_to_gspan(graph, 0) subgraph_gspan = networkx_to_gspan(subgraph, 1) # create temporary files during gspan processing input_fd, input_filename = tempfile.mkstemp() output_fd, output_filename = tempfile.mkstemp() with os.fdopen(input_fd, 'w', encoding='utf-8') as input_handler: input_handler.write(graph_gspan + subgraph_gspan) orig_stdout = sys.stdout sys.stdout = os.fdopen(output_fd, 'w', encoding='utf-8') subgraph_miner = gSpan(input_filename, 2, where=True) subgraph_miner.run() sys.stdout = orig_stdout mined_subgraphs = parse_mined_gspan_file(output_filename) # remove temporary files os.remove(input_filename) os.remove(output_filename) em = iso.numerical_edge_match('weight', 0) nm = iso.categorical_node_match('name', None) for mined_subgraph in mined_subgraphs: graph_matcher = iso.GraphMatcher(mined_subgraph, subgraph, node_match=nm, edge_match=em) if graph_matcher.is_isomorphic(): return True return False
def find_type(T, graphlet_list): """ Given graph T, find an isomorphic graph from 'graphlet_list'. Returns the index of the isomorphic graph in 'graphlet_list'. """ edge_num = T.number_of_edges() node_num = T.number_of_nodes() if node_num == 1: return 0 if node_num == 2: return 0 if node_num == 3: if edge_num == 2: return 0 if edge_num == 3: return 1 if node_num == 4: max_degree = max((T.degree(node) for node in T.nodes())) if edge_num == 3 and max_degree == 3: return 0 if edge_num == 3 and max_degree == 2: return 1 if edge_num == 4 and max_degree == 3: return 2 if edge_num == 4 and max_degree == 2: return 3 if edge_num == 5: return 4 if edge_num == 6: return 5 # Improve matching procedure here for n=5 GM = next((i for (i, T_) in enumerate(graphlet_list) if iso.GraphMatcher(T, T_).is_isomorphic())) return GM
def is_isomorphic(graph1, graph2): """Determines if two graphs are isomorphic. @graph2: graph to be compared to self @return: true if they are isomorphic. """ if graph1.order() != graph2.order(): return False # select method to be used to determine isomorphism if graph1.order() > 5000: return fast_could_be_isomorphic(graph1, graph2) elif graph1.order() > 1000: return could_be_isomorphic(graph1, graph2) else: matcher = isomorphism.GraphMatcher(graph1, graph2) try: match_iter = matcher.isomorphisms_iter() for iso in match_iter: sameAttributes = True for atom in iso: if not (graph1.getAttributes(atom).getInfo().getType() == graph2.getAttributes( iso[atom]).getInfo().getType()): #print "is_isomorphic atributos diferentes",graph1.getAttributes(atom), graph2.getAttributes(iso[atom]) sameAttributes = False break if sameAttributes: return True return False except StopIteration: return False
def _mapped_graph_list(G1, liblist): """ find all matches of library element in the graph """ logging.info("Matching circuit Graph from library elements") mapped_graph_list = {} for lib_ele in liblist: G2 = lib_ele['lib_graph'] sub_block_name = lib_ele['name'] #print("Matching:",sub_block_name) logging.info("G: %s : %s", sub_block_name, str(' '.join(G2.nodes()))) GM = isomorphism.GraphMatcher( G1, G2, node_match=isomorphism.categorical_node_match(['inst_type'], ['nmos']), edge_match=isomorphism.categorical_edge_match(['weight'], [1])) if GM.subgraph_is_isomorphic(): logging.info("ISOMORPHIC : %s", sub_block_name) map_list = [] for Gsub in GM.subgraph_isomorphisms_iter(): map_list.append(Gsub) logging.info("Matched Lib: %s", str(' '.join(Gsub.values()))) logging.info("Matched Circuit: %s", str(' '.join(Gsub))) mapped_graph_list[sub_block_name] = map_list return mapped_graph_list
def is_isomorphic3(graph1, graph2): """Determines if two graphs are isomorphic. @graph2: graph to be compared to self @return: true if they are isomorphic. """ print("graph1: ", graph1.order()) print("graph2: ", graph2.order()) matcher = isomorphism.GraphMatcher(graph1, graph2) if graph1.order() == graph2.order(): print("order is the same") try: match_iter = next(matcher.isomorphisms_iter()) for atom in match_iter: if not (graph1.getAttributes(atom) == graph2.getAttributes( match_iter[atom])): return False break return True except StopIteration: return False else: return False
def get_patches(self, selection): """ Obtains names and patch info for a modified residue in a selection. Identifies which amino acid is patched by finding which amino acid this one is a maximal subgraph of. Then, builds a library of graphs representing all valid patches applied to this amino acid. Note that this does NOT handle multiple-residue patches such as disulfides! Args: selection (VMD atomsel): Selection that is patched Returns: (str, str, dict) resname matched, patch name applied, name translation dictionary """ resname = selection.resname[0] rgraph = self.parse_vmd_graph(selection)[0] # Check this residue against all possible patches applied to the for names in self.known_pres: graph = self.known_pres[names] matcher = isomorphism.GraphMatcher(rgraph, graph, \ node_match=super(CharmmMatcher, self)._check_atom_match) if matcher.is_isomorphic(): logger.info("Detected patch %s", names[1]) match = next(matcher.match()) _, atomnames = self._get_names_from_match(graph, match) return (names[0], names[1], atomnames) logger.error("Couldn't find a patch for resname '%s'." "Dumping as 'rgraph.dot'", resname) self.write_dot(rgraph, "rgraph.dot") return (None, None, None)
def test_multiedge(): # Simple test for multigraphs # Need something much more rigorous edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (10, 11), (11, 12), (11, 12), (12, 13), (12, 13), (13, 14), (13, 14), (14, 15), (14, 15), (15, 16), (15, 16), (16, 17), (16, 17), (17, 18), (17, 18), (18, 19), (18, 19), (19, 0), (19, 0)] nodes = list(range(20)) for g1 in [nx.MultiGraph(), nx.MultiDiGraph()]: g1.add_edges_from(edges) for _ in range(10): new_nodes = list(nodes) random.shuffle(new_nodes) d = dict(zip(nodes, new_nodes)) g2 = nx.relabel_nodes(g1, d) if not g1.is_directed(): gm = iso.GraphMatcher(g1, g2) else: gm = iso.DiGraphMatcher(g1, g2) assert gm.is_isomorphic() # Testing if monomorphism works in multigraphs assert gm.subgraph_is_monomorphic()
def sm(): payload = request.get_json() nodesQ, edgesQ, nodesB, edgesB = parsePayload(payload) GQ = nx.Graph() GQ.add_nodes_from(nodesQ) GQ.add_edges_from(edgesQ) GB = nx.Graph() GB.add_nodes_from(nodesB) GB.add_edges_from(edgesB) print(nx.to_scipy_sparse_matrix(GQ)) GM = isomorphism.GraphMatcher(GB, GQ, node_match=my_node_match, edge_match=my_edge_match) res = [] for iso in GM.subgraph_isomorphisms_iter(): res += [iso] return flask.jsonify([r.keys() for r in res])
def new_tree_match(self, G, v2type, tree, threshold, outfile_prefix, repeat): #use new tree matching algorithm to return tree template's matching subgraph in G #seed not fixed as root, but any 3-degree node in the tree #use those templete where all terminals have appeared more then threshold times GM = isomorphism.GraphMatcher(G, tree) vertex_appearance_tracker = dict() outputcount = 1 # counter = 0 for mapping in GM.subgraph_isomorphisms_iter(): for vertex, node in mapping.iteritems(): if (node, vertex) not in vertex_appearance_tracker: vertex_appearance_tracker[(node, vertex)] = 1 else: vertex_appearance_tracker[(node, vertex)] += 1 if self.is_all_terminals_repeated(mapping, threshold, tree, vertex_appearance_tracker): print mapping #write to the template files when all requrement satisfies self.template_output(mapping, tree, v2type, outfile_prefix + str(outputcount)) outputcount += 1 if outputcount > repeat: break
def main(): opts = get_options() conf = GraphConfig(opts.size, opts.r) Gbase, degseq = base_graph(conf, opts.d) E, Erev = make_sat_vars(conf, Gbase, degseq) s = make_sat_solver(E, degseq) dirname = os.path.dirname(opts.prefix) if len(dirname) > 0 and not os.path.isdir(dirname): os.mkdir(dirname) mcount = 1 fmtstr = '{}-{:0' + str(len(str(opts.ngraphs))) + 'd}.elist' while s.check() == sat and (opts.ngraphs <= 0 or mcount <= opts.ngraphs): m = s.model() G = Gbase.copy() G.add_edges_from((u, v) for u, v in Erev.values() if m.eval(E[(u, v)])) filename = fmtstr.format(opts.prefix, mcount) nx.write_edgelist(G, filename, data=False) # add new solution # s = add_new_solution(s, m, E) for i in iso.GraphMatcher(G, G.copy()).isomorphisms_iter(): if any((i[u], i[v]) not in E for u, v in Erev.values()): continue s.add(Not(And([ l if m.eval(E[(i[u], i[v])]) else Not(l) for l, (u, v) in Erev.items() ]))) mcount += 1
def compare(cc1, cc2): s1 = {a.id for a in cc1.atoms} s2 = {a.id for a in cc2.atoms} b1 = {b.lexicographic_str() for b in cc1.rt.bonds} b2 = {b.lexicographic_str() for b in cc2.rt.bonds} if s1 == s2 and b1 == b2: #print(cc1.name, "the same") return G1 = graph_from_chemcomp(cc1) G2 = graph_from_chemcomp(cc2) node_match = isomorphism.categorical_node_match('Z', 0) GM = isomorphism.GraphMatcher(G1, G2, node_match=node_match) if GM.is_isomorphic(): print(cc1.name, 'is isomorphic') # we could use GM.match(), but here we try to find the shortest diff short_diff = None for n, mapping in enumerate(GM.isomorphisms_iter()): diff = {k: v for k, v in mapping.items() if k != v} if short_diff is None or len(diff) < len(short_diff): short_diff = diff if n == 10000: # don't spend too much here print(' (it may not be the simplest isomorphism)') break for id1, id2 in short_diff.items(): print('\t', id1, '->', id2) else: print(cc1.name, 'differs') if s2 - s1: print('\tmissing:', ' '.join(s2 - s1)) if s1 - s2: print('\textra: ', ' '.join(s1 - s2))
def equal_graphs(g1, g2, node_attrs=('resid', 'resname', 'atomname', 'chain', 'charge_group', 'atype'), edge_attrs=()): """ Parameters ---------- g1: networkx.Graph g2: networkx.Graph node_attrs: collections.abc.Iterable or None Node attributes to consider. If `None`, the node attribute dicts must be equal. edge_attrs: collections.abc.Iterable or None Edge attributes to consider. If `None`, the edge attribute dicts must be equal. Returns ------- bool True if `g1` and `g2` are isomorphic, False otherwise. """ if node_attrs is None: node_equal = operator.eq else: node_equal = iso.categorical_node_match(node_attrs, [''] * len(node_attrs)) if edge_attrs is None: edge_equal = operator.eq else: edge_equal = iso.categorical_node_match(edge_attrs, [''] * len(edge_attrs)) matcher = iso.GraphMatcher(g1, g2, node_match=node_equal, edge_match=edge_equal) return matcher.is_isomorphic()
def do_atomic_pg_test(): s = ''' proctype p(){ bit x, y; /* 0 */ do :: true; /* 1 */ atomic { x = 2; /* 2 */ y = 1; goto S0; } /* 3 */ :: x == 1; /* 4 */ y == 2; /* 0 */ od; x = 3; /* 3 */ S0: skip /* 5 */ } ''' tree = parser.parse(s) g = tree[0].to_pg() dump(g) h = nx.MultiDiGraph() h.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 5), (0, 4), (4, 0)]) for u in h: h.add_node(u, context=None) h.add_node(2, context='atomic') nm = lambda x, y: x['context'] == y['context'] gm = iso.GraphMatcher(g, h, node_match=nm) assert gm.is_isomorphic()