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