Beispiel #1
0
def generate_buckets(vertices, bits, max_edges, num_ops, verify_isomorphism):

    buckets = {}
    matrix = np.fromfunction(graph_util.gen_is_edge_fn(bits),
                             (vertices, vertices),
                             dtype=np.int8)
    if (not graph_util.is_full_dag(matrix)
            or graph_util.num_edges(matrix) > max_edges):
        return

    # Iterate through all possible labelings
    for labeling in itertools.product(
            *[range(num_ops) for _ in range(vertices - 2)]):
        labeling = [-1] + list(labeling) + [-2]
        fingerprint = graph_util.hash_module(matrix, labeling)

        if fingerprint not in buckets:
            buckets[fingerprint] = (matrix.tolist(), labeling)

        # This catches the "false positive" case of two models which are not
        # isomorphic hashing to the same bucket.
        elif verify_isomorphism:
            canonical_graph = buckets[fingerprint]
            if not graph_util.is_isomorphic(
                (matrix.tolist(), labeling), canonical_graph):
                logging.fatal(
                    'Matrix:\n%s\nLabel: %s\nis not isomorphic to'
                    ' canonical matrix:\n%s\nLabel: %s', str(matrix),
                    str(labeling), str(canonical_graph[0]),
                    str(canonical_graph[1]))
                sys.exit()
    return buckets
Beispiel #2
0
def generate_graph(max_vertices, max_edges, num_ops, verify_isomorphism,
                   output_file):

    FLAGS = Namespace(max_vertices=max_vertices,
                      num_ops=num_ops,
                      max_edges=max_edges,
                      verify_isomorphism=verify_isomorphism,
                      output_file=output_file)

    total_graphs = 0  # Total number of graphs (including isomorphisms)
    # hash --> (matrix, label) for the canonical graph associated with each hash
    buckets = {}

    logging.info('Using %d vertices, %d op labels, max %d edges',
                 FLAGS.max_vertices, FLAGS.num_ops, FLAGS.max_edges)
    for vertices in range(2, FLAGS.max_vertices + 1):
        for bits in range(2**(vertices * (vertices - 1) // 2)):
            # Construct adj matrix from bit string
            matrix = np.fromfunction(graph_util.gen_is_edge_fn(bits),
                                     (vertices, vertices),
                                     dtype=np.int8)

            # Discard any graphs which can be pruned or exceed constraints
            if (not graph_util.is_full_dag(matrix)
                    or graph_util.num_edges(matrix) > FLAGS.max_edges):
                continue

            # Iterate through all possible labelings
            for labeling in itertools.product(
                    *[range(FLAGS.num_ops) for _ in range(vertices - 2)]):
                total_graphs += 1
                labeling = [-1] + list(labeling) + [-2]
                fingerprint = graph_util.hash_module(matrix, labeling)

                if fingerprint not in buckets:
                    buckets[fingerprint] = (matrix.tolist(), labeling)

                # This catches the "false positive" case of two models which are not
                # isomorphic hashing to the same bucket.
                elif FLAGS.verify_isomorphism:
                    canonical_graph = buckets[fingerprint]
                    if not graph_util.is_isomorphic(
                        (matrix.tolist(), labeling), canonical_graph):
                        logging.fatal(
                            'Matrix:\n%s\nLabel: %s\nis not isomorphic to'
                            ' canonical matrix:\n%s\nLabel: %s', str(matrix),
                            str(labeling), str(canonical_graph[0]),
                            str(canonical_graph[1]))
                        sys.exit()

        logging.info('Up to %d vertices: %d graphs (%d without hashing)',
                     vertices, len(buckets), total_graphs)

    with open(FLAGS.output_file, 'w') as f:
        json.dump(buckets, f, sort_keys=True)
Beispiel #3
0
  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)))
Beispiel #4
0
def main(_):
    total_graphs = 0  # Total number of graphs (including isomorphisms)
    total_unlabeled_graphs = 0  # Total number of unlabeled graphs
    # hash --> (matrix, label) for the canonical graph associated with each hash
    buckets = {}

    logging.info('Using %d vertices, %d op labels, min %d max %d edges',
                 FLAGS.max_vertices, FLAGS.num_ops, FLAGS.min_edges,
                 FLAGS.max_edges)
    for vertices in range(FLAGS.min_vertices, FLAGS.max_vertices + 1):
        for bits in range(2**(vertices * (vertices - 1) // 2)):
            if bits % 100000 == 0:
                print('bits:', bits)

            # Construct adj matrix from bit string
            matrix = np.fromfunction(graph_util.gen_is_edge_fn(bits),
                                     (vertices, vertices),
                                     dtype=np.int8)

            # Discard any graphs which can be pruned or exceed constraints
            if (not graph_util.is_full_dag(matrix)
                    or graph_util.num_edges(matrix) > FLAGS.max_edges
                    or graph_util.num_edges(matrix) < FLAGS.min_edges):

                continue

            # this step should be redundant with is_full_dag()
            if graph_util.hanging_edge(matrix):
                print(np.array(matrix))
                continue

            print('found valid ulabeled graph')
            print(matrix)
            total_unlabeled_graphs += 1

            # Iterate through all possible labelings
            for labeling in itertools.product(
                    *[range(FLAGS.num_ops) for _ in range(vertices - 2)]):
                total_graphs += 1
                labeling = [-1] + list(labeling) + [-2]
                fingerprint = graph_util.hash_module(matrix, labeling)

                # todo: check if hash is in nasbench
                if fingerprint not in buckets:
                    buckets[fingerprint] = (matrix.tolist(), labeling)

                # This catches the "false positive" case of two models which are not
                # isomorphic hashing to the same bucket.
                elif FLAGS.verify_isomorphism:
                    canonical_graph = buckets[fingerprint]
                    if not graph_util.is_isomorphic(
                        (matrix.tolist(), labeling), canonical_graph):
                        logging.fatal(
                            'Matrix:\n%s\nLabel: %s\nis not isomorphic to'
                            ' canonical matrix:\n%s\nLabel: %s', str(matrix),
                            str(labeling), str(canonical_graph[0]),
                            str(canonical_graph[1]))
                        sys.exit()

        logging.info('Up to %d vertices: %d graphs (%d without hashing)',
                     vertices, len(buckets), total_graphs)
        logging.info('%d unlabeled graphs', total_unlabeled_graphs)

    print('finished')

    with tf.io.gfile.GFile(FLAGS.output_file, 'w') as f:
        print('outputting now to ', FLAGS.output_file)
        json.dump(buckets, f, sort_keys=True)