Ejemplo n.º 1
0
    def is_same(self, prod_rule, ignore_order=False):
        """ judge whether this production rule is
        the same as the input one, `prod_rule`

        Parameters
        ----------
        prod_rule : ProductionRule
            production rule to be compared

        Returns
        -------
        is_same : bool
        isomap : dict
            isomorphism of nodes and hyperedges.
            ex) {'bond_42': 'bond_37', 'bond_2': 'bond_1',
                 'e36': 'e11', 'e16': 'e12', 'e25': 'e18',
                 'bond_40': 'bond_38', 'e26': 'e21', 'bond_41': 'bond_39'}.
            key comes from `prod_rule`, value comes from `self`.
        """
        if self.is_start_rule:
            if not prod_rule.is_start_rule:
                return False, {}
        else:
            if prod_rule.is_start_rule:
                return False, {}
            else:
                if prod_rule.lhs.num_nodes != self.lhs.num_nodes:
                    return False, {}

        if prod_rule.rhs.num_nodes != self.rhs.num_nodes:
            return False, {}
        if prod_rule.rhs.num_edges != self.rhs.num_edges:
            return False, {}

        subhg_bond_symbol_counter \
            = Counter([prod_rule.rhs.node_attr(each_node)['symbol'] \
                       for each_node in prod_rule.rhs.nodes])
        each_bond_symbol_counter \
            = Counter([self.rhs.node_attr(each_node)['symbol'] \
                       for each_node in self.rhs.nodes])
        if subhg_bond_symbol_counter != each_bond_symbol_counter:
            return False, {}

        subhg_atom_symbol_counter \
            = Counter([prod_rule.rhs.edge_attr(each_edge)['symbol'] \
                       for each_edge in prod_rule.rhs.edges])
        each_atom_symbol_counter \
            = Counter([self.rhs.edge_attr(each_edge)['symbol'] \
                       for each_edge in self.rhs.edges])
        if subhg_atom_symbol_counter != each_atom_symbol_counter:
            return False, {}

        gm = GraphMatcher(
            prod_rule.rhs.hg, self.rhs.hg,
            partial(_node_match_prod_rule, ignore_order=ignore_order),
            partial(_edge_match, ignore_order=ignore_order))
        try:
            return True, next(gm.isomorphisms_iter())
        except StopIteration:
            return False, {}
Ejemplo n.º 2
0
 def test_iso(self):
     base = os.path.dirname(os.path.abspath(__file__))
     hg_list = HGGen(os.path.join(base, "test.smi"))
     hg_list = list(hg_list)
     hrg = HyperedgeReplacementGrammar()
     prod_rule_seq_list = hrg.learn(hg_list)
     not_iso = 0
     for idx, each_prod_rule_seq in enumerate(prod_rule_seq_list):
         hg = hrg.construct(each_prod_rule_seq)
         self.assertEqual(len(hg.nodes), len(list(hg_list)[idx].nodes))
         self.assertEqual(len(hg.edges), len(list(hg_list)[idx].edges))
         gm = GraphMatcher(hg.hg, list(hg_list)[idx].hg)
         try:
             isomap = next(gm.isomorphisms_iter())
         except StopIteration:
             isomap = None
         if isomap is None:
             print("not isomorphic")
             not_iso += 1
         self.assertEqual(not_iso, 0)
     print("not_iso = {}".format(not_iso))
Ejemplo n.º 3
0
def sparse_orbigraph_nx(n, H):
    import networkx as nx
    from networkx.algorithms.isomorphism import GraphMatcher

    bag = nx.Graph()
    for i in range(n):
        bag.add_node(i, syndrome=H[i,i])

    for i in range(n):
      for j in range(n):
        if i==j:
            continue
        if H.get((i, j)):
            bag.add_edge(i, j)

    def node_match(n0, n1):
        return n0['syndrome'] == n1['syndrome']

    matcher = GraphMatcher(bag, bag, node_match=node_match)

    print("search...")

    graph = nx.Graph()
    for i in range(n):
        graph.add_node(i)

    count = 0
    for iso in matcher.isomorphisms_iter(): # too slow :P
        #print iso
        write('.')
        for i, j in list(iso.items()):
            graph.add_edge(i, j)
        count += 1
    print()

    equs = nx.connected_components(graph)
    m = len(equs)

    print("isomorphisms:", count)
    print("components:", m)
Ejemplo n.º 4
0
    def add_subhg(self, subhg):
        if len(self.subhg_list) == 0:
            node_dict = {}
            for each_node in subhg.nodes:
                node_dict[each_node] = subhg.node_attr(each_node)['symbol'].__hash__()
            node_list = []
            for each_key, _ in sorted(node_dict.items(), key=lambda x:x[1]):
                node_list.append(each_key)
            for each_idx, each_node in enumerate(node_list):
                subhg.node_attr(each_node)['order4hrg'] = each_idx
            self.subhg_list.append(subhg)
            return 0, True
        else:
            match = False
            for each_idx, each_subhg in enumerate(self.subhg_list):
                subhg_bond_symbol_counter \
                    = Counter([subhg.node_attr(each_node)['symbol'] \
                               for each_node in subhg.nodes])
                each_bond_symbol_counter \
                    = Counter([each_subhg.node_attr(each_node)['symbol'] \
                               for each_node in each_subhg.nodes])

                subhg_atom_symbol_counter \
                    = Counter([subhg.edge_attr(each_edge).get('symbol', None) \
                               for each_edge in subhg.edges])
                each_atom_symbol_counter \
                    = Counter([each_subhg.edge_attr(each_edge).get('symbol', None) \
                               for each_edge in each_subhg.edges])
                if not match \
                   and (subhg.num_nodes == each_subhg.num_nodes
                        and subhg.num_edges == each_subhg.num_edges
                        and subhg_bond_symbol_counter == each_bond_symbol_counter
                        and subhg_atom_symbol_counter == each_atom_symbol_counter):
                    gm = GraphMatcher(each_subhg.hg,
                                      subhg.hg,
                                      node_match=_easy_node_match,
                                      edge_match=_edge_match)
                    try:
                        isomap = next(gm.isomorphisms_iter())
                        match = True
                        for each_node in each_subhg.nodes:
                            subhg.node_attr(isomap[each_node])['order4hrg'] \
                                = each_subhg.node_attr(each_node)['order4hrg']
                            if 'ext_id' in each_subhg.node_attr(each_node):
                                subhg.node_attr(isomap[each_node])['ext_id'] \
                                    = each_subhg.node_attr(each_node)['ext_id']
                        return each_idx, False
                    except StopIteration:
                        match = False    
            if not match:
                node_dict = {}
                for each_node in subhg.nodes:
                    node_dict[each_node] = subhg.node_attr(each_node)['symbol'].__hash__()
                node_list = []
                for each_key, _ in sorted(node_dict.items(), key=lambda x:x[1]):
                    node_list.append(each_key)
                for each_idx, each_node in enumerate(node_list):
                    subhg.node_attr(each_node)['order4hrg'] = each_idx

                #for each_idx, each_node in enumerate(subhg.nodes):
                #    subhg.node_attr(each_node)['order4hrg'] = each_idx
                self.subhg_list.append(subhg)
                return len(self.subhg_list) - 1, True