lemon/dimacs.h
changeset 385 50d96f2166d7
child 386 9d1faab5e0f1
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/lemon/dimacs.h	Thu Nov 27 22:04:46 2008 +0000
     1.3 @@ -0,0 +1,248 @@
     1.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
     1.5 + *
     1.6 + * This file is a part of LEMON, a generic C++ optimization library.
     1.7 + *
     1.8 + * Copyright (C) 2003-2008
     1.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    1.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
    1.11 + *
    1.12 + * Permission to use, modify and distribute this software is granted
    1.13 + * provided that this copyright notice appears in all copies. For
    1.14 + * precise terms see the accompanying LICENSE file.
    1.15 + *
    1.16 + * This software is provided "AS IS" with no warranty of any kind,
    1.17 + * express or implied, and with no claim as to its suitability for any
    1.18 + * purpose.
    1.19 + *
    1.20 + */
    1.21 +
    1.22 +#ifndef LEMON_DIMACS_H
    1.23 +#define LEMON_DIMACS_H
    1.24 +
    1.25 +#include <iostream>
    1.26 +#include <string>
    1.27 +#include <vector>
    1.28 +#include <lemon/maps.h>
    1.29 +
    1.30 +/// \ingroup dimacs_group
    1.31 +/// \file
    1.32 +/// \brief DIMACS file format reader.
    1.33 +
    1.34 +namespace lemon {
    1.35 +
    1.36 +  ///@defgroup dimacs_group DIMACS format
    1.37 +  ///\brief Read and write files in DIMACS format
    1.38 +  ///
    1.39 +  ///Tools to read a digraph from or write it to a file in DIMACS format
    1.40 +  ///data
    1.41 +  ///\ingroup io_group
    1.42 +
    1.43 +  /// \addtogroup dimacs_group
    1.44 +  /// @{
    1.45 +
    1.46 +  /// DIMACS min cost flow reader function.
    1.47 +  ///
    1.48 +  /// This function reads a min cost flow instance from DIMACS format,
    1.49 +  /// i.e. from DIMACS files having a line starting with
    1.50 +  /// \code
    1.51 +  ///   p min
    1.52 +  /// \endcode
    1.53 +  /// At the beginning \c g is cleared by \c g.clear(). The supply
    1.54 +  /// amount of the nodes are written to \c supply (signed). The
    1.55 +  /// lower bounds, capacities and costs of the arcs are written to
    1.56 +  /// \c lower, \c capacity and \c cost.
    1.57 +  template <typename Digraph, typename LowerMap,
    1.58 +    typename CapacityMap, typename CostMap,
    1.59 +    typename SupplyMap>
    1.60 +  void readDimacs( std::istream& is,
    1.61 +                   Digraph &g,
    1.62 +                   LowerMap& lower,
    1.63 +                   CapacityMap& capacity,
    1.64 +                   CostMap& cost,
    1.65 +                   SupplyMap& supply )
    1.66 +  {
    1.67 +    g.clear();
    1.68 +    std::vector<typename Digraph::Node> nodes;
    1.69 +    typename Digraph::Arc e;
    1.70 +    std::string problem, str;
    1.71 +    char c;
    1.72 +    int n, m;
    1.73 +    int i, j;
    1.74 +    typename SupplyMap::Value sup;
    1.75 +    typename CapacityMap::Value low;
    1.76 +    typename CapacityMap::Value cap;
    1.77 +    typename CostMap::Value co;
    1.78 +    while (is >> c) {
    1.79 +      switch (c) {
    1.80 +      case 'c': // comment line
    1.81 +        getline(is, str);
    1.82 +        break;
    1.83 +      case 'p': // problem definition line
    1.84 +        is >> problem >> n >> m;
    1.85 +        getline(is, str);
    1.86 +        if (problem != "min") return;
    1.87 +        nodes.resize(n + 1);
    1.88 +        for (int k = 1; k <= n; ++k) {
    1.89 +          nodes[k] = g.addNode();
    1.90 +          supply.set(nodes[k], 0);
    1.91 +        }
    1.92 +        break;
    1.93 +      case 'n': // node definition line
    1.94 +        is >> i >> sup;
    1.95 +        getline(is, str);
    1.96 +        supply.set(nodes[i], sup);
    1.97 +        break;
    1.98 +      case 'a': // arc (arc) definition line
    1.99 +        is >> i >> j >> low >> cap >> co;
   1.100 +        getline(is, str);
   1.101 +        e = g.addArc(nodes[i], nodes[j]);
   1.102 +        lower.set(e, low);
   1.103 +        if (cap >= 0)
   1.104 +          capacity.set(e, cap);
   1.105 +        else
   1.106 +          capacity.set(e, -1);
   1.107 +        cost.set(e, co);
   1.108 +        break;
   1.109 +      }
   1.110 +    }
   1.111 +  }
   1.112 +
   1.113 +  /// DIMACS max flow reader function.
   1.114 +  ///
   1.115 +  /// This function reads a max flow instance from DIMACS format,
   1.116 +  /// i.e. from DIMACS files having a line starting with
   1.117 +  /// \code
   1.118 +  ///   p max
   1.119 +  /// \endcode
   1.120 +  /// At the beginning \c g is cleared by \c g.clear(). The arc
   1.121 +  /// capacities are written to \c capacity and \c s and \c t are
   1.122 +  /// set to the source and the target nodes.
   1.123 +  template<typename Digraph, typename CapacityMap>
   1.124 +  void readDimacs(std::istream& is, Digraph &g, CapacityMap& capacity,
   1.125 +                  typename Digraph::Node &s, typename Digraph::Node &t) {
   1.126 +    g.clear();
   1.127 +    std::vector<typename Digraph::Node> nodes;
   1.128 +    typename Digraph::Arc e;
   1.129 +    std::string problem;
   1.130 +    char c, d;
   1.131 +    int n, m;
   1.132 +    int i, j;
   1.133 +    typename CapacityMap::Value _cap;
   1.134 +    std::string str;
   1.135 +    while (is >> c) {
   1.136 +      switch (c) {
   1.137 +      case 'c': // comment line
   1.138 +        getline(is, str);
   1.139 +        break;
   1.140 +      case 'p': // problem definition line
   1.141 +        is >> problem >> n >> m;
   1.142 +        getline(is, str);
   1.143 +        nodes.resize(n + 1);
   1.144 +        for (int k = 1; k <= n; ++k)
   1.145 +          nodes[k] = g.addNode();
   1.146 +        break;
   1.147 +      case 'n': // node definition line
   1.148 +        if (problem == "sp") { // shortest path problem
   1.149 +          is >> i;
   1.150 +          getline(is, str);
   1.151 +          s = nodes[i];
   1.152 +        }
   1.153 +        if (problem == "max") { // max flow problem
   1.154 +          is >> i >> d;
   1.155 +          getline(is, str);
   1.156 +          if (d == 's') s = nodes[i];
   1.157 +          if (d == 't') t = nodes[i];
   1.158 +        }
   1.159 +        break;
   1.160 +      case 'a': // arc (arc) definition line
   1.161 +        if (problem == "max" || problem == "sp") {
   1.162 +          is >> i >> j >> _cap;
   1.163 +          getline(is, str);
   1.164 +          e = g.addArc(nodes[i], nodes[j]);
   1.165 +          capacity.set(e, _cap);
   1.166 +        } else {
   1.167 +          is >> i >> j;
   1.168 +          getline(is, str);
   1.169 +          g.addArc(nodes[i], nodes[j]);
   1.170 +        }
   1.171 +        break;
   1.172 +      }
   1.173 +    }
   1.174 +  }
   1.175 +
   1.176 +  /// DIMACS shortest path reader function.
   1.177 +  ///
   1.178 +  /// This function reads a shortest path instance from DIMACS format,
   1.179 +  /// i.e. from DIMACS files having a line starting with
   1.180 +  /// \code
   1.181 +  ///   p sp
   1.182 +  /// \endcode
   1.183 +  /// At the beginning \c g is cleared by \c g.clear(). The arc
   1.184 +  /// capacities are written to \c capacity and \c s is set to the
   1.185 +  /// source node.
   1.186 +  template<typename Digraph, typename CapacityMap>
   1.187 +  void readDimacs(std::istream& is, Digraph &g, CapacityMap& capacity,
   1.188 +                  typename Digraph::Node &s) {
   1.189 +    readDimacs(is, g, capacity, s, s);
   1.190 +  }
   1.191 +
   1.192 +  /// DIMACS capacitated digraph reader function.
   1.193 +  ///
   1.194 +  /// This function reads an arc capacitated digraph instance from
   1.195 +  /// DIMACS format. At the beginning \c g is cleared by \c g.clear()
   1.196 +  /// and the arc capacities are written to \c capacity.
   1.197 +  template<typename Digraph, typename CapacityMap>
   1.198 +  void readDimacs(std::istream& is, Digraph &g, CapacityMap& capacity) {
   1.199 +    typename Digraph::Node u;
   1.200 +    readDimacs(is, g, capacity, u, u);
   1.201 +  }
   1.202 +
   1.203 +  /// DIMACS plain digraph reader function.
   1.204 +  ///
   1.205 +  /// This function reads a digraph without any designated nodes and
   1.206 +  /// maps from DIMACS format, i.e. from DIMACS files having a line
   1.207 +  /// starting with
   1.208 +  /// \code
   1.209 +  ///   p mat
   1.210 +  /// \endcode
   1.211 +  /// At the beginning \c g is cleared by \c g.clear().
   1.212 +  template<typename Digraph>
   1.213 +  void readDimacs(std::istream& is, Digraph &g) {
   1.214 +    typename Digraph::Node u;
   1.215 +    NullMap<typename Digraph::Arc, int> n;
   1.216 +    readDimacs(is, g, n, u, u);
   1.217 +  }
   1.218 +
   1.219 +  /// DIMACS plain digraph writer function.
   1.220 +  ///
   1.221 +  /// This function writes a digraph without any designated nodes and
   1.222 +  /// maps into DIMACS format, i.e. into DIMACS file having a line
   1.223 +  /// starting with
   1.224 +  /// \code
   1.225 +  ///   p mat
   1.226 +  /// \endcode
   1.227 +  template<typename Digraph>
   1.228 +  void writeDimacs(std::ostream& os, const Digraph &g) {
   1.229 +    typedef typename Digraph::NodeIt NodeIt;
   1.230 +    typedef typename Digraph::ArcIt ArcIt;
   1.231 +
   1.232 +    os << "c matching problem" << std::endl;
   1.233 +    os << "p mat " << g.nodeNum() << " " << g.arcNum() << std::endl;
   1.234 +
   1.235 +    typename Digraph::template NodeMap<int> nodes(g);
   1.236 +    int i = 1;
   1.237 +    for(NodeIt v(g); v != INVALID; ++v) {
   1.238 +      nodes.set(v, i);
   1.239 +      ++i;
   1.240 +    }
   1.241 +    for(ArcIt e(g); e != INVALID; ++e) {
   1.242 +      os << "a " << nodes[g.source(e)] << " " << nodes[g.target(e)]
   1.243 +         << std::endl;
   1.244 +    }
   1.245 +  }
   1.246 +
   1.247 +  /// @}
   1.248 +
   1.249 +} //namespace lemon
   1.250 +
   1.251 +#endif //LEMON_DIMACS_H