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
|