lemon/dimacs.h
author Balazs Dezso <deba@inf.elte.hu>
Thu, 24 Jun 2010 09:27:53 +0200
changeset 982 bb70ad62c95f
parent 608 6e0525ec5355
child 956 141f9c0db4a3
child 1081 f1398882a928
permissions -rw-r--r--
Fix critical bug in preflow (#372)

The wrong transition between the bound decrease and highest active
heuristics caused the bug. The last node chosen in bound decrease mode
is used in the first iteration in highest active mode.
alpar@400
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
alpar@400
     2
 *
alpar@400
     3
 * This file is a part of LEMON, a generic C++ optimization library.
alpar@400
     4
 *
alpar@463
     5
 * Copyright (C) 2003-2009
alpar@400
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@400
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@400
     8
 *
alpar@400
     9
 * Permission to use, modify and distribute this software is granted
alpar@400
    10
 * provided that this copyright notice appears in all copies. For
alpar@400
    11
 * precise terms see the accompanying LICENSE file.
alpar@400
    12
 *
alpar@400
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@400
    14
 * express or implied, and with no claim as to its suitability for any
alpar@400
    15
 * purpose.
alpar@400
    16
 *
alpar@400
    17
 */
alpar@400
    18
alpar@400
    19
#ifndef LEMON_DIMACS_H
alpar@400
    20
#define LEMON_DIMACS_H
alpar@400
    21
alpar@400
    22
#include <iostream>
alpar@400
    23
#include <string>
alpar@400
    24
#include <vector>
alpar@608
    25
#include <limits>
alpar@400
    26
#include <lemon/maps.h>
alpar@402
    27
#include <lemon/error.h>
alpar@400
    28
/// \ingroup dimacs_group
alpar@400
    29
/// \file
alpar@400
    30
/// \brief DIMACS file format reader.
alpar@400
    31
alpar@400
    32
namespace lemon {
alpar@400
    33
alpar@400
    34
  /// \addtogroup dimacs_group
alpar@400
    35
  /// @{
alpar@400
    36
alpar@402
    37
  /// DIMACS file type descriptor.
alpar@402
    38
  struct DimacsDescriptor
alpar@402
    39
  {
kpeter@631
    40
    ///\brief DIMACS file type enum
kpeter@631
    41
    ///
kpeter@631
    42
    ///DIMACS file type enum.
kpeter@631
    43
    enum Type {
kpeter@631
    44
      NONE,  ///< Undefined type.
kpeter@631
    45
      MIN,   ///< DIMACS file type for minimum cost flow problems.
kpeter@631
    46
      MAX,   ///< DIMACS file type for maximum flow problems.
kpeter@631
    47
      SP,    ///< DIMACS file type for shostest path problems.
kpeter@631
    48
      MAT    ///< DIMACS file type for plain graphs and matching problems.
kpeter@631
    49
    };
alpar@402
    50
    ///The file type
alpar@402
    51
    Type type;
kpeter@403
    52
    ///The number of nodes in the graph
alpar@402
    53
    int nodeNum;
kpeter@403
    54
    ///The number of edges in the graph
alpar@402
    55
    int edgeNum;
alpar@402
    56
    int lineShift;
kpeter@631
    57
    ///Constructor. It sets the type to \c NONE.
alpar@402
    58
    DimacsDescriptor() : type(NONE) {}
alpar@402
    59
  };
alpar@402
    60
alpar@402
    61
  ///Discover the type of a DIMACS file
alpar@402
    62
kpeter@631
    63
  ///This function starts seeking the beginning of the given file for the
kpeter@631
    64
  ///problem type and size info. 
kpeter@631
    65
  ///The found data is returned in a special struct that can be evaluated
kpeter@631
    66
  ///and passed to the appropriate reader function.
alpar@402
    67
  DimacsDescriptor dimacsType(std::istream& is)
alpar@402
    68
  {
alpar@402
    69
    DimacsDescriptor r;
alpar@402
    70
    std::string problem,str;
alpar@402
    71
    char c;
alpar@402
    72
    r.lineShift=0;
alpar@402
    73
    while (is >> c)
alpar@402
    74
      switch(c)
alpar@402
    75
        {
alpar@402
    76
        case 'p':
alpar@402
    77
          if(is >> problem >> r.nodeNum >> r.edgeNum)
alpar@402
    78
            {
alpar@402
    79
              getline(is, str);
alpar@402
    80
              r.lineShift++;
alpar@402
    81
              if(problem=="min") r.type=DimacsDescriptor::MIN;
alpar@402
    82
              else if(problem=="max") r.type=DimacsDescriptor::MAX;
alpar@402
    83
              else if(problem=="sp") r.type=DimacsDescriptor::SP;
alpar@402
    84
              else if(problem=="mat") r.type=DimacsDescriptor::MAT;
alpar@402
    85
              else throw FormatError("Unknown problem type");
alpar@402
    86
              return r;
alpar@402
    87
            }
alpar@402
    88
          else
alpar@402
    89
            {
alpar@402
    90
              throw FormatError("Missing or wrong problem type declaration.");
alpar@402
    91
            }
alpar@402
    92
          break;
alpar@402
    93
        case 'c':
alpar@402
    94
          getline(is, str);
alpar@402
    95
          r.lineShift++;
alpar@402
    96
          break;
alpar@402
    97
        default:
alpar@402
    98
          throw FormatError("Unknown DIMACS declaration.");
alpar@402
    99
        }
alpar@402
   100
    throw FormatError("Missing problem type declaration.");
alpar@402
   101
  }
alpar@402
   102
alpar@402
   103
kpeter@631
   104
  /// \brief DIMACS minimum cost flow reader function.
alpar@400
   105
  ///
kpeter@403
   106
  /// This function reads a minimum cost flow instance from DIMACS format,
kpeter@403
   107
  /// i.e. from a DIMACS file having a line starting with
alpar@400
   108
  /// \code
alpar@400
   109
  ///   p min
alpar@400
   110
  /// \endcode
alpar@402
   111
  /// At the beginning, \c g is cleared by \c g.clear(). The supply
alpar@608
   112
  /// amount of the nodes are written to the \c supply node map
alpar@608
   113
  /// (they are signed values). The lower bounds, capacities and costs
alpar@608
   114
  /// of the arcs are written to the \c lower, \c capacity and \c cost
alpar@608
   115
  /// arc maps.
alpar@608
   116
  ///
alpar@608
   117
  /// If the capacity of an arc is less than the lower bound, it will
alpar@608
   118
  /// be set to "infinite" instead. The actual value of "infinite" is
alpar@608
   119
  /// contolled by the \c infty parameter. If it is 0 (the default value),
alpar@608
   120
  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
alpar@608
   121
  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
alpar@608
   122
  /// a non-zero value, that value will be used as "infinite".
alpar@402
   123
  ///
alpar@402
   124
  /// If the file type was previously evaluated by dimacsType(), then
alpar@402
   125
  /// the descriptor struct should be given by the \c dest parameter.
alpar@400
   126
  template <typename Digraph, typename LowerMap,
alpar@402
   127
            typename CapacityMap, typename CostMap,
alpar@402
   128
            typename SupplyMap>
alpar@402
   129
  void readDimacsMin(std::istream& is,
alpar@402
   130
                     Digraph &g,
alpar@402
   131
                     LowerMap& lower,
alpar@402
   132
                     CapacityMap& capacity,
alpar@402
   133
                     CostMap& cost,
alpar@402
   134
                     SupplyMap& supply,
alpar@608
   135
                     typename CapacityMap::Value infty = 0,
alpar@402
   136
                     DimacsDescriptor desc=DimacsDescriptor())
alpar@400
   137
  {
alpar@400
   138
    g.clear();
alpar@400
   139
    std::vector<typename Digraph::Node> nodes;
alpar@400
   140
    typename Digraph::Arc e;
alpar@400
   141
    std::string problem, str;
alpar@400
   142
    char c;
alpar@400
   143
    int i, j;
alpar@402
   144
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
alpar@402
   145
    if(desc.type!=DimacsDescriptor::MIN)
alpar@402
   146
      throw FormatError("Problem type mismatch");
alpar@402
   147
alpar@402
   148
    nodes.resize(desc.nodeNum + 1);
alpar@402
   149
    for (int k = 1; k <= desc.nodeNum; ++k) {
alpar@402
   150
      nodes[k] = g.addNode();
alpar@402
   151
      supply.set(nodes[k], 0);
alpar@402
   152
    }
alpar@402
   153
alpar@400
   154
    typename SupplyMap::Value sup;
alpar@400
   155
    typename CapacityMap::Value low;
alpar@400
   156
    typename CapacityMap::Value cap;
alpar@400
   157
    typename CostMap::Value co;
alpar@608
   158
    typedef typename CapacityMap::Value Capacity;
alpar@608
   159
    if(infty==0)
alpar@608
   160
      infty = std::numeric_limits<Capacity>::has_infinity ?
alpar@608
   161
        std::numeric_limits<Capacity>::infinity() :
alpar@608
   162
        std::numeric_limits<Capacity>::max();
alpar@608
   163
alpar@400
   164
    while (is >> c) {
alpar@400
   165
      switch (c) {
alpar@400
   166
      case 'c': // comment line
alpar@400
   167
        getline(is, str);
alpar@400
   168
        break;
alpar@400
   169
      case 'n': // node definition line
alpar@400
   170
        is >> i >> sup;
alpar@400
   171
        getline(is, str);
alpar@400
   172
        supply.set(nodes[i], sup);
alpar@400
   173
        break;
alpar@608
   174
      case 'a': // arc definition line
alpar@400
   175
        is >> i >> j >> low >> cap >> co;
alpar@400
   176
        getline(is, str);
alpar@400
   177
        e = g.addArc(nodes[i], nodes[j]);
alpar@400
   178
        lower.set(e, low);
alpar@608
   179
        if (cap >= low)
alpar@400
   180
          capacity.set(e, cap);
alpar@400
   181
        else
alpar@608
   182
          capacity.set(e, infty);
alpar@400
   183
        cost.set(e, co);
alpar@400
   184
        break;
alpar@400
   185
      }
alpar@400
   186
    }
alpar@400
   187
  }
alpar@400
   188
alpar@400
   189
  template<typename Digraph, typename CapacityMap>
alpar@402
   190
  void _readDimacs(std::istream& is,
alpar@402
   191
                   Digraph &g,
alpar@402
   192
                   CapacityMap& capacity,
alpar@402
   193
                   typename Digraph::Node &s,
alpar@402
   194
                   typename Digraph::Node &t,
alpar@608
   195
                   typename CapacityMap::Value infty = 0,
alpar@402
   196
                   DimacsDescriptor desc=DimacsDescriptor()) {
alpar@400
   197
    g.clear();
alpar@402
   198
    s=t=INVALID;
alpar@400
   199
    std::vector<typename Digraph::Node> nodes;
alpar@400
   200
    typename Digraph::Arc e;
alpar@400
   201
    char c, d;
alpar@400
   202
    int i, j;
alpar@400
   203
    typename CapacityMap::Value _cap;
alpar@400
   204
    std::string str;
alpar@402
   205
    nodes.resize(desc.nodeNum + 1);
alpar@402
   206
    for (int k = 1; k <= desc.nodeNum; ++k) {
alpar@402
   207
      nodes[k] = g.addNode();
alpar@402
   208
    }
alpar@608
   209
    typedef typename CapacityMap::Value Capacity;
alpar@402
   210
alpar@608
   211
    if(infty==0)
alpar@608
   212
      infty = std::numeric_limits<Capacity>::has_infinity ?
alpar@608
   213
        std::numeric_limits<Capacity>::infinity() :
alpar@608
   214
        std::numeric_limits<Capacity>::max();
alpar@608
   215
 
alpar@400
   216
    while (is >> c) {
alpar@400
   217
      switch (c) {
alpar@400
   218
      case 'c': // comment line
alpar@400
   219
        getline(is, str);
alpar@400
   220
        break;
alpar@400
   221
      case 'n': // node definition line
alpar@402
   222
        if (desc.type==DimacsDescriptor::SP) { // shortest path problem
alpar@400
   223
          is >> i;
alpar@400
   224
          getline(is, str);
alpar@400
   225
          s = nodes[i];
alpar@400
   226
        }
alpar@402
   227
        if (desc.type==DimacsDescriptor::MAX) { // max flow problem
alpar@400
   228
          is >> i >> d;
alpar@400
   229
          getline(is, str);
alpar@400
   230
          if (d == 's') s = nodes[i];
alpar@400
   231
          if (d == 't') t = nodes[i];
alpar@400
   232
        }
alpar@400
   233
        break;
alpar@608
   234
      case 'a': // arc definition line
alpar@608
   235
        if (desc.type==DimacsDescriptor::SP) {
alpar@400
   236
          is >> i >> j >> _cap;
alpar@400
   237
          getline(is, str);
alpar@400
   238
          e = g.addArc(nodes[i], nodes[j]);
alpar@400
   239
          capacity.set(e, _cap);
alpar@608
   240
        } 
alpar@608
   241
        else if (desc.type==DimacsDescriptor::MAX) {
alpar@608
   242
          is >> i >> j >> _cap;
alpar@608
   243
          getline(is, str);
alpar@608
   244
          e = g.addArc(nodes[i], nodes[j]);
alpar@608
   245
          if (_cap >= 0)
alpar@608
   246
            capacity.set(e, _cap);
alpar@608
   247
          else
alpar@608
   248
            capacity.set(e, infty);
alpar@608
   249
        }
alpar@608
   250
        else {
alpar@400
   251
          is >> i >> j;
alpar@400
   252
          getline(is, str);
alpar@400
   253
          g.addArc(nodes[i], nodes[j]);
alpar@400
   254
        }
alpar@400
   255
        break;
alpar@400
   256
      }
alpar@400
   257
    }
alpar@400
   258
  }
alpar@400
   259
kpeter@631
   260
  /// \brief DIMACS maximum flow reader function.
alpar@402
   261
  ///
kpeter@403
   262
  /// This function reads a maximum flow instance from DIMACS format,
kpeter@403
   263
  /// i.e. from a DIMACS file having a line starting with
alpar@402
   264
  /// \code
alpar@402
   265
  ///   p max
alpar@402
   266
  /// \endcode
alpar@402
   267
  /// At the beginning, \c g is cleared by \c g.clear(). The arc
alpar@608
   268
  /// capacities are written to the \c capacity arc map and \c s and
alpar@608
   269
  /// \c t are set to the source and the target nodes.
alpar@608
   270
  ///
alpar@608
   271
  /// If the capacity of an arc is negative, it will
alpar@608
   272
  /// be set to "infinite" instead. The actual value of "infinite" is
alpar@608
   273
  /// contolled by the \c infty parameter. If it is 0 (the default value),
alpar@608
   274
  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
alpar@608
   275
  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
alpar@608
   276
  /// a non-zero value, that value will be used as "infinite".
alpar@402
   277
  ///
alpar@402
   278
  /// If the file type was previously evaluated by dimacsType(), then
alpar@402
   279
  /// the descriptor struct should be given by the \c dest parameter.
alpar@402
   280
  template<typename Digraph, typename CapacityMap>
alpar@402
   281
  void readDimacsMax(std::istream& is,
alpar@402
   282
                     Digraph &g,
alpar@402
   283
                     CapacityMap& capacity,
alpar@402
   284
                     typename Digraph::Node &s,
alpar@402
   285
                     typename Digraph::Node &t,
alpar@608
   286
                     typename CapacityMap::Value infty = 0,
alpar@402
   287
                     DimacsDescriptor desc=DimacsDescriptor()) {
alpar@402
   288
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
alpar@402
   289
    if(desc.type!=DimacsDescriptor::MAX)
alpar@402
   290
      throw FormatError("Problem type mismatch");
alpar@608
   291
    _readDimacs(is,g,capacity,s,t,infty,desc);
alpar@402
   292
  }
alpar@402
   293
kpeter@631
   294
  /// \brief DIMACS shortest path reader function.
alpar@400
   295
  ///
alpar@400
   296
  /// This function reads a shortest path instance from DIMACS format,
kpeter@403
   297
  /// i.e. from a DIMACS file having a line starting with
alpar@400
   298
  /// \code
alpar@400
   299
  ///   p sp
alpar@400
   300
  /// \endcode
alpar@402
   301
  /// At the beginning, \c g is cleared by \c g.clear(). The arc
alpar@608
   302
  /// lengths are written to the \c length arc map and \c s is set to the
alpar@400
   303
  /// source node.
alpar@402
   304
  ///
alpar@402
   305
  /// If the file type was previously evaluated by dimacsType(), then
alpar@402
   306
  /// the descriptor struct should be given by the \c dest parameter.
alpar@402
   307
  template<typename Digraph, typename LengthMap>
alpar@402
   308
  void readDimacsSp(std::istream& is,
alpar@402
   309
                    Digraph &g,
alpar@402
   310
                    LengthMap& length,
alpar@402
   311
                    typename Digraph::Node &s,
alpar@402
   312
                    DimacsDescriptor desc=DimacsDescriptor()) {
alpar@401
   313
    typename Digraph::Node t;
alpar@402
   314
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
alpar@402
   315
    if(desc.type!=DimacsDescriptor::SP)
alpar@402
   316
      throw FormatError("Problem type mismatch");
alpar@608
   317
    _readDimacs(is, g, length, s, t, 0, desc);
alpar@400
   318
  }
alpar@400
   319
kpeter@631
   320
  /// \brief DIMACS capacitated digraph reader function.
alpar@400
   321
  ///
alpar@400
   322
  /// This function reads an arc capacitated digraph instance from
alpar@608
   323
  /// DIMACS 'max' or 'sp' format.
alpar@402
   324
  /// At the beginning, \c g is cleared by \c g.clear()
alpar@608
   325
  /// and the arc capacities/lengths are written to the \c capacity
alpar@608
   326
  /// arc map.
alpar@608
   327
  ///
alpar@608
   328
  /// In case of the 'max' format, if the capacity of an arc is negative,
alpar@608
   329
  /// it will
alpar@608
   330
  /// be set to "infinite" instead. The actual value of "infinite" is
alpar@608
   331
  /// contolled by the \c infty parameter. If it is 0 (the default value),
alpar@608
   332
  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
alpar@608
   333
  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
alpar@608
   334
  /// a non-zero value, that value will be used as "infinite".
alpar@402
   335
  ///
alpar@402
   336
  /// If the file type was previously evaluated by dimacsType(), then
alpar@402
   337
  /// the descriptor struct should be given by the \c dest parameter.
alpar@400
   338
  template<typename Digraph, typename CapacityMap>
alpar@402
   339
  void readDimacsCap(std::istream& is,
alpar@402
   340
                     Digraph &g,
alpar@402
   341
                     CapacityMap& capacity,
alpar@608
   342
                     typename CapacityMap::Value infty = 0,
alpar@402
   343
                     DimacsDescriptor desc=DimacsDescriptor()) {
alpar@401
   344
    typename Digraph::Node u,v;
alpar@402
   345
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
alpar@402
   346
    if(desc.type!=DimacsDescriptor::MAX || desc.type!=DimacsDescriptor::SP)
alpar@402
   347
      throw FormatError("Problem type mismatch");
alpar@608
   348
    _readDimacs(is, g, capacity, u, v, infty, desc);
alpar@400
   349
  }
alpar@400
   350
alpar@572
   351
  template<typename Graph>
alpar@572
   352
  typename enable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
alpar@572
   353
  _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
alpar@572
   354
              dummy<0> = 0)
alpar@572
   355
  {
alpar@572
   356
    g.addEdge(s,t);
alpar@572
   357
  }
alpar@572
   358
  template<typename Graph>
alpar@572
   359
  typename disable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
alpar@572
   360
  _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
alpar@572
   361
              dummy<1> = 1)
