def test_copyAndMap(self): """ Test the returned dictionary points toward equivaalent vertices and edges """ vertices = [Vertex() for i in range(6)] edges = [ Edge(vertices[0], vertices[1]), Edge(vertices[1], vertices[2]), Edge(vertices[2], vertices[3]), Edge(vertices[3], vertices[4]), Edge(vertices[4], vertices[5]), ] graph = Graph() for vertex in vertices: graph.addVertex(vertex) for edge in edges: graph.addEdge(edge) graphDict = graph.copyAndMap() graph2 = Graph(vertices = graphDict.values()) for vertex in graph.vertices: self.assertTrue(graph2.hasVertex(graphDict[vertex])) for v1 in graph.vertices: for v2 in v1.edges: self.assertTrue(graph2.hasEdge(graphDict[v1], graphDict[v2])) self.assertTrue(graph2.hasEdge(graphDict[v2], graphDict[v1])) self.assertTrue(graph2.isIsomorphic(graph)) self.assertTrue(graph.isIsomorphic(graph2))
def test_isomorphism(self): """ Check the graph isomorphism functions. """ vertices1 = [Vertex() for i in range(6)] edges1 = [ Edge(vertices1[0], vertices1[1]), Edge(vertices1[1], vertices1[2]), Edge(vertices1[2], vertices1[3]), Edge(vertices1[3], vertices1[4]), Edge(vertices1[4], vertices1[5]), ] vertices2 = [Vertex() for i in range(6)] edges2 = [ Edge(vertices2[0], vertices2[1]), Edge(vertices2[1], vertices2[2]), Edge(vertices2[2], vertices2[3]), Edge(vertices2[3], vertices2[4]), Edge(vertices2[4], vertices2[5]), ] graph1 = Graph() for vertex in vertices1: graph1.addVertex(vertex) for edge in edges1: graph1.addEdge(edge) graph2 = Graph() for vertex in vertices2: graph2.addVertex(vertex) for edge in edges2: graph2.addEdge(edge) self.assertTrue(graph1.isIsomorphic(graph2)) self.assertTrue(graph1.isSubgraphIsomorphic(graph2)) self.assertTrue(graph2.isIsomorphic(graph1)) self.assertTrue(graph2.isSubgraphIsomorphic(graph1))
def test_pickle(self): """ Test that a Graph object can be successfully pickled and unpickled with no loss of information. """ vertices = [Vertex() for i in range(6)] edges = [ Edge(vertices[0], vertices[1]), Edge(vertices[1], vertices[2]), Edge(vertices[2], vertices[3]), Edge(vertices[3], vertices[4]), Edge(vertices[4], vertices[5]), ] graph0 = Graph() for vertex in vertices: graph0.addVertex(vertex) for edge in edges: graph0.addEdge(edge) graph0.updateConnectivityValues() import cPickle graph = cPickle.loads(cPickle.dumps(graph0)) self.assertEqual(len(graph0.vertices), len(graph.vertices)) for v1, v2 in zip(graph0.vertices, graph.vertices): self.assertEqual(v1.connectivity1, v2.connectivity1) self.assertEqual(v1.connectivity2, v2.connectivity2) self.assertEqual(v1.connectivity3, v2.connectivity3) self.assertEqual(v1.sortingLabel, v2.sortingLabel) self.assertEqual(len(v1.edges), len(v2.edges)) self.assertTrue(graph0.isIsomorphic(graph)) self.assertTrue(graph.isIsomorphic(graph0))
def test_copy(self): """ Test the graph copy function to ensure a complete copy of the graph is made while preserving vertices and edges. """ vertices = [Vertex() for i in range(6)] edges = [ Edge(vertices[0], vertices[1]), Edge(vertices[1], vertices[2]), Edge(vertices[2], vertices[3]), Edge(vertices[3], vertices[4]), Edge(vertices[4], vertices[5]), ] graph = Graph() for vertex in vertices: graph.addVertex(vertex) for edge in edges: graph.addEdge(edge) graph2 = graph.copy() for vertex in graph.vertices: self.assertTrue(graph2.hasVertex(vertex)) for v1 in graph.vertices: for v2 in v1.edges: self.assertTrue(graph2.hasEdge(v1, v2)) self.assertTrue(graph2.hasEdge(v2, v1)) self.assertTrue(graph2.isIsomorphic(graph)) self.assertTrue(graph.isIsomorphic(graph2))
def test_isomorphism_disconnected(self): """ Check the graph isomorphism for broken graphs. This tries to match graphs with a missing bond, eg. [ 0-1-2-3-4 5 ] should match [ 0-1-2-3-4 5 ] """ vertices1 = [Vertex() for i in range(6)] edges1 = [ Edge(vertices1[0], vertices1[1]), Edge(vertices1[1], vertices1[2]), Edge(vertices1[2], vertices1[3]), Edge(vertices1[3], vertices1[4]), #Edge(vertices1[4], vertices1[5]), ] vertices2 = [Vertex() for i in range(6)] edges2 = [ Edge(vertices2[0], vertices2[1]), Edge(vertices2[1], vertices2[2]), Edge(vertices2[2], vertices2[3]), Edge(vertices2[3], vertices2[4]), #Edge(vertices2[4], vertices2[5]), ] graph1 = Graph() for vertex in vertices1: graph1.addVertex(vertex) for edge in edges1: graph1.addEdge(edge) graph2 = Graph() for vertex in vertices2: graph2.addVertex(vertex) for edge in edges2: graph2.addEdge(edge) self.assertTrue(graph1.isIsomorphic(graph2)) self.assertTrue(graph1.isSubgraphIsomorphic(graph2)) self.assertTrue(graph2.isIsomorphic(graph1)) self.assertTrue(graph2.isSubgraphIsomorphic(graph1)) self.assertTrue(len(graph1.findSubgraphIsomorphisms(graph2)) > 0)
def isIsomorphic(self, other, initialMap=None, generateInitialMap=False, saveOrder=False, strict=True): """ Returns :data:`True` if two graphs are isomorphic and :data:`False` otherwise. The `initialMap` attribute can be used to specify a required mapping from `self` to `other` (i.e. the atoms of `self` are the keys, while the atoms of `other` are the values). The `other` parameter must be a :class:`Graph` object, or a :class:`TypeError` is raised. Also ensures multiplicities are also equal. Args: initialMap (dict, optional): initial atom mapping to use generateInitialMap (bool, optional): if ``True``, initialize map by pairing atoms with same labels saveOrder (bool, optional): if ``True``, reset atom order after performing atom isomorphism strict (bool, optional): if ``False``, perform isomorphism ignoring electrons """ # It only makes sense to compare a Molecule to a Molecule for full # isomorphism, so raise an exception if this is not what was requested if not isinstance(other, Graph): raise TypeError( 'Got a {0} object for parameter "other", when a Molecule object is required.' .format(other.__class__)) # Do the quick isomorphism comparison using the fingerprint # Two fingerprint strings matching is a necessary (but not # sufficient!) condition for the associated molecules to be isomorphic if self.fingerprint != other.fingerprint: return False # check multiplicity if self.multiplicity != other.multiplicity: return False if generateInitialMap: initialMap = dict() for atom in self.vertices: if atom.label and atom.label != '': for a in other.vertices: if a.label == atom.label: initialMap[atom] = a break else: return False if not self.isMappingValid(other, initialMap, equivalent=True): return False # Do the full isomorphism comparison result = Graph.isIsomorphic(self, other, initialMap, saveOrder=saveOrder, strict=strict) return result
def test_subgraphIsomorphism(self): """ Check the subgraph isomorphism functions. """ vertices1 = [Vertex() for i in range(6)] edges1 = [ Edge(vertices1[0], vertices1[1]), Edge(vertices1[1], vertices1[2]), Edge(vertices1[2], vertices1[3]), Edge(vertices1[3], vertices1[4]), Edge(vertices1[4], vertices1[5]), ] vertices2 = [Vertex() for i in range(2)] edges2 = [ Edge(vertices2[0], vertices2[1]), ] graph1 = Graph() for vertex in vertices1: graph1.addVertex(vertex) for edge in edges1: graph1.addEdge(edge) graph2 = Graph() for vertex in vertices2: graph2.addVertex(vertex) for edge in edges2: graph2.addEdge(edge) self.assertFalse(graph1.isIsomorphic(graph2)) self.assertFalse(graph2.isIsomorphic(graph1)) self.assertTrue(graph1.isSubgraphIsomorphic(graph2)) mapList = graph1.findSubgraphIsomorphisms(graph2) self.assertTrue(len(mapList) == 10) for mapping in mapList: self.assertTrue(graph1.isMappingValid(graph2, mapping)) self.assertTrue(graph1.isMappingValid(graph2, mapping))
def test_subgraphIsomorphism(self): """ Check the subgraph isomorphism functions. """ vertices1 = [Vertex() for i in range(6)] edges1 = [ Edge(vertices1[0], vertices1[1]), Edge(vertices1[1], vertices1[2]), Edge(vertices1[2], vertices1[3]), Edge(vertices1[3], vertices1[4]), Edge(vertices1[4], vertices1[5]), ] vertices2 = [Vertex() for i in range(2)] edges2 = [Edge(vertices2[0], vertices2[1])] graph1 = Graph() for vertex in vertices1: graph1.addVertex(vertex) for edge in edges1: graph1.addEdge(edge) graph2 = Graph() for vertex in vertices2: graph2.addVertex(vertex) for edge in edges2: graph2.addEdge(edge) self.assertFalse(graph1.isIsomorphic(graph2)) self.assertFalse(graph2.isIsomorphic(graph1)) self.assertTrue(graph1.isSubgraphIsomorphic(graph2)) mapList = graph1.findSubgraphIsomorphisms(graph2) self.assertTrue(len(mapList) == 10) for mapping in mapList: self.assertTrue(graph1.isMappingValid(graph2, mapping)) self.assertTrue(graph1.isMappingValid(graph2, mapping))