src/lemon/dimacs.h
author deba
Wed, 11 May 2005 13:49:17 +0000
changeset 1411 5d161e08bda8
parent 1287 984723507b86
permissions -rw-r--r--
Bug fix.
     1 /* -*- C++ -*-
     2  * src/lemon/dimacs.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     6  *
     7  * Permission to use, modify and distribute this software is granted
     8  * provided that this copyright notice appears in all copies. For
     9  * precise terms see the accompanying LICENSE file.
    10  *
    11  * This software is provided "AS IS" with no warranty of any kind,
    12  * express or implied, and with no claim as to its suitability for any
    13  * purpose.
    14  *
    15  */
    16 
    17 #ifndef LEMON_DIMACS_H
    18 #define LEMON_DIMACS_H
    19 
    20 #include <iostream>
    21 #include <string>
    22 #include <vector>
    23 #include <lemon/maps.h>
    24 #include <lemon/invalid.h>
    25 
    26 /// \ingroup dimacs_group
    27 /// \file
    28 /// \brief Dimacs file format reader.
    29 
    30 namespace lemon {
    31 
    32   ///
    33   ///@defgroup dimacs_group DIMACS format
    34   ///\brief Read and write files in DIMACS format
    35   ///
    36   ///Tools to read a graph from or write it to a file in DIMACS format
    37   ///data
    38   ///\ingroup io_group
    39 
    40   /// \addtogroup dimacs_group
    41   /// @{
    42 
    43   /// Dimacs min cost flow reader function.
    44 
    45   /// This function reads a min cost flow instance from dimacs format,
    46   /// i.e. from dimacs files having a line starting with
    47   /// \code
    48   /// p "min"
    49   /// \endcode
    50   /// At the beginning \c g is cleared by \c g.clear(). The edge
    51   /// capacities are written to \c capacity, \c s and \c t are set to
    52   /// the source and the target nodes resp. and the cost of the edges
    53   /// are written to \c cost.
    54   ///
    55   /// \author Marton Makai
    56   template<typename Graph, typename CapacityMap, typename CostMap>
    57   void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity, 
    58 		  typename Graph::Node &s, typename Graph::Node &t, 
    59 		  CostMap& cost) {
    60     g.clear();
    61     typename CapacityMap::Value _cap;
    62     typename CostMap::Value _cost;
    63     char d;
    64     std::string problem;
    65     char c;
    66     int i, j;
    67     std::string str;
    68     int n, m; 
    69     typename Graph::Edge e;
    70     std::vector<typename Graph::Node> nodes;
    71     while (is>>c) {
    72       switch (c) {
    73       case 'c': //comment
    74 	getline(is, str);
    75 	break;
    76       case 'p': //problem definition
    77 	is >> problem >> n >> m;
    78 	getline(is, str);
    79 	nodes.resize(n+1);
    80 	for (int k=1; k<=n; ++k) nodes[k]=g.addNode();
    81 	break;
    82       case 'n': //node definition
    83 	if (problem=="sp") { //shortest path problem
    84 	  is >> i;
    85 	  getline(is, str);
    86 	  s=nodes[i];
    87 	}
    88 	if (problem=="max" || problem=="min") { //((max) or (min cost)) flow problem
    89 	  is >> i >> d;
    90 	  getline(is, str);
    91 	  if (d=='s') s=nodes[i];
    92 	  if (d=='t') t=nodes[i];
    93 	}
    94 	break;
    95       case 'a':
    96 	if ( problem == "max" || problem == "sp") {
    97 	  is >> i >> j >> _cap;
    98 	  getline(is, str);
    99 	  e=g.addEdge(nodes[i], nodes[j]);
   100 	  //capacity.update();
   101 	  capacity.set(e, _cap);
   102 	} else {
   103 	  if ( problem == "min" ) {
   104 	    is >> i >> j >> _cap >> _cost;
   105 	    getline(is, str);
   106 	    e=g.addEdge(nodes[i], nodes[j]);
   107 	    //capacity.update();
   108 	    capacity.set(e, _cap);
   109 	    //cost.update();
   110 	    cost.set(e, _cost);
   111 	  } else {
   112 	    is >> i >> j;
   113 	    getline(is, str);
   114 	    g.addEdge(nodes[i], nodes[j]);
   115 	  }
   116 	}
   117 	break;
   118       }
   119     }
   120   }
   121 
   122 
   123   /// Dimacs max flow reader function.
   124 
   125   /// This function reads a max flow instance from dimacs format,
   126   /// i.e. from dimacs files having a line starting with
   127   /// \code
   128   /// p "max"
   129   /// \endcode
   130   ///At the beginning \c g is cleared by \c g.clear(). The
   131   /// edge capacities are written to \c capacity and \c s and \c t are
   132   /// set to the source and the target nodes.
   133   ///
   134   /// \author Marton Makai
   135   template<typename Graph, typename CapacityMap>
   136   void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity, 
   137 		  typename Graph::Node &s, typename Graph::Node &t) {
   138     NullMap<typename Graph::Edge, int> n;
   139     readDimacs(is, g, capacity, s, t, n);
   140   }
   141 
   142 
   143   /// Dimacs shortest path reader function.
   144 
   145   /// This function reads a shortest path instance from dimacs format,
   146   /// i.e. from dimacs files having a line starting with
   147   /// \code
   148   /// p "sp"
   149   /// \endcode
   150   /// At the beginning \c g is cleared by \c g.clear(). The edge
   151   /// capacities are written to \c capacity and \c s is set to the
   152   /// source node.
   153   ///
   154   /// \author Marton Makai
   155   template<typename Graph, typename CapacityMap>
   156   void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity, 
   157 		  typename Graph::Node &s) {
   158     NullMap<typename Graph::Edge, int> n;
   159     readDimacs(is, g, capacity, s, s, n);
   160   }
   161 
   162 
   163   /// Dimacs capacitated graph reader function.
   164 
   165   /// This function reads an edge capacitated graph instance from
   166   /// dimacs format.  At the beginning \c g is cleared by \c g.clear()
   167   /// and the edge capacities are written to \c capacity.
   168   ///
   169   /// \author Marton Makai
   170   template<typename Graph, typename CapacityMap>
   171   void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity) {
   172     typename Graph::Node u;
   173     NullMap<typename Graph::Edge, int> n;
   174     readDimacs(is, g, capacity, u, u, n);
   175   }
   176 
   177 
   178   /// Dimacs plain graph reader function.
   179 
   180   /// This function reads a graph without any designated nodes and
   181   /// maps from dimacs format, i.e. from dimacs files having a line
   182   /// starting with
   183   /// \code
   184   /// p "mat"
   185   /// \endcode
   186   /// At the beginning \c g is cleared
   187   /// by \c g.clear().
   188   ///
   189   /// \author Marton Makai
   190   template<typename Graph>
   191   void readDimacs(std::istream& is, Graph &g) {
   192     typename Graph::Node u;
   193     NullMap<typename Graph::Edge, int> n;
   194     readDimacs(is, g, n, u, u, n);
   195   }
   196   
   197 
   198 
   199   
   200   /// write matching problem
   201   template<typename Graph>
   202   void writeDimacs(std::ostream& os, const Graph &g) {
   203     typedef typename Graph::NodeIt NodeIt;
   204     typedef typename Graph::EdgeIt EdgeIt;  
   205     
   206     typename Graph::template NodeMap<int> nodes(g);
   207 
   208     os << "c matching problem" << std::endl;
   209 
   210     int i=1;
   211     for(NodeIt v(g); v!=INVALID; ++v) {
   212       nodes.set(v, i);
   213       ++i;
   214     }    
   215     
   216     os << "p mat " << g.nodeNum() << " " << g.edgeNum() << std::endl;
   217 
   218     for(EdgeIt e(g); e!=INVALID; ++e) {
   219       os << "a " << nodes[g.source(e)] << " " << nodes[g.target(e)] << std::endl; 
   220     }
   221 
   222   }
   223 
   224   /// @}
   225 
   226 } //namespace lemon
   227 
   228 #endif //LEMON_DIMACS_H