lemon/nauty_reader.h
author Balazs Dezso <deba@inf.elte.hu>
Wed, 29 Oct 2008 15:29:34 +0100
changeset 362 c6c6e1d863c4
parent 360 96f7cc46c91c
child 363 91e68d590e61
permissions -rw-r--r--
Swap parameters in readNauty()
deba@360
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
deba@360
     2
 *
deba@360
     3
 * This file is a part of LEMON, a generic C++ optimization library.
deba@360
     4
 *
deba@360
     5
 * Copyright (C) 2003-2008
deba@360
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@360
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@360
     8
 *
deba@360
     9
 * Permission to use, modify and distribute this software is granted
deba@360
    10
 * provided that this copyright notice appears in all copies. For
deba@360
    11
 * precise terms see the accompanying LICENSE file.
deba@360
    12
 *
deba@360
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@360
    14
 * express or implied, and with no claim as to its suitability for any
deba@360
    15
 * purpose.
deba@360
    16
 *
deba@360
    17
 */
deba@360
    18
deba@360
    19
#ifndef LEMON_NAUTY_READER_H
deba@360
    20
#define LEMON_NAUTY_READER_H
deba@360
    21
deba@360
    22
#include <vector>
deba@360
    23
#include <iostream>
deba@360
    24
#include <string>
deba@360
    25
deba@360
    26
/// \ingroup io_group
deba@360
    27
///
deba@360
    28
/// @defgroup nauty_group NAUTY format
deba@360
    29
///
deba@360
    30
/// \brief Read \e Nauty format
deba@360
    31
///
deba@360
    32
/// Tool to read graphs from \e Nauty format data
deba@360
    33
deba@360
    34
/// \ingroup nauty_group
deba@360
    35
/// \file
deba@360
    36
/// \brief Nauty file reader.
deba@360
    37
namespace lemon {
deba@360
    38
deba@360
    39
  /// \ingroup nauty_group
deba@360
    40
  ///
deba@360
    41
  /// \brief Nauty file reader
deba@360
    42
  ///
deba@360
    43
  /// The \e geng program is in the \e gtools suite of the nauty
deba@360
    44
  /// package. This tool can generate all non-isomorphic undirected
deba@360
    45
  /// graphs with given node number from several classes (for example,
deba@360
    46
  /// general, connected, biconnected, triangle-free, 4-cycle-free,
deba@360
    47
  /// bipartite and graphs with given edge number and degree
deba@360
    48
  /// constraints). This function reads a \e nauty \e graph6 \e format
deba@360
    49
  /// line from the given stream and builds it in the given graph.
deba@360
    50
  ///
deba@360
    51
  /// The site of nauty package: http://cs.anu.edu.au/~bdm/nauty/
deba@360
    52
  ///
deba@360
    53
  /// For example, the number of all non-isomorphic connected graphs
deba@360
    54
  /// can be computed with following code.
deba@360
    55
  ///\code
deba@360
    56
  /// int num = 0;
deba@360
    57
  /// SmartGraph graph;
deba@362
    58
  /// while (readNauty(graph, std::cin)) {
deba@362
    59
  ///   PlanarityChecking<SmartGraph> pc(graph);
deba@360
    60
  ///   if (pc.run()) ++num;
deba@360
    61
  /// }
deba@360
    62
  /// std::cout << "Number of planar graphs: " << num << std::endl;
deba@360
    63
  ///\endcode
deba@360
    64
  ///
deba@360
    65
  /// The nauty files are quite huge, therefore instead of the direct
deba@360
    66
  /// file generation the pipelining is recommended.
deba@360
    67
  ///\code
deba@360
    68
  /// ./geng -c 10 | ./num_of_pg
deba@360
    69
  ///\endcode
deba@360
    70
  template <typename Graph>
deba@362
    71
  std::istream& readNauty(Graph& graph, std::istream& is) {
deba@360
    72
    graph.clear();
deba@360
    73
deba@360
    74
    std::string line;
deba@360
    75
    if (getline(is, line)) {
deba@360
    76
      int index = 0;
deba@360
    77
deba@360
    78
      int n;
deba@360
    79
deba@360
    80
      if (line[index] == '>') {
deba@360
    81
        index += 10;
deba@360
    82
      }
deba@360
    83
deba@360
    84
      char c = line[index++]; c -= 63;
deba@360
    85
      if (c != 63) {
deba@360
    86
        n = int(c);
deba@360
    87
      } else {
deba@360
    88
        c = line[index++]; c -= 63;
deba@360
    89
        n = (int(c) << 12);
deba@360
    90
        c = line[index++]; c -= 63;
deba@360
    91
        n |= (int(c) << 6);
deba@360
    92
        c = line[index++]; c -= 63;
deba@360
    93
        n |= int(c);
deba@360
    94
      }
deba@360
    95
deba@360
    96
      std::vector<typename Graph::Node> nodes;
deba@360
    97
      for (int i = 0; i < n; ++i) {
deba@360
    98
        nodes.push_back(graph.addNode());
deba@360
    99
      }
deba@360
   100
deba@360
   101
      int bit = -1;
deba@360
   102
      for (int j = 0; j < n; ++j) {
deba@360
   103
        for (int i = 0; i < j; ++i) {
deba@360
   104
          if (bit == -1) {
deba@360
   105
            c = line[index++]; c -= 63;
deba@360
   106
            bit = 5;
deba@360
   107
          }
deba@360
   108
          bool b = (c & (1 << (bit--))) != 0;
deba@360
   109
deba@360
   110
          if (b) {
deba@360
   111
            graph.addEdge(nodes[i], nodes[j]);
deba@360
   112
          }
deba@360
   113
        }
deba@360
   114
      }
deba@360
   115
    }
deba@360
   116
    return is;
deba@360
   117
  }
deba@360
   118
}
deba@360
   119
deba@360
   120
#endif