So I am running a artificial chemistry simulation and I'm using networkx's undirected graphs to represent the structure of molecules. I want to be able to determine if two molecules have the same structure. So determining if two molecular graphs are isomorphic is an appropriate way of determining if they have the same structure. The atoms can be different chemical elements in the simulation. So nodes/atoms have a label which is effectively the atomic number of the element. However there are specific bonding sites on the atoms as well which also have a integer label. For example, consider the molecular structure 1-1-3 (dashes are edges and numbers are labelled nodes/atoms). Let's say there are two molecules with this structure but with a different bonding site configuration:
1(2)-(1)1(2)-(1)3 and 1(1)-(2)1(1)-(1)3
where the numbers in brackets are the bonding sites of the atoms. If I compare these molecules using the following code, is_isomorphic would incorrectly return true:
node_match = iso.numerical_node_match('element', -1)
nx.is_isomorphic(molecule1, molecule2, node_match=node_match))
Additionally if I made it so each edge contains a bonding_sites attribute, which is a sorted list of bonding sites (e.g. bonding_sites=[1,2]), and tried to add an edge matcher, the following code would also incorrectly return true:
edge_match = iso.categorical_edge_match('bonding_sites', None)
node_match = iso.numerical_node_match('element', -1)
nx.is_isomorphic(molecule1, molecule2, node_match=node_match, edge_match=edge_match))
The only way I can think to ensure is_isomorphic returns false is to introduce some kind of label matching based on node-edge tuples. But I cannot find any facility for this in networkx. Can anyone think of a solution to this that uses networkx (rest of my code heavily relies on it)? Also, is there a name for the type of graph I'm trying to compare here?
I can think of a slightly complicated solution which is to have each atom be represented by a complete subgraph with each node of the subgraph representing each bonding site. But I would like to avoid this if possible.
I haven't used
networkxbut you can try this. It may help.Fist try if instead of adding vertices by a list of numbers you can add vertices of a class data structure. So
[Node(id=1), Node(id=2), Node(id=3)]instead of[1, 2, 3]. This way your Node class can have multiple attributes based on which you can compare.If this does not work.
Then you can use [1, 2, 3] and create an external data structure like a dictionary.
And you can always use those same
[1, 2, 3,...]but now instead usingmap(lambda i:d[i].attribute, [1, 2, 3])to return a new list.