Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:37:26

0001 // Copyright 2005 The Trustees of Indiana University.
0002 
0003 // Use, modification and distribution is subject to the Boost Software
0004 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 //  Authors: Alex Breuer
0008 //           Andrew Lumsdaine
0009 #ifndef BOOST_GRAPH_DIMACS_HPP
0010 #define BOOST_GRAPH_DIMACS_HPP
0011 
0012 #include <string>
0013 #include <sstream>
0014 #include <iostream>
0015 #include <fstream>
0016 #include <iterator>
0017 #include <exception>
0018 #include <vector>
0019 #include <queue>
0020 #include <boost/assert.hpp>
0021 
0022 namespace boost
0023 {
0024 namespace graph
0025 {
0026 
0027     class BOOST_SYMBOL_VISIBLE dimacs_exception : public std::exception
0028     {
0029     };
0030 
0031     class dimacs_basic_reader
0032     {
0033     public:
0034         typedef std::size_t vertices_size_type;
0035         typedef std::size_t edges_size_type;
0036         typedef double vertex_weight_type;
0037         typedef double edge_weight_type;
0038         typedef std::pair< vertices_size_type, vertices_size_type > edge_type;
0039         enum incr_mode
0040         {
0041             edge,
0042             edge_weight
0043         };
0044 
0045         dimacs_basic_reader(std::istream& in, bool want_weights = true)
0046         : inpt(in), seen_edges(0), want_weights(want_weights)
0047         {
0048             while (getline(inpt, buf) && !buf.empty() && buf[0] == 'c')
0049                 ;
0050 
0051             if (buf[0] != 'p')
0052             {
0053                 boost::throw_exception(dimacs_exception());
0054             }
0055 
0056             std::stringstream instr(buf);
0057             std::string junk;
0058 
0059             instr >> junk >> junk >> num_vertices >> num_edges;
0060             read_edge_weights.push(-1);
0061             incr(edge_weight);
0062         }
0063 
0064         // for a past the end iterator
0065         dimacs_basic_reader()
0066         : inpt(std::cin)
0067         , num_vertices(0)
0068         , num_edges(0)
0069         , seen_edges(0)
0070         , want_weights(false)
0071         {
0072         }
0073 
0074         edge_type edge_deref()
0075         {
0076             BOOST_ASSERT(!read_edges.empty());
0077             return read_edges.front();
0078         }
0079 
0080         inline edge_type* edge_ref()
0081         {
0082             BOOST_ASSERT(!read_edges.empty());
0083             return &read_edges.front();
0084         }
0085 
0086         inline edge_weight_type edge_weight_deref()
0087         {
0088             BOOST_ASSERT(!read_edge_weights.empty());
0089             return read_edge_weights.front();
0090         }
0091 
0092         inline dimacs_basic_reader incr(incr_mode mode)
0093         {
0094             if (mode == edge)
0095             {
0096                 BOOST_ASSERT(!read_edges.empty());
0097                 read_edges.pop();
0098             }
0099             else if (mode == edge_weight)
0100             {
0101                 BOOST_ASSERT(!read_edge_weights.empty());
0102                 read_edge_weights.pop();
0103             }
0104 
0105             if ((mode == edge && read_edges.empty())
0106                 || (mode == edge_weight && read_edge_weights.empty()))
0107             {
0108 
0109                 if (seen_edges > num_edges)
0110                 {
0111                     boost::throw_exception(dimacs_exception());
0112                 }
0113 
0114                 while (getline(inpt, buf) && !buf.empty() && buf[0] == 'c')
0115                     ;
0116 
0117                 if (!inpt.eof())
0118                 {
0119                     int source, dest, weight;
0120                     read_edge_line((char*)buf.c_str(), source, dest, weight);
0121 
0122                     seen_edges++;
0123                     source--;
0124                     dest--;
0125 
0126                     read_edges.push(edge_type(source, dest));
0127                     if (want_weights)
0128                     {
0129                         read_edge_weights.push(weight);
0130                     }
0131                 }
0132                 BOOST_ASSERT(read_edges.size() < 100);
0133                 BOOST_ASSERT(read_edge_weights.size() < 100);
0134             }
0135 
0136             // the 1000000 just happens to be about how many edges can be read
0137             // in 10s
0138             //     if( !(seen_edges % 1000000) && !process_id( pg ) && mode ==
0139             //     edge ) {
0140             //       std::cout << "read " << seen_edges << " edges" <<
0141             //       std::endl;
0142             //     }
0143             return *this;
0144         }
0145 
0146         inline bool done_edges()
0147         {
0148             return inpt.eof() && read_edges.size() == 0;
0149         }
0150 
0151         inline bool done_edge_weights()
0152         {
0153             return inpt.eof() && read_edge_weights.size() == 0;
0154         }
0155 
0156         inline vertices_size_type n_vertices() { return num_vertices; }
0157 
0158         inline vertices_size_type processed_edges()
0159         {
0160             return seen_edges - read_edges.size();
0161         }
0162 
0163         inline vertices_size_type processed_edge_weights()
0164         {
0165             return seen_edges - read_edge_weights.size();
0166         }
0167 
0168         inline vertices_size_type n_edges() { return num_edges; }
0169 
0170     protected:
0171         bool read_edge_line(char* linebuf, int& from, int& to, int& weight)
0172         {
0173             char *fs = NULL, *ts = NULL, *ws = NULL;
0174             char* tmp = linebuf + 2;
0175 
0176             fs = tmp;
0177             if ('e' == linebuf[0])
0178             {
0179                 while (*tmp != '\n' && *tmp != '\0')
0180                 {
0181                     if (*tmp == ' ')
0182                     {
0183                         *tmp = '\0';
0184                         ts = ++tmp;
0185                         break;
0186                     }
0187                     tmp++;
0188                 }
0189                 *tmp = '\0';
0190                 if (NULL == fs || NULL == ts)
0191                     return false;
0192                 from = atoi(fs);
0193                 to = atoi(ts);
0194                 weight = 0;
0195             }
0196             else if ('a' == linebuf[0])
0197             {
0198                 while (*tmp != '\n' && *tmp != '\0')
0199                 {
0200                     if (*tmp == ' ')
0201                     {
0202                         *tmp = '\0';
0203                         ts = ++tmp;
0204                         break;
0205                     }
0206                     tmp++;
0207                 }
0208                 while (*tmp != '\n' && *tmp != '\0')
0209                 {
0210                     if (*tmp == ' ')
0211                     {
0212                         *tmp = '\0';
0213                         ws = ++tmp;
0214                         break;
0215                     }
0216                     tmp++;
0217                 }
0218                 while (*tmp != '\n' && *tmp != '\0')
0219                     tmp++;
0220                 *tmp = '\0';
0221                 if (fs == NULL || ts == NULL || ws == NULL)
0222                     return false;
0223                 from = atoi(fs);
0224                 to = atoi(ts);
0225                 if (want_weights)
0226                     weight = atoi(ws);
0227                 else
0228                     weight = 0;
0229             }
0230             else
0231             {
0232                 return false;
0233             }
0234 
0235             return true;
0236         }
0237 
0238         std::queue< edge_type > read_edges;
0239         std::queue< edge_weight_type > read_edge_weights;
0240 
0241         std::istream& inpt;
0242         std::string buf;
0243         vertices_size_type num_vertices, num_edges, seen_edges;
0244         bool want_weights;
0245     };
0246 
0247     template < typename T > class dimacs_edge_iterator
0248     {
0249     public:
0250         typedef dimacs_basic_reader::edge_type edge_type;
0251         typedef dimacs_basic_reader::incr_mode incr_mode;
0252 
0253         typedef std::input_iterator_tag iterator_category;
0254         typedef edge_type value_type;
0255         typedef value_type reference;
0256         typedef edge_type* pointer;
0257         typedef std::ptrdiff_t difference_type;
0258 
0259         dimacs_edge_iterator(T& reader) : reader(reader) {}
0260 
0261         inline dimacs_edge_iterator& operator++()
0262         {
0263             reader.incr(dimacs_basic_reader::edge);
0264             return *this;
0265         }
0266 
0267         inline edge_type operator*() { return reader.edge_deref(); }
0268 
0269         inline edge_type* operator->() { return reader.edge_ref(); }
0270 
0271         // don't expect this to do the right thing if you're not comparing
0272         // against a general past-the-end-iterator made with the default
0273         // constructor for dimacs_basic_reader
0274         inline bool operator==(dimacs_edge_iterator arg)
0275         {
0276             if (reader.n_vertices() == 0)
0277             {
0278                 return arg.reader.done_edges();
0279             }
0280             else if (arg.reader.n_vertices() == 0)
0281             {
0282                 return reader.done_edges();
0283             }
0284             else
0285             {
0286                 return false;
0287             }
0288             return false;
0289         }
0290 
0291         inline bool operator!=(dimacs_edge_iterator arg)
0292         {
0293             if (reader.n_vertices() == 0)
0294             {
0295                 return !arg.reader.done_edges();
0296             }
0297             else if (arg.reader.n_vertices() == 0)
0298             {
0299                 return !reader.done_edges();
0300             }
0301             else
0302             {
0303                 return true;
0304             }
0305             return true;
0306         }
0307 
0308     private:
0309         T& reader;
0310     };
0311 
0312     template < typename T > class dimacs_edge_weight_iterator
0313     {
0314     public:
0315         typedef dimacs_basic_reader::edge_weight_type edge_weight_type;
0316         typedef dimacs_basic_reader::incr_mode incr_mode;
0317 
0318         dimacs_edge_weight_iterator(T& reader) : reader(reader) {}
0319 
0320         inline dimacs_edge_weight_iterator& operator++()
0321         {
0322             reader.incr(dimacs_basic_reader::edge_weight);
0323             return *this;
0324         }
0325 
0326         inline edge_weight_type operator*()
0327         {
0328             return reader.edge_weight_deref();
0329         }
0330 
0331         // don't expect this to do the right thing if you're not comparing
0332         // against a general past-the-end-iterator made with the default
0333         // constructor for dimacs_basic_reader
0334         inline bool operator==(dimacs_edge_weight_iterator arg)
0335         {
0336             if (reader.n_vertices() == 0)
0337             {
0338                 return arg.reader.done_edge_weights();
0339             }
0340             else if (arg.reader.n_vertices() == 0)
0341             {
0342                 return reader.done_edge_weights();
0343             }
0344             else
0345             {
0346                 return false;
0347             }
0348             return false;
0349         }
0350 
0351         inline bool operator!=(dimacs_edge_weight_iterator arg)
0352         {
0353             if (reader.n_vertices() == 0)
0354             {
0355                 return !arg.reader.done_edge_weights();
0356             }
0357             else if (arg.reader.n_vertices() == 0)
0358             {
0359                 return !reader.done_edge_weights();
0360             }
0361             else
0362             {
0363                 return true;
0364             }
0365             return true;
0366         }
0367 
0368     private:
0369         T& reader;
0370     };
0371 
0372 }
0373 } // end namespace boost::graph
0374 #endif