COIN-OR::LEMON - Graph Library

Ticket #243: 5d1dc5085b44.patch

File 5d1dc5085b44.patch, 9.6 KB (added by Alpar Juttner, 16 years ago)
  • lemon/dimacs.h

    # HG changeset patch
    # User Alpar Juttner <alpar@cs.elte.hu>
    # Date 1238427997 -3600
    # Node ID 5d1dc5085b442dcf54533aca3a689fc7abc49efc
    # Parent  49a39bae067c4eca487e09c782ab3edba172b030
    Accept negative values as unbounded capacity in dimacs readers (#243)
    
    diff --git a/lemon/dimacs.h b/lemon/dimacs.h
    a b  
    2222#include <iostream>
    2323#include <string>
    2424#include <vector>
     25#include <limits>
    2526#include <lemon/maps.h>
    2627#include <lemon/error.h>
    27 
    2828/// \ingroup dimacs_group
    2929/// \file
    3030/// \brief DIMACS file format reader.
     
    109109  /// lower bounds, capacities and costs of the arcs are written to
    110110  /// \c lower, \c capacity and \c cost.
    111111  ///
     112  /// If the capacity of an arc is less than the lower bound, it will
     113  /// be set to "infinite" instead. The value if "infinite" is contolled
     114  /// by the \c infty parameter. If it is 0 (the default value),
     115  /// std::numeric_limits<Capacity>::infinity() will be used if available,
     116  /// std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
     117  /// a nonzero value, that value will be used as "infinite".
     118  ///
    112119  /// If the file type was previously evaluated by dimacsType(), then
    113120  /// the descriptor struct should be given by the \c dest parameter.
    114121  template <typename Digraph, typename LowerMap,
     
    120127                     CapacityMap& capacity,
    121128                     CostMap& cost,
    122129                     SupplyMap& supply,
     130                     typename CapacityMap::Value infty = 0,
    123131                     DimacsDescriptor desc=DimacsDescriptor())
    124132  {
    125133    g.clear();
     
    142150    typename CapacityMap::Value low;
    143151    typename CapacityMap::Value cap;
    144152    typename CostMap::Value co;
     153    typedef typename CapacityMap::Value Capacity;
     154    if(infty==0)
     155      infty = std::numeric_limits<Capacity>::has_infinity ?
     156        std::numeric_limits<Capacity>::infinity() :
     157        std::numeric_limits<Capacity>::max();
     158
    145159    while (is >> c) {
    146160      switch (c) {
    147161      case 'c': // comment line
     
    152166        getline(is, str);
    153167        supply.set(nodes[i], sup);
    154168        break;
    155       case 'a': // arc (arc) definition line
     169      case 'a': // arc definition line
    156170        is >> i >> j >> low >> cap >> co;
    157171        getline(is, str);
    158172        e = g.addArc(nodes[i], nodes[j]);
    159173        lower.set(e, low);
    160         if (cap >= 0)
     174        if (cap >= low)
    161175          capacity.set(e, cap);
    162176        else
    163           capacity.set(e, -1);
     177          capacity.set(e, infty);
    164178        cost.set(e, co);
    165179        break;
    166180      }
     
    173187                   CapacityMap& capacity,
    174188                   typename Digraph::Node &s,
    175189                   typename Digraph::Node &t,
     190                   typename CapacityMap::Value infty = 0,
    176191                   DimacsDescriptor desc=DimacsDescriptor()) {
    177192    g.clear();
    178193    s=t=INVALID;
     
    186201    for (int k = 1; k <= desc.nodeNum; ++k) {
    187202      nodes[k] = g.addNode();
    188203    }
     204    typedef typename CapacityMap::Value Capacity;
    189205
     206    if(infty==0)
     207      infty = std::numeric_limits<Capacity>::has_infinity ?
     208        std::numeric_limits<Capacity>::infinity() :
     209        std::numeric_limits<Capacity>::max();
     210 
    190211    while (is >> c) {
    191212      switch (c) {
    192213      case 'c': // comment line
     
    205226          if (d == 't') t = nodes[i];
    206227        }
    207228        break;
    208       case 'a': // arc (arc) definition line
    209         if (desc.type==DimacsDescriptor::SP ||
    210             desc.type==DimacsDescriptor::MAX) {
     229      case 'a': // arc definition line
     230        if (desc.type==DimacsDescriptor::SP) {
    211231          is >> i >> j >> _cap;
    212232          getline(is, str);
    213233          e = g.addArc(nodes[i], nodes[j]);
    214234          capacity.set(e, _cap);
    215         } else {
     235        }
     236        else if (desc.type==DimacsDescriptor::MAX) {
     237          is >> i >> j >> _cap;
     238          getline(is, str);
     239          e = g.addArc(nodes[i], nodes[j]);
     240          if (_cap >= 0)
     241            capacity.set(e, _cap);
     242          else
     243            capacity.set(e, infty);
     244        }
     245        else {
    216246          is >> i >> j;
    217247          getline(is, str);
    218248          g.addArc(nodes[i], nodes[j]);
     
    233263  /// capacities are written to \c capacity and \c s and \c t are
    234264  /// set to the source and the target nodes.
    235265  ///
     266  /// If the capacity of an arc is less than 0, it will
     267  /// be set to "infinite" instead. The value if "infinite" is contolled
     268  /// by the \c infty parameter. If it is 0 (the default value),
     269  /// std::numeric_limits<Capacity>::infinity() will be used if available,
     270  /// std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
     271  /// a nonzero value, that value will be used as "infinite".
     272  ///
    236273  /// If the file type was previously evaluated by dimacsType(), then
    237274  /// the descriptor struct should be given by the \c dest parameter.
    238275  template<typename Digraph, typename CapacityMap>
     
    241278                     CapacityMap& capacity,
    242279                     typename Digraph::Node &s,
    243280                     typename Digraph::Node &t,
     281                     typename CapacityMap::Value infty = 0,
    244282                     DimacsDescriptor desc=DimacsDescriptor()) {
    245283    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
    246284    if(desc.type!=DimacsDescriptor::MAX)
    247285      throw FormatError("Problem type mismatch");
    248     _readDimacs(is,g,capacity,s,t,desc);
     286    _readDimacs(is,g,capacity,s,t,infty,desc);
    249287  }
    250288
    251289  /// DIMACS shortest path reader function.
     
    271309    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
    272310    if(desc.type!=DimacsDescriptor::SP)
    273311      throw FormatError("Problem type mismatch");
    274     _readDimacs(is, g, length, s, t,desc);
     312    _readDimacs(is, g, length, s, t, 0, desc);
    275313  }
    276314
    277315  /// DIMACS capacitated digraph reader function.
     
    281319  /// At the beginning, \c g is cleared by \c g.clear()
    282320  /// and the arc capacities/lengths are written to \c capacity.
    283321  ///
     322  /// If the capacity of an arc is less than 0, it will
     323  /// be set to "infinite" instead. The value if "infinite" is contolled
     324  /// by the \c infty parameter. If it is 0 (the default value),
     325  /// std::numeric_limits<Capacity>::infinity() will be used if available,
     326  /// std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
     327  /// a nonzero value, that value will be used as "infinite".
     328  ///
    284329  /// If the file type was previously evaluated by dimacsType(), then
    285330  /// the descriptor struct should be given by the \c dest parameter.
    286331  template<typename Digraph, typename CapacityMap>
    287332  void readDimacsCap(std::istream& is,
    288333                     Digraph &g,
    289334                     CapacityMap& capacity,
     335                     typename CapacityMap::Value infty = 0,
    290336                     DimacsDescriptor desc=DimacsDescriptor()) {
    291337    typename Digraph::Node u,v;
    292338    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
    293339    if(desc.type!=DimacsDescriptor::MAX || desc.type!=DimacsDescriptor::SP)
    294340      throw FormatError("Problem type mismatch");
    295     _readDimacs(is, g, capacity, u, v, desc);
     341    _readDimacs(is, g, capacity, u, v, infty, desc);
    296342  }
    297343
    298344  template<typename Graph>
  • tools/dimacs-solver.cc

    diff --git a/tools/dimacs-solver.cc b/tools/dimacs-solver.cc
    a b  
    7272
    7373template<class Value>
    7474void solve_max(ArgParser &ap, std::istream &is, std::ostream &,
    75               DimacsDescriptor &desc)
     75               Value infty, DimacsDescriptor &desc)
    7676{
    7777  bool report = !ap.given("q");
    7878  Digraph g;
     
    8080  Digraph::ArcMap<Value> cap(g);
    8181  Timer ti;
    8282  ti.restart();
    83   readDimacsMax(is, g, cap, s, t, desc);
     83  readDimacsMax(is, g, cap, s, t, infty, desc);
    8484  if(report) std::cerr << "Read the file: " << ti << '\n';
    8585  ti.restart();
    8686  Preflow<Digraph, Digraph::ArcMap<Value> > pre(g,cap,s,t);
     
    115115void solve(ArgParser &ap, std::istream &is, std::ostream &os,
    116116           DimacsDescriptor &desc)
    117117{
     118  std::stringstream iss(ap["infty"]);
     119  Value infty;
     120  iss >> infty;
     121  if(is.fail())
     122    {
     123      std::cerr << "Cannot interpret '"
     124                << static_cast<std::string>(ap["infty"]) << "' as infinite"
     125           << std::endl;
     126      exit(1);
     127    }
     128 
    118129  switch(desc.type)
    119130    {
    120131    case DimacsDescriptor::MIN:
     
    122133        "\n\n Sorry, the min. cost flow solver is not yet available.\n";
    123134      break;
    124135    case DimacsDescriptor::MAX:
    125       solve_max<Value>(ap,is,os,desc);
     136      solve_max<Value>(ap,is,os,infty,desc);
    126137      break;
    127138    case DimacsDescriptor::SP:
    128139      solve_sp<Value>(ap,is,os,desc);
     
    159170    .boolOption("ldouble","Use 'long double' for capacities, costs etc.")
    160171    .optionGroup("datatype","ldouble")
    161172    .onlyOneGroup("datatype")
     173    .stringOption("infcap","Value of 'very high' capacities","0")
    162174    .run();
    163175
    164176  std::ifstream input;
  • tools/dimacs-to-lgf.cc

    diff --git a/tools/dimacs-to-lgf.cc b/tools/dimacs-to-lgf.cc
    a b  
    9696        Digraph digraph;
    9797        DoubleArcMap lower(digraph), capacity(digraph), cost(digraph);
    9898        DoubleNodeMap supply(digraph);
    99         readDimacsMin(is, digraph, lower, capacity, cost, supply, desc);
     99        readDimacsMin(is, digraph, lower, capacity, cost, supply, 0, desc);
    100100        DigraphWriter<Digraph>(digraph, os).
    101101          nodeMap("supply", supply).
    102102          arcMap("lower", lower).
     
    111111        Digraph digraph;
    112112        Node s, t;
    113113        DoubleArcMap capacity(digraph);
    114         readDimacsMax(is, digraph, capacity, s, t, desc);
     114        readDimacsMax(is, digraph, capacity, s, t, 0, desc);
    115115        DigraphWriter<Digraph>(digraph, os).
    116116          arcMap("capacity", capacity).
    117117          node("source", s).