File: enumerate.cc

package info (click to toggle)
bliss 0.77-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 876 kB
  • sloc: cpp: 6,505; makefile: 181; sh: 6
file content (71 lines) | stat: -rw-r--r-- 1,961 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <unordered_set>
#include <string>
#include <bliss/graph.hh>

/** \file
 * A small example that enumerates all non-isomorphic graphs of n vertices.
 * Uses the "folklore" method.
 */

/* The equals operator needed in std::unordered_set of BlissGraph*. */
struct equals {
  bool operator()(bliss::Graph* g1, bliss::Graph* g2) const {
    return g1->cmp(*g2) == 0;
  }
};

/* The hash operator needed in std::unordered_set of BlissGraph*. */
struct hash {
  unsigned int operator()(bliss::Graph* g) const {
    return g->get_hash();
  }
};

void
traverse(const unsigned int n, std::unordered_set<bliss::Graph*, hash, equals>& seen, bliss::Graph* g, unsigned int& nof_graphs) {
  // Build the canonical form of g
  bliss::Stats stats;
  bliss::Graph* g_canonical = g->permute(g->canonical_form(stats));
  // Do not expand this node if an isomorphic graph have already been expanded
  if(seen.find(g_canonical) != seen.end()) {
    delete g_canonical;
    return;
  }
  seen.insert(g_canonical);

  const unsigned int k = g->get_nof_vertices();
  if(k == n) {
    // A graph with n vertices has been generated
    nof_graphs++;
    return;
  }
  // Expand children (graphs with one more vertex)
  for(unsigned long i = 0; i < (1UL << k); i++) {
    bliss::Graph* child = g->copy();
    int v = child->add_vertex();
    for(unsigned int j = 0; j < n; j++)
      if((i >> j) & 0x01)
	child->add_edge(j, v);
    traverse(n, seen, child, nof_graphs);
    delete child;
  }
}

  
int main(const int argc, const char** argv)
{
  unsigned int n = 7;
  if(argc >= 2)
    n = std::stoi(std::string(argv[1]));
  bliss::Graph* root = new bliss::Graph();
  std::unordered_set<bliss::Graph*, hash, equals> seen;
  unsigned int nof_graphs = 0;
  traverse(n, seen, root, nof_graphs);
  printf("There are %u non-isomorphic simple graphs of %d vertices\n", nof_graphs, n);
  // Clear everything
  for(auto g: seen)
    delete g;
  seen.clear();
  delete root;
  return 0;
}