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