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