gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Accept negative values as unbounded capacity in dimacs readers (#243) and some doc improvements.
0 3 0
default
3 files changed with 87 insertions and 26 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_DIMACS_H
20 20
#define LEMON_DIMACS_H
21 21

	
22 22
#include <iostream>
23 23
#include <string>
24 24
#include <vector>
25
#include <limits>
25 26
#include <lemon/maps.h>
26 27
#include <lemon/error.h>
27

	
28 28
/// \ingroup dimacs_group
29 29
/// \file
30 30
/// \brief DIMACS file format reader.
31 31

	
32 32
namespace lemon {
33 33

	
34 34
  /// \addtogroup dimacs_group
35 35
  /// @{
36 36

	
37 37
  /// DIMACS file type descriptor.
38 38
  struct DimacsDescriptor
39 39
  {
40 40
    ///File type enum
41 41
    enum Type
42 42
      {
43 43
        NONE, MIN, MAX, SP, MAT
44 44
      };
45 45
    ///The file type
46 46
    Type type;
47 47
    ///The number of nodes in the graph
48 48
    int nodeNum;
49 49
    ///The number of edges in the graph
50 50
    int edgeNum;
51 51
    int lineShift;
52 52
    /// Constructor. Sets the type to NONE.
53 53
    DimacsDescriptor() : type(NONE) {}
54 54
  };
55 55

	
56 56
  ///Discover the type of a DIMACS file
57 57

	
58
  ///It starts seeking the begining of the file for the problem type
58
  ///It starts seeking the beginning of the file for the problem type
59 59
  ///and size info. The found data is returned in a special struct
60 60
  ///that can be evaluated and passed to the appropriate reader
61 61
  ///function.
62 62
  DimacsDescriptor dimacsType(std::istream& is)
63 63
  {
64 64
    DimacsDescriptor r;
65 65
    std::string problem,str;
66 66
    char c;
67 67
    r.lineShift=0;
68 68
    while (is >> c)
69 69
      switch(c)
70 70
        {
71 71
        case 'p':
72 72
          if(is >> problem >> r.nodeNum >> r.edgeNum)
73 73
            {
74 74
              getline(is, str);
75 75
              r.lineShift++;
76 76
              if(problem=="min") r.type=DimacsDescriptor::MIN;
77 77
              else if(problem=="max") r.type=DimacsDescriptor::MAX;
78 78
              else if(problem=="sp") r.type=DimacsDescriptor::SP;
79 79
              else if(problem=="mat") r.type=DimacsDescriptor::MAT;
80 80
              else throw FormatError("Unknown problem type");
81 81
              return r;
82 82
            }
... ...
@@ -84,236 +84,285 @@
84 84
            {
85 85
              throw FormatError("Missing or wrong problem type declaration.");
86 86
            }
87 87
          break;
88 88
        case 'c':
89 89
          getline(is, str);
90 90
          r.lineShift++;
91 91
          break;
92 92
        default:
93 93
          throw FormatError("Unknown DIMACS declaration.");
94 94
        }
95 95
    throw FormatError("Missing problem type declaration.");
96 96
  }
97 97

	
98 98

	
99 99

	
100 100
  /// DIMACS minimum cost flow reader function.
101 101
  ///
102 102
  /// This function reads a minimum cost flow instance from DIMACS format,
103 103
  /// i.e. from a DIMACS file having a line starting with
104 104
  /// \code
105 105
  ///   p min
106 106
  /// \endcode
107 107
  /// At the beginning, \c g is cleared by \c g.clear(). The supply
108
  /// amount of the nodes are written to \c supply (signed). The
109
  /// lower bounds, capacities and costs of the arcs are written to
110
  /// \c lower, \c capacity and \c cost.
108
  /// amount of the nodes are written to the \c supply node map
109
  /// (they are signed values). The lower bounds, capacities and costs
110
  /// of the arcs are written to the \c lower, \c capacity and \c cost
111
  /// arc maps.
112
  ///
113
  /// If the capacity of an arc is less than the lower bound, it will
114
  /// be set to "infinite" instead. The actual value of "infinite" is
115
  /// contolled by the \c infty parameter. If it is 0 (the default value),
116
  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
117
  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
118
  /// a non-zero value, that value will be used as "infinite".
111 119
  ///
112 120
  /// If the file type was previously evaluated by dimacsType(), then
113 121
  /// the descriptor struct should be given by the \c dest parameter.
114 122
  template <typename Digraph, typename LowerMap,
115 123
            typename CapacityMap, typename CostMap,
116 124
            typename SupplyMap>
117 125
  void readDimacsMin(std::istream& is,
118 126
                     Digraph &g,
119 127
                     LowerMap& lower,
120 128
                     CapacityMap& capacity,
121 129
                     CostMap& cost,
122 130
                     SupplyMap& supply,
131
                     typename CapacityMap::Value infty = 0,
123 132
                     DimacsDescriptor desc=DimacsDescriptor())
124 133
  {
125 134
    g.clear();
126 135
    std::vector<typename Digraph::Node> nodes;
127 136
    typename Digraph::Arc e;
128 137
    std::string problem, str;
129 138
    char c;
130 139
    int i, j;
131 140
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
132 141
    if(desc.type!=DimacsDescriptor::MIN)
133 142
      throw FormatError("Problem type mismatch");
134 143

	
135 144
    nodes.resize(desc.nodeNum + 1);
136 145
    for (int k = 1; k <= desc.nodeNum; ++k) {
137 146
      nodes[k] = g.addNode();
138 147
      supply.set(nodes[k], 0);
139 148
    }
140 149

	
141 150
    typename SupplyMap::Value sup;
142 151
    typename CapacityMap::Value low;
143 152
    typename CapacityMap::Value cap;
144 153
    typename CostMap::Value co;
154
    typedef typename CapacityMap::Value Capacity;
155
    if(infty==0)
156
      infty = std::numeric_limits<Capacity>::has_infinity ?
157
        std::numeric_limits<Capacity>::infinity() :
158
        std::numeric_limits<Capacity>::max();
159

	
145 160
    while (is >> c) {
146 161
      switch (c) {
147 162
      case 'c': // comment line
148 163
        getline(is, str);
149 164
        break;
150 165
      case 'n': // node definition line
151 166
        is >> i >> sup;
152 167
        getline(is, str);
153 168
        supply.set(nodes[i], sup);
154 169
        break;
155
      case 'a': // arc (arc) definition line
170
      case 'a': // arc definition line
156 171
        is >> i >> j >> low >> cap >> co;
157 172
        getline(is, str);
158 173
        e = g.addArc(nodes[i], nodes[j]);
159 174
        lower.set(e, low);
160
        if (cap >= 0)
175
        if (cap >= low)
161 176
          capacity.set(e, cap);
162 177
        else
163
          capacity.set(e, -1);
178
          capacity.set(e, infty);
164 179
        cost.set(e, co);
165 180
        break;
166 181
      }
167 182
    }
168 183
  }
169 184

	
170 185
  template<typename Digraph, typename CapacityMap>
171 186
  void _readDimacs(std::istream& is,
172 187
                   Digraph &g,
173 188
                   CapacityMap& capacity,
174 189
                   typename Digraph::Node &s,
175 190
                   typename Digraph::Node &t,
191
                   typename CapacityMap::Value infty = 0,
176 192
                   DimacsDescriptor desc=DimacsDescriptor()) {
177 193
    g.clear();
178 194
    s=t=INVALID;
179 195
    std::vector<typename Digraph::Node> nodes;
180 196
    typename Digraph::Arc e;
181 197
    char c, d;
182 198
    int i, j;
183 199
    typename CapacityMap::Value _cap;
184 200
    std::string str;
185 201
    nodes.resize(desc.nodeNum + 1);
186 202
    for (int k = 1; k <= desc.nodeNum; ++k) {
187 203
      nodes[k] = g.addNode();
188 204
    }
205
    typedef typename CapacityMap::Value Capacity;
189 206

	
207
    if(infty==0)
208
      infty = std::numeric_limits<Capacity>::has_infinity ?
209
        std::numeric_limits<Capacity>::infinity() :
210
        std::numeric_limits<Capacity>::max();
211
 
190 212
    while (is >> c) {
191 213
      switch (c) {
192 214
      case 'c': // comment line
193 215
        getline(is, str);
194 216
        break;
195 217
      case 'n': // node definition line
196 218
        if (desc.type==DimacsDescriptor::SP) { // shortest path problem
197 219
          is >> i;
198 220
          getline(is, str);
199 221
          s = nodes[i];
200 222
        }
201 223
        if (desc.type==DimacsDescriptor::MAX) { // max flow problem
202 224
          is >> i >> d;
203 225
          getline(is, str);
204 226
          if (d == 's') s = nodes[i];
205 227
          if (d == 't') t = nodes[i];
206 228
        }
207 229
        break;
208
      case 'a': // arc (arc) definition line
209
        if (desc.type==DimacsDescriptor::SP ||
210
            desc.type==DimacsDescriptor::MAX) {
230
      case 'a': // arc definition line
231
        if (desc.type==DimacsDescriptor::SP) {
211 232
          is >> i >> j >> _cap;
212 233
          getline(is, str);
213 234
          e = g.addArc(nodes[i], nodes[j]);
214 235
          capacity.set(e, _cap);
215
        } else {
236
        } 
237
        else if (desc.type==DimacsDescriptor::MAX) {
238
          is >> i >> j >> _cap;
239
          getline(is, str);
240
          e = g.addArc(nodes[i], nodes[j]);
241
          if (_cap >= 0)
242
            capacity.set(e, _cap);
243
          else
244
            capacity.set(e, infty);
245
        }
246
        else {
216 247
          is >> i >> j;
217 248
          getline(is, str);
218 249
          g.addArc(nodes[i], nodes[j]);
219 250
        }
220 251
        break;
221 252
      }
222 253
    }
223 254
  }
224 255

	
225 256
  /// DIMACS maximum flow reader function.
226 257
  ///
227 258
  /// This function reads a maximum flow instance from DIMACS format,
228 259
  /// i.e. from a DIMACS file having a line starting with
229 260
  /// \code
230 261
  ///   p max
231 262
  /// \endcode
232 263
  /// At the beginning, \c g is cleared by \c g.clear(). The arc
233
  /// capacities are written to \c capacity and \c s and \c t are
234
  /// set to the source and the target nodes.
264
  /// capacities are written to the \c capacity arc map and \c s and
265
  /// \c t are set to the source and the target nodes.
266
  ///
267
  /// If the capacity of an arc is negative, it will
268
  /// be set to "infinite" instead. The actual value of "infinite" is
269
  /// contolled by the \c infty parameter. If it is 0 (the default value),
270
  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
271
  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
272
  /// a non-zero value, that value will be used as "infinite".
235 273
  ///
236 274
  /// If the file type was previously evaluated by dimacsType(), then
237 275
  /// the descriptor struct should be given by the \c dest parameter.
238 276
  template<typename Digraph, typename CapacityMap>
239 277
  void readDimacsMax(std::istream& is,
240 278
                     Digraph &g,
241 279
                     CapacityMap& capacity,
242 280
                     typename Digraph::Node &s,
243 281
                     typename Digraph::Node &t,
282
                     typename CapacityMap::Value infty = 0,
244 283
                     DimacsDescriptor desc=DimacsDescriptor()) {
245 284
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
246 285
    if(desc.type!=DimacsDescriptor::MAX)
247 286
      throw FormatError("Problem type mismatch");
248
    _readDimacs(is,g,capacity,s,t,desc);
287
    _readDimacs(is,g,capacity,s,t,infty,desc);
249 288
  }
250 289

	
251 290
  /// DIMACS shortest path reader function.
252 291
  ///
253 292
  /// This function reads a shortest path instance from DIMACS format,
254 293
  /// i.e. from a DIMACS file having a line starting with
255 294
  /// \code
256 295
  ///   p sp
257 296
  /// \endcode
258 297
  /// At the beginning, \c g is cleared by \c g.clear(). The arc
259
  /// lengths are written to \c length and \c s is set to the
298
  /// lengths are written to the \c length arc map and \c s is set to the
260 299
  /// source node.
261 300
  ///
262 301
  /// If the file type was previously evaluated by dimacsType(), then
263 302
  /// the descriptor struct should be given by the \c dest parameter.
264 303
  template<typename Digraph, typename LengthMap>
265 304
  void readDimacsSp(std::istream& is,
266 305
                    Digraph &g,
267 306
                    LengthMap& length,
268 307
                    typename Digraph::Node &s,
269 308
                    DimacsDescriptor desc=DimacsDescriptor()) {
270 309
    typename Digraph::Node t;
271 310
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
272 311
    if(desc.type!=DimacsDescriptor::SP)
273 312
      throw FormatError("Problem type mismatch");
274
    _readDimacs(is, g, length, s, t,desc);
313
    _readDimacs(is, g, length, s, t, 0, desc);
275 314
  }
276 315

	
277 316
  /// DIMACS capacitated digraph reader function.
278 317
  ///
279 318
  /// This function reads an arc capacitated digraph instance from
280
  /// DIMACS 'mat' or 'sp' format.
319
  /// DIMACS 'max' or 'sp' format.
281 320
  /// At the beginning, \c g is cleared by \c g.clear()
282
  /// and the arc capacities/lengths are written to \c capacity.
321
  /// and the arc capacities/lengths are written to the \c capacity
322
  /// arc map.
323
  ///
324
  /// In case of the 'max' format, if the capacity of an arc is negative,
325
  /// it will
326
  /// be set to "infinite" instead. The actual value of "infinite" is
327
  /// contolled by the \c infty parameter. If it is 0 (the default value),
328
  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
329
  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
330
  /// a non-zero value, that value will be used as "infinite".
283 331
  ///
284 332
  /// If the file type was previously evaluated by dimacsType(), then
285 333
  /// the descriptor struct should be given by the \c dest parameter.
286 334
  template<typename Digraph, typename CapacityMap>
287 335
  void readDimacsCap(std::istream& is,
288 336
                     Digraph &g,
289 337
                     CapacityMap& capacity,
338
                     typename CapacityMap::Value infty = 0,
290 339
                     DimacsDescriptor desc=DimacsDescriptor()) {
291 340
    typename Digraph::Node u,v;
292 341
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
293 342
    if(desc.type!=DimacsDescriptor::MAX || desc.type!=DimacsDescriptor::SP)
294 343
      throw FormatError("Problem type mismatch");
295
    _readDimacs(is, g, capacity, u, v, desc);
344
    _readDimacs(is, g, capacity, u, v, infty, desc);
296 345
  }
297 346

	
298 347
  template<typename Graph>
299 348
  typename enable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
300 349
  _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
301 350
              dummy<0> = 0)
302 351
  {
303 352
    g.addEdge(s,t);
304 353
  }
305 354
  template<typename Graph>
306 355
  typename disable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
307 356
  _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
308 357
              dummy<1> = 1)
309 358
  {
310 359
    g.addArc(s,t);
311 360
  }
312 361
  
313 362
  /// DIMACS plain (di)graph reader function.
314 363
  ///
315 364
  /// This function reads a (di)graph without any designated nodes and
316 365
  /// maps from DIMACS format, i.e. from DIMACS files having a line
317 366
  /// starting with
318 367
  /// \code
319 368
  ///   p mat
... ...
@@ -326,49 +375,49 @@
326 375
  void readDimacsMat(std::istream& is, Graph &g,
327 376
                     DimacsDescriptor desc=DimacsDescriptor())
328 377
  {
329 378
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
330 379
    if(desc.type!=DimacsDescriptor::MAT)
331 380
      throw FormatError("Problem type mismatch");
332 381

	
333 382
    g.clear();
334 383
    std::vector<typename Graph::Node> nodes;
335 384
    char c;
336 385
    int i, j;
337 386
    std::string str;
338 387
    nodes.resize(desc.nodeNum + 1);
339 388
    for (int k = 1; k <= desc.nodeNum; ++k) {
340 389
      nodes[k] = g.addNode();
341 390
    }
342 391
    
343 392
    while (is >> c) {
344 393
      switch (c) {
345 394
      case 'c': // comment line
346 395
        getline(is, str);
347 396
        break;
348 397
      case 'n': // node definition line
349 398
        break;
350
      case 'a': // arc (arc) definition line
399
      case 'a': // arc definition line
351 400
        is >> i >> j;
352 401
        getline(is, str);
353 402
        _addArcEdge(g,nodes[i], nodes[j]);
354 403
        break;
355 404
      }
356 405
    }
357 406
  }
358 407

	
359 408
  /// DIMACS plain digraph writer function.
360 409
  ///
361 410
  /// This function writes a digraph without any designated nodes and
362 411
  /// maps into DIMACS format, i.e. into DIMACS file having a line
363 412
  /// starting with
364 413
  /// \code
365 414
  ///   p mat
366 415
  /// \endcode
367 416
  /// If \c comment is not empty, then it will be printed in the first line
368 417
  /// prefixed by 'c'.
369 418
  template<typename Digraph>
370 419
  void writeDimacsMat(std::ostream& os, const Digraph &g,
371 420
                      std::string comment="") {
372 421
    typedef typename Digraph::NodeIt NodeIt;
373 422
    typedef typename Digraph::ArcIt ArcIt;
374 423

	
Ignore white space 48 line context
... ...
@@ -51,135 +51,147 @@
51 51
typedef SmartGraph Graph;
52 52

	
53 53
template<class Value>
54 54
void solve_sp(ArgParser &ap, std::istream &is, std::ostream &,
55 55
              DimacsDescriptor &desc)
56 56
{
57 57
  bool report = !ap.given("q");
58 58
  Digraph g;
59 59
  Node s;
60 60
  Digraph::ArcMap<Value> len(g);
61 61
  Timer t;
62 62
  t.restart();
63 63
  readDimacsSp(is, g, len, s, desc);
64 64
  if(report) std::cerr << "Read the file: " << t << '\n';
65 65
  t.restart();
66 66
  Dijkstra<Digraph, Digraph::ArcMap<Value> > dij(g,len);
67 67
  if(report) std::cerr << "Setup Dijkstra class: " << t << '\n';
68 68
  t.restart();
69 69
  dij.run(s);
70 70
  if(report) std::cerr << "Run Dijkstra: " << t << '\n';
71 71
}
72 72

	
73 73
template<class Value>
74 74
void solve_max(ArgParser &ap, std::istream &is, std::ostream &,
75
              DimacsDescriptor &desc)
75
               Value infty, DimacsDescriptor &desc)
76 76
{
77 77
  bool report = !ap.given("q");
78 78
  Digraph g;
79 79
  Node s,t;
80 80
  Digraph::ArcMap<Value> cap(g);
81 81
  Timer ti;
82 82
  ti.restart();
83
  readDimacsMax(is, g, cap, s, t, desc);
83
  readDimacsMax(is, g, cap, s, t, infty, desc);
84 84
  if(report) std::cerr << "Read the file: " << ti << '\n';
85 85
  ti.restart();
86 86
  Preflow<Digraph, Digraph::ArcMap<Value> > pre(g,cap,s,t);
87 87
  if(report) std::cerr << "Setup Preflow class: " << ti << '\n';
88 88
  ti.restart();
89 89
  pre.run();
90 90
  if(report) std::cerr << "Run Preflow: " << ti << '\n';
91 91
  if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';  
92 92
}
93 93

	
94 94
void solve_mat(ArgParser &ap, std::istream &is, std::ostream &,
95 95
              DimacsDescriptor &desc)
96 96
{
97 97
  bool report = !ap.given("q");
98 98
  Graph g;
99 99
  Timer ti;
100 100
  ti.restart();
101 101
  readDimacsMat(is, g, desc);
102 102
  if(report) std::cerr << "Read the file: " << ti << '\n';
103 103
  ti.restart();
104 104
  MaxMatching<Graph> mat(g);
105 105
  if(report) std::cerr << "Setup MaxMatching class: " << ti << '\n';
106 106
  ti.restart();
107 107
  mat.run();
108 108
  if(report) std::cerr << "Run MaxMatching: " << ti << '\n';
109 109
  if(report) std::cerr << "\nCardinality of max matching: "
110 110
                       << mat.matchingSize() << '\n';  
111 111
}
112 112

	
113 113

	
114 114
template<class Value>
115 115
void solve(ArgParser &ap, std::istream &is, std::ostream &os,
116 116
           DimacsDescriptor &desc)
117 117
{
118
  std::stringstream iss(ap["infcap"]);
119
  Value infty;
120
  iss >> infty;
121
  if(iss.fail())
122
    {
123
      std::cerr << "Cannot interpret '"
124
                << static_cast<std::string>(ap["infcap"]) << "' as infinite"
125
                << std::endl;
126
      exit(1);
127
    }
128
  
118 129
  switch(desc.type)
119 130
    {
120 131
    case DimacsDescriptor::MIN:
121 132
      std::cerr <<
122 133
        "\n\n Sorry, the min. cost flow solver is not yet available.\n";
123 134
      break;
124 135
    case DimacsDescriptor::MAX:
125
      solve_max<Value>(ap,is,os,desc);
136
      solve_max<Value>(ap,is,os,infty,desc);
126 137
      break;
127 138
    case DimacsDescriptor::SP:
128 139
      solve_sp<Value>(ap,is,os,desc);
129 140
      break;
130 141
    case DimacsDescriptor::MAT:
131 142
      solve_mat(ap,is,os,desc);
132 143
      break;
133 144
    default:
134 145
      break;
135 146
    }
136 147
}
137 148

	
138 149
int main(int argc, const char *argv[]) {
139 150
  typedef SmartDigraph Digraph;
140 151

	
141 152
  typedef Digraph::Arc Arc;
142 153

	
143 154
  std::string inputName;
144 155
  std::string outputName;
145 156

	
146 157
  ArgParser ap(argc, argv);
147 158
  ap.other("[INFILE [OUTFILE]]",
148 159
           "If either the INFILE or OUTFILE file is missing the standard\n"
149 160
           "     input/output will be used instead.")
150 161
    .boolOption("q", "Do not print any report")
151 162
    .boolOption("int","Use 'int' for capacities, costs etc. (default)")
152 163
    .optionGroup("datatype","int")
153 164
#ifdef HAVE_LONG_LONG
154 165
    .boolOption("long","Use 'long long' for capacities, costs etc.")
155 166
    .optionGroup("datatype","long")
156 167
#endif
157 168
    .boolOption("double","Use 'double' for capacities, costs etc.")
158 169
    .optionGroup("datatype","double")
159 170
    .boolOption("ldouble","Use 'long double' for capacities, costs etc.")
160 171
    .optionGroup("datatype","ldouble")
161 172
    .onlyOneGroup("datatype")
173
    .stringOption("infcap","Value used for 'very high' capacities","0")
162 174
    .run();
163 175

	
164 176
  std::ifstream input;
165 177
  std::ofstream output;
166 178

	
167 179
  switch(ap.files().size())
168 180
    {
169 181
    case 2:
170 182
      output.open(ap.files()[1].c_str());
171 183
      if (!output) {
172 184
        throw IoError("Cannot open the file for writing", ap.files()[1]);
173 185
      }
174 186
    case 1:
175 187
      input.open(ap.files()[0].c_str());
176 188
      if (!input) {
177 189
        throw IoError("File cannot be found", ap.files()[0]);
178 190
      }
179 191
    case 0:
180 192
      break;
181 193
    default:
182 194
      std::cerr << ap.commandName() << ": too many arguments\n";
183 195
      return 1;
184 196
    }
185 197
  std::istream& is = (ap.files().size()<1 ? std::cin : input);
Ignore white space 6 line context
... ...
@@ -75,64 +75,64 @@
75 75
        throw IoError("Cannot open the file for writing", ap.files()[1]);
76 76
      }
77 77
    case 1:
78 78
      input.open(ap.files()[0].c_str());
79 79
      if (!input) {
80 80
        throw IoError("File cannot be found", ap.files()[0]);
81 81
      }
82 82
    case 0:
83 83
      break;
84 84
    default:
85 85
      cerr << ap.commandName() << ": too many arguments\n";
86 86
      return 1;
87 87
  }
