def is_isomorphic(self, g1, g2, approximate=False): """Check if two graphs are isomorphic. To accelerate the process, we use an approximate algorithm, whose False value means definitely not isomorphic while True value does not guarantee isomorphic for 100%. """ if approximate: return isomorphism.faster_could_be_isomorphic(g1, g2) else: if isomorphism.faster_could_be_isomorphic(g1, g2): if isomorphism.is_isomorphic(g1, g2): return True return False
def are_equivalent_partitions(a, b): """Checks for partition equivalence by checking if the graphs are isomorphic.""" ga = a["graph"] gb = b["graph"] if not iso.faster_could_be_isomorphic(ga, gb): return False em = iso.categorical_edge_match("particle", "exotic") return nx.is_isomorphic(ga, gb, edge_match=em)
def find_all_isomorphisms(home, other): if iso.faster_could_be_isomorphic(home, other): label_matcher = lambda x, y: x['distance_dependent_label'] == y['distance_dependent_label'] graph_label_matcher = iso.GraphMatcher(home, other, node_match=label_matcher) for index, mapping in enumerate(graph_label_matcher.isomorphisms_iter()): if index == 15: # give up .. break yield mapping else: logger.debug('faster iso check failed') raise StopIteration
def getValue(self, graph): ''' Lookup polynomial evaluation or calculate value if graph size is 1.''' if graph.number_of_edges() == 0: return 1 try: for candidate, value in self.knownGraphs[(graph.number_of_edges(), graph.number_of_nodes())]: if isomorphism.faster_could_be_isomorphic(candidate, graph): if isomorphism.is_isomorphic(candidate, graph): return value except KeyError: raise KeyError
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 find_all_isomorphisms(home, other): if iso.faster_could_be_isomorphic(home, other): ddl = 'distance_dependent_label' label_matcher = lambda x, y: x[ddl] == y[ddl] and \ x.get('shard', 1) == y.get('shard', 1) graph_label_matcher = iso.GraphMatcher(home, other, node_match=label_matcher) for index, mapping in enumerate(graph_label_matcher.isomorphisms_iter()): if index == 5: logger.debug('lsgg_compose_util i checked more than 5 isomorphisms') yield mapping else: logger.log(5, 'lsgg_compose_util faster iso check failed') yield {} # iso.graphmatcher returns empty dict when nothing is found. i do the same :)
def test_faster_could_be_isomorphic(self): assert_true(iso.faster_could_be_isomorphic(self.G3, self.G2))
def test_faster_could_be_isomorphic(self): assert iso.faster_could_be_isomorphic(self.G3, self.G2) assert not iso.faster_could_be_isomorphic(self.G3, self.G5) assert not iso.faster_could_be_isomorphic(self.G1, self.G6)
def test_faster_could_be_isomorphic(self): assert_true(iso.faster_could_be_isomorphic(self.G3,self.G2))