alpar@572
   362
  {
alpar@572
   363
    g.addArc(s,t);
alpar@572
   364
  }
alpar@572
   365
  
kpeter@631
   366
  /// \brief DIMACS plain (di)graph reader function.
alpar@400
   367
  ///
kpeter@631
   368
  /// This function reads a plain (di)graph without any designated nodes
kpeter@631
   369
  /// and maps (e.g. a matching instance) from DIMACS format, i.e. from 
kpeter@631
   370
  /// DIMACS files having a line starting with
alpar@400
   371
  /// \code
alpar@400
   372
  ///   p mat
alpar@400
   373
  /// \endcode
alpar@402
   374
  /// At the beginning, \c g is cleared by \c g.clear().
alpar@402
   375
  ///
alpar@402
   376
  /// If the file type was previously evaluated by dimacsType(), then
alpar@402
   377
  /// the descriptor struct should be given by the \c dest parameter.
alpar@572
   378
  template<typename Graph>
alpar@572
   379
  void readDimacsMat(std::istream& is, Graph &g,
alpar@572
   380
                     DimacsDescriptor desc=DimacsDescriptor())
alpar@572
   381
  {
alpar@402
   382
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
alpar@402
   383
    if(desc.type!=DimacsDescriptor::MAT)
alpar@402
   384
      throw FormatError("Problem type mismatch");
alpar@572
   385
alpar@572
   386
    g.clear();
alpar@572
   387
    std::vector<typename Graph::Node> nodes;
alpar@572
   388
    char c;
alpar@572
   389
    int i, j;
alpar@572
   390
    std::string str;
alpar@572
   391
    nodes.resize(desc.nodeNum + 1);
alpar@572
   392
    for (int k = 1; k <= desc.nodeNum; ++k) {
alpar@572
   393
      nodes[k] = g.addNode();
alpar@572
   394
    }
alpar@572
   395
    
alpar@572
   396
    while (is >> c) {
alpar@572
   397
      switch (c) {
alpar@572
   398
      case 'c': // comment line
alpar@572
   399
        getline(is, str);
alpar@572
   400
        break;
alpar@572
   401
      case 'n': // node definition line
alpar@572
   402
        break;
alpar@608
   403
      case 'a': // arc definition line
alpar@572
   404
        is >> i >> j;
alpar@572
   405
        getline(is, str);
alpar@572
   406
        _addArcEdge(g,nodes[i], nodes[j]);
alpar@572
   407
        break;
alpar@572
   408
      }
alpar@572
   409
    }
alpar@400
   410
  }
