annotate DEPENDENCIES/generic/include/boost/graph/dimacs.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Copyright 2005 The Trustees of Indiana University.
Chris@16 2
Chris@16 3 // Use, modification and distribution is subject to the Boost Software
Chris@16 4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 5 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6
Chris@16 7 // Authors: Alex Breuer
Chris@16 8 // Andrew Lumsdaine
Chris@16 9 #ifndef BOOST_GRAPH_DIMACS_HPP
Chris@16 10 #define BOOST_GRAPH_DIMACS_HPP
Chris@16 11
Chris@16 12 #include <string>
Chris@16 13 #include <sstream>
Chris@16 14 #include <iostream>
Chris@16 15 #include <fstream>
Chris@16 16 #include <iterator>
Chris@16 17 #include <exception>
Chris@16 18 #include <vector>
Chris@16 19 #include <queue>
Chris@16 20 #include <boost/assert.hpp>
Chris@16 21
Chris@16 22 namespace boost { namespace graph {
Chris@16 23
Chris@16 24 class dimacs_exception : public std::exception {};
Chris@16 25
Chris@16 26 class dimacs_basic_reader {
Chris@16 27 public:
Chris@16 28 typedef std::size_t vertices_size_type;
Chris@16 29 typedef std::size_t edges_size_type;
Chris@16 30 typedef double vertex_weight_type;
Chris@16 31 typedef double edge_weight_type;
Chris@16 32 typedef std::pair<vertices_size_type,
Chris@16 33 vertices_size_type> edge_type;
Chris@16 34 enum incr_mode {edge, edge_weight};
Chris@16 35
Chris@16 36 dimacs_basic_reader( std::istream& in, bool want_weights = true ) :
Chris@16 37 inpt( in ), seen_edges( 0 ), want_weights(want_weights)
Chris@16 38 {
Chris@16 39 while( getline( inpt, buf ) && !buf.empty() && buf[0] == 'c' );
Chris@16 40
Chris@16 41 if( buf[0] != 'p' ) {
Chris@16 42 boost::throw_exception(dimacs_exception());
Chris@16 43 }
Chris@16 44
Chris@16 45 std::stringstream instr( buf );
Chris@16 46 std::string junk;
Chris@16 47
Chris@16 48 instr >> junk >> junk >> num_vertices >> num_edges;
Chris@16 49 read_edge_weights.push( -1 );
Chris@16 50 incr( edge_weight );
Chris@16 51 }
Chris@16 52
Chris@16 53 //for a past the end iterator
Chris@16 54 dimacs_basic_reader() : inpt( std::cin ), num_vertices( 0 ),
Chris@16 55 num_edges( 0 ), seen_edges( 0 ), want_weights(false) {}
Chris@16 56
Chris@16 57 edge_type edge_deref() {
Chris@16 58 BOOST_ASSERT( !read_edges.empty() );
Chris@16 59 return read_edges.front();
Chris@16 60 }
Chris@16 61
Chris@16 62 inline edge_type* edge_ref() {
Chris@16 63 BOOST_ASSERT( !read_edges.empty() );
Chris@16 64 return &read_edges.front();
Chris@16 65 }
Chris@16 66
Chris@16 67 inline edge_weight_type edge_weight_deref() {
Chris@16 68 BOOST_ASSERT( !read_edge_weights.empty() );
Chris@16 69 return read_edge_weights.front();
Chris@16 70 }
Chris@16 71
Chris@16 72 inline dimacs_basic_reader incr( incr_mode mode ) {
Chris@16 73 if( mode == edge ) {
Chris@16 74 BOOST_ASSERT( !read_edges.empty() );
Chris@16 75 read_edges.pop();
Chris@16 76 }
Chris@16 77 else if( mode == edge_weight ) {
Chris@16 78 BOOST_ASSERT( !read_edge_weights.empty() );
Chris@16 79 read_edge_weights.pop();
Chris@16 80 }
Chris@16 81
Chris@16 82 if( (mode == edge && read_edges.empty()) ||
Chris@16 83 (mode == edge_weight && read_edge_weights.empty() )) {
Chris@16 84
Chris@16 85 if( seen_edges > num_edges ) {
Chris@16 86 boost::throw_exception(dimacs_exception());
Chris@16 87 }
Chris@16 88
Chris@16 89 while( getline( inpt, buf ) && !buf.empty() && buf[0] == 'c' );
Chris@16 90
Chris@16 91 if( !inpt.eof() ) {
Chris@16 92 int source, dest, weight;
Chris@16 93 read_edge_line((char*) buf.c_str(), source, dest, weight);
Chris@16 94
Chris@16 95 seen_edges++;
Chris@16 96 source--;
Chris@16 97 dest--;
Chris@16 98
Chris@16 99 read_edges.push( edge_type( source, dest ) );
Chris@16 100 if (want_weights) {
Chris@16 101 read_edge_weights.push( weight );
Chris@16 102 }
Chris@16 103 }
Chris@16 104 BOOST_ASSERT( read_edges.size() < 100 );
Chris@16 105 BOOST_ASSERT( read_edge_weights.size() < 100 );
Chris@16 106 }
Chris@16 107
Chris@16 108 // the 1000000 just happens to be about how many edges can be read in
Chris@16 109 // 10s
Chris@16 110 // if( !(seen_edges % 1000000) && !process_id( pg ) && mode == edge ) {
Chris@16 111 // std::cout << "read " << seen_edges << " edges" << std::endl;
Chris@16 112 // }
Chris@16 113 return *this;
Chris@16 114 }
Chris@16 115
Chris@16 116 inline bool done_edges() {
Chris@16 117 return inpt.eof() && read_edges.size() == 0;
Chris@16 118 }
Chris@16 119
Chris@16 120 inline bool done_edge_weights() {
Chris@16 121 return inpt.eof() && read_edge_weights.size() == 0;
Chris@16 122 }
Chris@16 123
Chris@16 124 inline vertices_size_type n_vertices() {
Chris@16 125 return num_vertices;
Chris@16 126 }
Chris@16 127
Chris@16 128 inline vertices_size_type processed_edges() {
Chris@16 129 return seen_edges - read_edges.size();
Chris@16 130 }
Chris@16 131
Chris@16 132 inline vertices_size_type processed_edge_weights() {
Chris@16 133 return seen_edges - read_edge_weights.size();
Chris@16 134 }
Chris@16 135
Chris@16 136 inline vertices_size_type n_edges() {
Chris@16 137 return num_edges;
Chris@16 138 }
Chris@16 139
Chris@16 140 protected:
Chris@16 141 bool read_edge_line(char *linebuf, int &from, int &to, int &weight)
Chris@16 142 {
Chris@16 143 char *fs = NULL, *ts = NULL, *ws = NULL;
Chris@16 144 char *tmp = linebuf + 2;
Chris@16 145
Chris@16 146 fs = tmp;
Chris@16 147 if ('e' == linebuf[0]) {
Chris@16 148 while (*tmp != '\n' && *tmp != '\0') {
Chris@16 149 if (*tmp == ' ') {
Chris@16 150 *tmp = '\0';
Chris@16 151 ts = ++tmp;
Chris@16 152 break;
Chris@16 153 }
Chris@16 154 tmp++;
Chris@16 155 }
Chris@16 156 *tmp = '\0';
Chris@16 157 if (NULL == fs || NULL == ts) return false;
Chris@16 158 from = atoi(fs); to = atoi(ts); weight = 0;
Chris@16 159
Chris@16 160 } else if ('a' == linebuf[0]) {
Chris@16 161 while (*tmp != '\n' && *tmp != '\0') {
Chris@16 162 if (*tmp == ' ') {
Chris@16 163 *tmp = '\0';
Chris@16 164 ts = ++tmp;
Chris@16 165 break;
Chris@16 166 }
Chris@16 167 tmp++;
Chris@16 168 }
Chris@16 169 while (*tmp != '\n' && *tmp != '\0') {
Chris@16 170 if (*tmp == ' ') {
Chris@16 171 *tmp = '\0';
Chris@16 172 ws = ++tmp;
Chris@16 173 break;
Chris@16 174 }
Chris@16 175 tmp++;
Chris@16 176 }
Chris@16 177 while (*tmp != '\n' && *tmp != '\0') tmp++;
Chris@16 178 *tmp = '\0';
Chris@16 179 if (fs == NULL || ts == NULL || ws == NULL) return false;
Chris@16 180 from = atoi(fs); to = atoi(ts) ;
Chris@16 181 if (want_weights) weight = atoi(ws); else weight = 0;
Chris@16 182
Chris@16 183 } else {
Chris@16 184 return false;
Chris@16 185 }
Chris@16 186
Chris@16 187 return true;
Chris@16 188 }
Chris@16 189
Chris@16 190 std::queue<edge_type> read_edges;
Chris@16 191 std::queue<edge_weight_type> read_edge_weights;
Chris@16 192
Chris@16 193 std::istream& inpt;
Chris@16 194 std::string buf;
Chris@16 195 vertices_size_type num_vertices, num_edges, seen_edges;
Chris@16 196 bool want_weights;
Chris@16 197 };
Chris@16 198
Chris@16 199 template<typename T>
Chris@16 200 class dimacs_edge_iterator {
Chris@16 201 public:
Chris@16 202 typedef dimacs_basic_reader::edge_type edge_type;
Chris@16 203 typedef dimacs_basic_reader::incr_mode incr_mode;
Chris@16 204
Chris@16 205 typedef std::input_iterator_tag iterator_category;
Chris@16 206 typedef edge_type value_type;
Chris@16 207 typedef value_type reference;
Chris@16 208 typedef edge_type* pointer;
Chris@16 209 typedef std::ptrdiff_t difference_type;
Chris@16 210
Chris@16 211 dimacs_edge_iterator( T& reader ) :
Chris@16 212 reader( reader ) {}
Chris@16 213
Chris@16 214 inline dimacs_edge_iterator& operator++() {
Chris@16 215 reader.incr( dimacs_basic_reader::edge );
Chris@16 216 return *this;
Chris@16 217 }
Chris@16 218
Chris@16 219 inline edge_type operator*() {
Chris@16 220 return reader.edge_deref();
Chris@16 221 }
Chris@16 222
Chris@16 223 inline edge_type* operator->() {
Chris@16 224 return reader.edge_ref();
Chris@16 225 }
Chris@16 226
Chris@16 227 // don't expect this to do the right thing if you're not comparing against a
Chris@16 228 // general past-the-end-iterator made with the default constructor for
Chris@16 229 // dimacs_basic_reader
Chris@16 230 inline bool operator==( dimacs_edge_iterator arg ) {
Chris@16 231 if( reader.n_vertices() == 0 ) {
Chris@16 232 return arg.reader.done_edges();
Chris@16 233 }
Chris@16 234 else if( arg.reader.n_vertices() == 0 ) {
Chris@16 235 return reader.done_edges();
Chris@16 236 }
Chris@16 237 else {
Chris@16 238 return false;
Chris@16 239 }
Chris@16 240 return false;
Chris@16 241 }
Chris@16 242
Chris@16 243 inline bool operator!=( dimacs_edge_iterator arg ) {
Chris@16 244 if( reader.n_vertices() == 0 ) {
Chris@16 245 return !arg.reader.done_edges();
Chris@16 246 }
Chris@16 247 else if( arg.reader.n_vertices() == 0 ) {
Chris@16 248 return !reader.done_edges();
Chris@16 249 }
Chris@16 250 else {
Chris@16 251 return true;
Chris@16 252 }
Chris@16 253 return true;
Chris@16 254 }
Chris@16 255
Chris@16 256 private:
Chris@16 257 T& reader;
Chris@16 258 };
Chris@16 259
Chris@16 260 template<typename T>
Chris@16 261 class dimacs_edge_weight_iterator {
Chris@16 262 public:
Chris@16 263 typedef dimacs_basic_reader::edge_weight_type edge_weight_type;
Chris@16 264 typedef dimacs_basic_reader::incr_mode incr_mode;
Chris@16 265
Chris@16 266 dimacs_edge_weight_iterator( T& reader ) : reader( reader ) {}
Chris@16 267
Chris@16 268 inline dimacs_edge_weight_iterator& operator++() {
Chris@16 269 reader.incr( dimacs_basic_reader::edge_weight );
Chris@16 270 return *this;
Chris@16 271 }
Chris@16 272
Chris@16 273 inline edge_weight_type operator*() {
Chris@16 274 return reader.edge_weight_deref();
Chris@16 275 }
Chris@16 276
Chris@16 277 // don't expect this to do the right thing if you're not comparing against a
Chris@16 278 // general past-the-end-iterator made with the default constructor for
Chris@16 279 // dimacs_basic_reader
Chris@16 280 inline bool operator==( dimacs_edge_weight_iterator arg ) {
Chris@16 281 if( reader.n_vertices() == 0 ) {
Chris@16 282 return arg.reader.done_edge_weights();
Chris@16 283 }
Chris@16 284 else if( arg.reader.n_vertices() == 0 ) {
Chris@16 285 return reader.done_edge_weights();
Chris@16 286 }
Chris@16 287 else {
Chris@16 288 return false;
Chris@16 289 }
Chris@16 290 return false;
Chris@16 291 }
Chris@16 292
Chris@16 293 inline bool operator!=( dimacs_edge_weight_iterator arg ) {
Chris@16 294 if( reader.n_vertices() == 0 ) {
Chris@16 295 return !arg.reader.done_edge_weights();
Chris@16 296 }
Chris@16 297 else if( arg.reader.n_vertices() == 0 ) {
Chris@16 298 return !reader.done_edge_weights();
Chris@16 299 }
Chris@16 300 else {
Chris@16 301 return true;
Chris@16 302 }
Chris@16 303 return true;
Chris@16 304 }
Chris@16 305 private:
Chris@16 306 T& reader;
Chris@16 307 };
Chris@16 308
Chris@16 309 } } // end namespace boost::graph
Chris@16 310 #endif