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