alpar@400
   411
alpar@400
   412
  /// DIMACS plain digraph writer function.
alpar@400
   413
  ///
alpar@400
   414
  /// This function writes a digraph without any designated nodes and
alpar@400
   415
  /// maps into DIMACS format, i.e. into DIMACS file having a line
alpar@400
   416
  /// starting with
alpar@400
   417
  /// \code
alpar@400
   418
  ///   p mat
alpar@400
   419
  /// \endcode
alpar@402
   420
  /// If \c comment is not empty, then it will be printed in the first line
alpar@402
   421
  /// prefixed by 'c'.
alpar@400
   422
  template<typename Digraph>
alpar@402
   423
  void writeDimacsMat(std::ostream& os, const Digraph &g,
alpar@402
   424
                      std::string comment="") {
alpar@400
   425
    typedef typename Digraph::NodeIt NodeIt;
alpar@400
   426
    typedef typename Digraph::ArcIt ArcIt;
alpar@400
   427
alpar@463
   428
    if(!comment.empty())
alpar@402
   429
      os << "c " << comment << std::endl;
alpar@400
   430
    os << "p mat " << g.nodeNum() << " " << g.arcNum() << std::endl;
alpar@400
   431
alpar@400
   432
    typename Digraph::template NodeMap<int> nodes(g);
alpar@400
   433
    int i = 1;
alpar@400
   434
    for(NodeIt v(g); v != INVALID; ++v) {
alpar@400
   435
      nodes.set(v, i);
alpar@400
   436
      ++i;
alpar@400
   437
    }
alpar@400
   438
    for(ArcIt e(g); e != INVALID; ++e) {
alpar@400
   439
      os << "a " << nodes[g.source(e)] << " " << nodes[g.target(e)]
alpar@400
   440
         << std::endl;
alpar@400
   441
    }
alpar@400
   442
  }
alpar@400
   443
alpar@400
   444
  /// @}
alpar@400
   445
alpar@400
   446
} //namespace lemon
alpar@400
   447
alpar@400
   448
#endif //LEMON_DIMACS_H