88 88
  istream& is = (ap.files().size()<1 ? cin : input);
89 89
  ostream& os = (ap.files().size()<2 ? cout : output);
90 90

	
91 91
  DimacsDescriptor desc = dimacsType(is);
92 92
  switch(desc.type)
93 93
    {
94 94
    case DimacsDescriptor::MIN:
95 95
      {
96 96
        Digraph digraph;
97 97
        DoubleArcMap lower(digraph), capacity(digraph), cost(digraph);
98 98
        DoubleNodeMap supply(digraph);
99
        readDimacsMin(is, digraph, lower, capacity, cost, supply, desc);
99
        readDimacsMin(is, digraph, lower, capacity, cost, supply, 0, desc);
100 100
        DigraphWriter<Digraph>(digraph, os).
101 101
          nodeMap("supply", supply).
102 102
          arcMap("lower", lower).
103 103
          arcMap("capacity", capacity).
104 104
          arcMap("cost", cost).
105 105
          attribute("problem","min").
106 106
          run();
107 107
      }
108 108
      break;
109 109
    case DimacsDescriptor::MAX:
110 110
      {
111 111
        Digraph digraph;
112 112
        Node s, t;
113 113
        DoubleArcMap capacity(digraph);
114
        readDimacsMax(is, digraph, capacity, s, t, desc);
114
        readDimacsMax(is, digraph, capacity, s, t, 0, desc);
115 115
        DigraphWriter<Digraph>(digraph, os).
116 116
          arcMap("capacity", capacity).
117 117
          node("source", s).
118 118
          node("target", t).
119 119
          attribute("problem","max").
120 120
          run();
121 121
      }
122 122
      break;
123 123
    case DimacsDescriptor::SP:
124 124
      {
125 125
        Digraph digraph;
126 126
        Node s;
127 127
        DoubleArcMap capacity(digraph);
128 128
        readDimacsSp(is, digraph, capacity, s, desc);
129 129
        DigraphWriter<Digraph>(digraph, os).
130 130
          arcMap("capacity", capacity).
131 131
          node("source", s).
132 132
          attribute("problem","sp").
133 133
          run();
134 134
      }
135 135
      break;
136 136
    case DimacsDescriptor::MAT:
137 137
      {
138 138
        Digraph digraph;
0 comments (0 inline)