deba@360: /* -*- mode: C++; indent-tabs-mode: nil; -*- deba@360: * deba@360: * This file is a part of LEMON, a generic C++ optimization library. deba@360: * alpar@463: * Copyright (C) 2003-2009 deba@360: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport deba@360: * (Egervary Research Group on Combinatorial Optimization, EGRES). deba@360: * deba@360: * Permission to use, modify and distribute this software is granted deba@360: * provided that this copyright notice appears in all copies. For deba@360: * precise terms see the accompanying LICENSE file. deba@360: * deba@360: * This software is provided "AS IS" with no warranty of any kind, deba@360: * express or implied, and with no claim as to its suitability for any deba@360: * purpose. deba@360: * deba@360: */ deba@360: deba@360: #ifndef LEMON_NAUTY_READER_H deba@360: #define LEMON_NAUTY_READER_H deba@360: deba@360: #include deba@360: #include deba@360: #include deba@360: deba@360: /// \ingroup nauty_group deba@360: /// \file deba@360: /// \brief Nauty file reader. kpeter@363: deba@360: namespace lemon { deba@360: deba@360: /// \ingroup nauty_group deba@360: /// deba@360: /// \brief Nauty file reader deba@360: /// deba@360: /// The \e geng program is in the \e gtools suite of the nauty deba@360: /// package. This tool can generate all non-isomorphic undirected kpeter@364: /// graphs of several classes with given node number (e.g. deba@360: /// general, connected, biconnected, triangle-free, 4-cycle-free, deba@360: /// bipartite and graphs with given edge number and degree kpeter@370: /// constraints). This function reads a \e nauty \e graph6 \e format deba@360: /// line from the given stream and builds it in the given graph. deba@360: /// deba@360: /// The site of nauty package: http://cs.anu.edu.au/~bdm/nauty/ deba@360: /// kpeter@364: /// For example, the number of all non-isomorphic planar graphs kpeter@364: /// can be computed with the following code. deba@360: ///\code deba@360: /// int num = 0; deba@360: /// SmartGraph graph; kpeter@371: /// while (readNautyGraph(graph, std::cin)) { deba@362: /// PlanarityChecking pc(graph); deba@360: /// if (pc.run()) ++num; deba@360: /// } deba@360: /// std::cout << "Number of planar graphs: " << num << std::endl; deba@360: ///\endcode deba@360: /// deba@360: /// The nauty files are quite huge, therefore instead of the direct kpeter@364: /// file generation pipelining is recommended. For example, deba@360: ///\code kpeter@364: /// ./geng -c 10 | ./num_of_planar_graphs deba@360: ///\endcode deba@360: template kpeter@371: std::istream& readNautyGraph(Graph& graph, std::istream& is = std::cin) { deba@360: graph.clear(); deba@360: deba@360: std::string line; deba@360: if (getline(is, line)) { deba@360: int index = 0; deba@360: deba@360: int n; deba@360: deba@360: if (line[index] == '>') { deba@360: index += 10; deba@360: } deba@360: deba@360: char c = line[index++]; c -= 63; deba@360: if (c != 63) { deba@360: n = int(c); deba@360: } else { deba@360: c = line[index++]; c -= 63; deba@360: n = (int(c) << 12); deba@360: c = line[index++]; c -= 63; deba@360: n |= (int(c) << 6); deba@360: c = line[index++]; c -= 63; deba@360: n |= int(c); deba@360: } deba@360: deba@360: std::vector nodes; deba@360: for (int i = 0; i < n; ++i) { deba@360: nodes.push_back(graph.addNode()); deba@360: } deba@360: deba@360: int bit = -1; deba@360: for (int j = 0; j < n; ++j) { deba@360: for (int i = 0; i < j; ++i) { deba@360: if (bit == -1) { deba@360: c = line[index++]; c -= 63; deba@360: bit = 5; deba@360: } deba@360: bool b = (c & (1 << (bit--))) != 0; deba@360: deba@360: if (b) { deba@360: graph.addEdge(nodes[i], nodes[j]); deba@360: } deba@360: } deba@360: } deba@360: } deba@360: return is; deba@360: } deba@360: } deba@360: deba@360: #endif