def test_permute_graph(self): # Does not have to be DAG matrix = np.array([[1, 1, 0], [0, 0, 1], [1, 0, 1]]) labels = ['a', 'b', 'c'] p1, l1 = graph_util.permute_graph(matrix, labels, [2, 0, 1]) self.assertTrue( np.array_equal(p1, np.array([[0, 1, 0], [0, 1, 1], [1, 0, 1]]))) self.assertEqual(l1, ['b', 'c', 'a']) p1, l1 = graph_util.permute_graph(matrix, labels, [0, 2, 1]) self.assertTrue( np.array_equal(p1, np.array([[1, 0, 1], [1, 1, 0], [0, 1, 0]]))) self.assertEqual(l1, ['a', 'c', 'b'])
def test_random_isomorphism_hashing(self): # Tests that hash_module always provides the same hash for randomly # generated isomorphic graphs. for _ in range(1000): # Generate random graph. Note: the algorithm works (i.e. same hash == # isomorphic graphs) for all directed graphs with coloring and does not # require the graph to be a DAG. size = random.randint(3, 20) matrix = np.random.randint(0, 2, [size, size]) labels = [random.randint(0, 10) for _ in range(size)] # Generate permutation of matrix and labels. perm = np.random.permutation(size).tolist() pmatrix, plabels = graph_util.permute_graph(matrix, labels, perm) # Hashes should be identical. hash1 = graph_util.hash_module(matrix, labels) hash2 = graph_util.hash_module(pmatrix, plabels) self.assertEqual(hash1, hash2)
def test_is_isomorphic(self): # Reuse some tests from hash_module matrix1 = np.array( [[0, 1, 1, 0,], [0, 0, 0, 1], [0, 0, 0, 1], [0, 0, 0, 0]]) label1 = [-1, 1, 2, -2] label2 = [-1, 2, 1, -2] self.assertTrue(graph_util.is_isomorphic((matrix1, label1), (matrix1, label2))) # Simple graph with edge permutation matrix1 = np.array( [[0, 1, 1, 0, 0], [0, 0, 0, 0, 1], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1], [0, 0, 0, 0, 0]]) label1 = [-1, 1, 2, 3, -2] matrix2 = np.array( [[0, 1, 0, 1, 0], [0, 0, 1, 0, 0], [0, 0, 0, 0, 1], [0, 0, 0, 0, 1], [0, 0, 0, 0, 0]]) label2 = [-1, 2, 3, 1, -2] matrix3 = np.array( [[0, 1, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1], [0, 0, 0, 0, 1], [0, 0, 0, 0, 0]]) label3 = [-1, 2, 1, 3, -2] self.assertTrue(graph_util.is_isomorphic((matrix1, label1), (matrix2, label2))) self.assertTrue(graph_util.is_isomorphic((matrix1, label1), (matrix3, label3))) self.assertFalse(graph_util.is_isomorphic((matrix1, label1), (matrix2, label1))) # Connected non-isomorphic regular graphs on 6 interior vertices (8 total) matrix1 = np.array( [[0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 0, 0, 1, 0], [0, 0, 0, 0, 1, 1, 0, 0], [0, 0, 0, 0, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0]]) matrix2 = np.array( [[0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0], [0, 0, 0, 0, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0]]) label1 = [-1, 1, 1, 1, 1, 1, 1, -2] self.assertFalse(graph_util.is_isomorphic((matrix1, label1), (matrix2, label1))) # Connected isomorphic regular graphs on 8 total vertices (bipartite) matrix1 = np.array( [[0, 0, 0, 0, 1, 1, 1, 0], [0, 0, 0, 0, 1, 1, 0, 1], [0, 0, 0, 0, 1, 0, 1, 1], [0, 0, 0, 0, 0, 1, 1, 1], [1, 1, 1, 0, 0, 0, 0, 0], [1, 1, 0, 1, 0, 0, 0, 0], [1, 0, 1, 1, 0, 0, 0, 0], [0, 1, 1, 1, 0, 0, 0, 0]]) matrix2 = np.array( [[0, 1, 0, 1, 1, 0, 0, 0], [1, 0, 1, 0, 0, 1, 0, 0], [0, 1, 0, 1, 0, 0, 1, 0], [1, 0, 1, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 1, 0, 1], [0, 1, 0, 0, 1, 0, 1, 0], [0, 0, 1, 0, 0, 1, 0, 1], [0, 0, 0, 1, 1, 0, 1, 0]]) label1 = [1, 1, 1, 1, 1, 1, 1, 1] # Sanity check: manual permutation perm = [0, 5, 7, 2, 4, 1, 3, 6] pm1, pl1 = graph_util.permute_graph(matrix1, label1, perm) self.assertTrue(np.array_equal(matrix2, pm1)) self.assertEqual(pl1, label1) self.assertTrue(graph_util.is_isomorphic((matrix1, label1), (matrix2, label1))) label2 = [1, 1, 1, 1, 2, 2, 2, 2] label3 = [1, 2, 1, 2, 2, 1, 2, 1] self.assertTrue(graph_util.is_isomorphic((matrix1, label2), (matrix2, label3)))