PageRenderTime 65ms CodeModel.GetById 17ms app.highlight 42ms RepoModel.GetById 2ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/graph/read_dimacs.hpp

http://hadesmem.googlecode.com/
C++ Header | 312 lines | 206 code | 56 blank | 50 comment | 42 complexity | 75e3bae670bda8253b7750a1a426055b MD5 | raw file
  1//=======================================================================
  2// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
  3// Authors: Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee
  4//
  5// Distributed under the Boost Software License, Version 1.0. (See
  6// accompanying file LICENSE_1_0.txt or copy at
  7// http://www.boost.org/LICENSE_1_0.txt)
  8//=======================================================================
  9
 10/*
 11  Reads maximal flow problem in extended DIMACS format.
 12  This works, but could use some polishing.
 13*/
 14
 15/* ----------------------------------------------------------------- */
 16
 17#ifndef BOOST_GRAPH_READ_DIMACS_HPP
 18#define BOOST_GRAPH_READ_DIMACS_HPP
 19
 20#include <vector>
 21#include <iostream>
 22#include <string>
 23#include <cstdio>
 24#include <cstring>
 25#include <cstdlib>
 26
 27#include <boost/graph/graph_traits.hpp>
 28
 29namespace boost {
 30
 31  namespace detail {
 32
 33template <class Graph, class CapacityMap, class ReverseEdgeMap>
 34int read_dimacs_max_flow_internal(Graph& g,
 35                                  CapacityMap capacity,
 36                                  ReverseEdgeMap reverse_edge,
 37                                  typename graph_traits<Graph>::vertex_descriptor& src,
 38                                  typename graph_traits<Graph>::vertex_descriptor& sink,
 39                                  std::istream& in,
 40                                  bool require_source_and_sink,
 41                                  const std::string& problem_type)
 42{
 43  //  const int MAXLINE = 100;      /* max line length in the input file */
 44  const int ARC_FIELDS = 3;     /* no of fields in arc line  */
 45  const int NODE_FIELDS = 2;    /* no of fields in node line  */
 46  const int P_FIELDS = 3;       /* no of fields in problem line */
 47
 48  typedef typename graph_traits<Graph>::vertices_size_type vertices_size_type;
 49  typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
 50  typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
 51
 52  std::vector<vertex_descriptor> verts;
 53
 54  long m, n,                    /*  number of edges and nodes */
 55    i, head, tail, cap;
 56
 57  long no_lines=0,              /* no of current input line */
 58    no_plines=0,                /* no of problem-lines */
 59    no_nslines=0,               /* no of node-source-lines */
 60    no_nklines=0,               /* no of node-source-lines */
 61    no_alines=0;                /* no of arc-lines */
 62
 63  std::string in_line;          /* for reading input line */
 64  char pr_type[4];              /* for reading type of the problem */
 65  char nd;                      /* source (s) or sink (t) */
 66
 67  int k,                        /* temporary */
 68    err_no;                     /* no of detected error */
 69
 70  /* -------------- error numbers & error messages ---------------- */
 71  const int EN1   = 0;
 72  const int EN2   = 1;
 73  const int EN3   = 2;
 74  const int EN4   = 3;
 75  //  const int EN6   = 4;
 76  //  const int EN10  = 5;
 77  //  const int EN7   = 6;
 78  const int EN8   = 7;
 79  const int EN9   = 8;
 80  const int EN11  = 9;
 81  const int EN12 = 10;
 82  //  const int EN13 = 11;
 83  const int EN14 = 12;
 84  const int EN16 = 13;
 85  const int EN15 = 14;
 86  const int EN17 = 15;
 87  const int EN18 = 16;
 88  const int EN21 = 17;
 89  const int EN19 = 18;
 90  const int EN20 = 19;
 91  const int EN22 = 20;
 92
 93  static const char *err_message[] =
 94  {
 95    /* 0*/    "more than one problem line.",
 96    /* 1*/    "wrong number of parameters in the problem line.",
 97    /* 2*/    "it is not a Max Flow problem line.",
 98    /* 3*/    "bad value of a parameter in the problem line.",
 99    /* 4*/    "can't obtain enough memory to solve this problem.",
100    /* 5*/    "more than one line with the problem name.",
101    /* 6*/    "can't read problem name.",
102    /* 7*/    "problem description must be before node description.",
103    /* 8*/    "this parser doesn't support multiply sources and sinks.",
104    /* 9*/    "wrong number of parameters in the node line.",
105    /*10*/    "wrong value of parameters in the node line.",
106    /*11*/    " ",
107    /*12*/    "source and sink descriptions must be before arc descriptions.",
108    /*13*/    "too many arcs in the input.",
109    /*14*/    "wrong number of parameters in the arc line.",
110    /*15*/    "wrong value of parameters in the arc line.",
111    /*16*/    "unknown line type in the input.",
112    /*17*/    "reading error.",
113    /*18*/    "not enough arcs in the input.",
114    /*19*/    "source or sink doesn't have incident arcs.",
115    /*20*/    "can't read anything from the input file."
116  };
117  /* --------------------------------------------------------------- */
118
119  /* The main loop:
120     -  reads the line of the input,
121     -  analyses its type,
122     -  checks correctness of parameters,
123     -  puts data to the arrays,
124     -  does service functions
125  */
126
127  while (std::getline(in, in_line)) {
128    ++no_lines;
129
130    switch (in_line[0]) {
131    case 'c':                  /* skip lines with comments */
132    case '\n':                 /* skip empty lines   */
133    case '\0':                 /* skip empty lines at the end of file */
134      break;
135
136    case 'p':                  /* problem description      */
137      if ( no_plines > 0 )
138        /* more than one problem line */
139        { err_no = EN1 ; goto error; }
140
141      no_plines = 1;
142
143      if (
144          /* reading problem line: type of problem, no of nodes, no of arcs */
145          std::sscanf ( in_line.c_str(), "%*c %3s %ld %ld", pr_type, &n, &m )
146          != P_FIELDS
147          )
148        /*wrong number of parameters in the problem line*/
149        { err_no = EN2; goto error; }
150
151      if ( pr_type != problem_type )
152        /*wrong problem type*/
153        { err_no = EN3; goto error; }
154
155      if ( n <= 0  || m <= 0 )
156        /*wrong value of no of arcs or nodes*/
157        { err_no = EN4; goto error; }
158
159      {
160        for (long vi = 0; vi < n; ++vi)
161          verts.push_back(add_vertex(g));
162      }
163      break;
164
165    case 'n':                    /* source(s) description */
166      if ( no_plines == 0 )
167        /* there was not problem line above */
168        { err_no = EN8; goto error; }
169
170      /* reading source  or sink */
171      k = std::sscanf ( in_line.c_str(),"%*c %ld %c", &i, &nd );
172      --i; // index from 0
173      if ( k < NODE_FIELDS )
174        /* node line is incorrect */
175        { err_no = EN11; goto error; }
176
177      if ( i < 0 || i > n )
178        /* wrong value of node */
179        { err_no = EN12; goto error; }
180
181      switch (nd) {
182      case 's':  /* source line */
183
184        if ( no_nslines != 0)
185          /* more than one source line */
186          { err_no = EN9; goto error; }
187
188        no_nslines = 1;
189        src = verts[i];
190        break;
191
192      case 't':  /* sink line */
193
194        if ( no_nklines != 0)
195          /* more than one sink line */
196          { err_no = EN9; goto error; }
197
198        no_nklines = 1;
199        sink = verts[i];
200        break;
201
202      default:
203        /* wrong type of node-line */
204        err_no = EN12; goto error;
205      }
206      break;
207
208    case 'a':                    /* arc description */
209      if ( require_source_and_sink && (no_nslines == 0 || no_nklines == 0) )
210        /* there was not source and sink description above */
211        { err_no = EN14; goto error; }
212
213      if ( no_alines >= m )
214        /*too many arcs on input*/
215        { err_no = EN16; goto error; }
216
217      if (
218          /* reading an arc description */
219          std::sscanf ( in_line.c_str(),"%*c %ld %ld %ld",
220                        &tail, &head, &cap )
221          != ARC_FIELDS
222          )
223        /* arc description is not correct */
224        { err_no = EN15; goto error; }
225
226      --tail; // index from 0, not 1
227      --head;
228      if ( tail < 0  ||  tail > n  ||
229           head < 0  ||  head > n
230           )
231        /* wrong value of nodes */
232        { err_no = EN17; goto error; }
233
234      {
235        edge_descriptor e1, e2;
236        bool in1, in2;
237        boost::tie(e1, in1) = add_edge(verts[tail], verts[head], g);
238        boost::tie(e2, in2) = add_edge(verts[head], verts[tail], g);
239        if (!in1 || !in2) {
240          std::cerr << "unable to add edge (" << head << "," << tail << ")"
241                    << std::endl;
242          return -1;
243        }
244        capacity[e1] = cap;
245        capacity[e2] = 0;
246        reverse_edge[e1] = e2;
247        reverse_edge[e2] = e1;
248      }
249      ++no_alines;
250      break;
251
252    default:
253      /* unknown type of line */
254      err_no = EN18; goto error;
255
256    } /* end of switch */
257  }     /* end of input loop */
258
259  /* ----- all is red  or  error while reading ----- */
260
261  if ( in.eof() == 0 ) /* reading error */
262    { err_no=EN21; goto error; }
263
264  if ( no_lines == 0 ) /* empty input */
265    { err_no = EN22; goto error; }
266
267  if ( no_alines < m ) /* not enough arcs */
268    { err_no = EN19; goto error; }
269
270  if ( require_source_and_sink &&
271       (out_degree(src, g) == 0 || out_degree(sink, g) == 0) )
272    /* no arc goes out of the source */
273    { err_no = EN20; goto error; }
274
275  /* Thanks God! all is done */
276  return (0);
277
278  /* ---------------------------------- */
279 error:  /* error found reading input */
280
281  std::printf ( "\nline %ld of input - %s\n",
282                no_lines, err_message[err_no] );
283
284  std::exit (1);
285  return (0); /* to avoid warning */
286}
287/* --------------------   end of parser  -------------------*/
288
289  } // namespace detail
290
291template <class Graph, class CapacityMap, class ReverseEdgeMap>
292int read_dimacs_max_flow(Graph& g,
293                         CapacityMap capacity,
294                         ReverseEdgeMap reverse_edge,
295                         typename graph_traits<Graph>::vertex_descriptor& src,
296                         typename graph_traits<Graph>::vertex_descriptor& sink,
297                         std::istream& in = std::cin) {
298  return detail::read_dimacs_max_flow_internal(g, capacity, reverse_edge, src, sink, in, true, "max");
299}
300
301template <class Graph, class CapacityMap, class ReverseEdgeMap>
302int read_dimacs_min_cut(Graph& g,
303                        CapacityMap capacity,
304                        ReverseEdgeMap reverse_edge,
305                        std::istream& in = std::cin) {
306  typename graph_traits<Graph>::vertex_descriptor dummy_src, dummy_sink; // Not filled in
307  return detail::read_dimacs_max_flow_internal(g, capacity, reverse_edge, dummy_src, dummy_sink, in, false, "cut");
308}
309
310} // namespace boost
311
312#endif // BOOST_GRAPH_READ_DIMACS_HPP