src/hugo/dimacs.h
author ladanyi
Fri, 28 May 2004 07:48:16 +0000
changeset 666 410a1419e86b
parent 549 5531429143bc
child 778 08a1d1e3070d
permissions -rw-r--r--
Added a short tutorial on using graphs.
marci@423
     1
// -*- c++ -*-
marci@423
     2
#ifndef HUGO_DIMACS_H
marci@423
     3
#define HUGO_DIMACS_H
marci@423
     4
marci@423
     5
#include <iostream>
marci@423
     6
#include <string>
marci@423
     7
#include <vector>
ladanyi@542
     8
#include <hugo/maps.h>
marci@423
     9
jacint@575
    10
/// \ingroup misc
klao@442
    11
/// \file
klao@442
    12
/// \brief Dimacs file format reader.
klao@427
    13
marci@423
    14
namespace hugo {
marci@423
    15
marci@423
    16
jacint@575
    17
  /// \addtogroup misc
jacint@575
    18
  /// @{
jacint@575
    19
jacint@575
    20
  /// Dimacs min cost flow reader function.
jacint@575
    21
jacint@575
    22
  /// This function reads a min cost flow instance from dimacs format,
jacint@575
    23
  /// i.e. from dimacs files having a line starting with \c p \c "min".
jacint@575
    24
  /// At the beginning \c g is cleared by \c g.clear(). The edge
jacint@575
    25
  /// capacities are written to \c capacity, \c s and \c t are set to
jacint@575
    26
  /// the source and the target nodes resp. and the cost of the edges
jacint@575
    27
  /// are written to \c cost.
marci@465
    28
  ///
jacint@575
    29
  /// \author Marton Makai
jacint@528
    30
  template<typename Graph, typename CapacityMap, typename CostMap>
jacint@528
    31
  void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity, 
jacint@528
    32
		  typename Graph::Node &s, typename Graph::Node &t, 
jacint@528
    33
		  CostMap& cost) {
jacint@528
    34
    g.clear();
jacint@528
    35
    typename CapacityMap::ValueType _cap;
jacint@528
    36
    typename CostMap::ValueType _cost;
jacint@528
    37
    char d;
jacint@528
    38
    std::string problem;
jacint@528
    39
    char c;
jacint@528
    40
    int i, j;
jacint@528
    41
    std::string str;
jacint@528
    42
    int n, m; 
jacint@528
    43
    typename Graph::Edge e;
jacint@528
    44
    std::vector<typename Graph::Node> nodes;
jacint@528
    45
    while (is>>c) {
jacint@528
    46
      switch (c) {
jacint@528
    47
      case 'c': //comment
jacint@528
    48
	getline(is, str);
jacint@528
    49
	break;
jacint@528
    50
      case 'p': //problem definition
jacint@528
    51
	is >> problem >> n >> m;
jacint@528
    52
	getline(is, str);
jacint@528
    53
	nodes.resize(n+1);
jacint@528
    54
	for (int k=1; k<=n; ++k) nodes[k]=g.addNode();
jacint@528
    55
	break;
jacint@528
    56
      case 'n': //node definition
jacint@528
    57
	if (problem=="sp") { //shortest path problem
jacint@528
    58
	  is >> i;
jacint@528
    59
	  getline(is, str);
jacint@528
    60
	  s=nodes[i];
jacint@528
    61
	}
jacint@528
    62
	if (problem=="max" || problem=="min") { //((max) or (min cost)) flow problem
jacint@528
    63
	  is >> i >> d;
jacint@528
    64
	  getline(is, str);
jacint@528
    65
	  if (d=='s') s=nodes[i];
jacint@528
    66
	  if (d=='t') t=nodes[i];
jacint@528
    67
	}
jacint@528
    68
	break;
jacint@528
    69
      case 'a':
jacint@528
    70
	if ( problem == "max" || problem == "sp") {
jacint@528
    71
	  is >> i >> j >> _cap;
jacint@528
    72
	  getline(is, str);
jacint@528
    73
	  e=g.addEdge(nodes[i], nodes[j]);
jacint@528
    74
	  capacity.update();
jacint@528
    75
	  capacity.set(e, _cap);
jacint@575
    76
	} else {
jacint@575
    77
	  if ( problem == "min" ) {
jacint@575
    78
	    is >> i >> j >> _cap >> _cost;
jacint@575
    79
	    getline(is, str);
jacint@575
    80
	    e=g.addEdge(nodes[i], nodes[j]);
jacint@575
    81
	    capacity.update();
jacint@575
    82
	    capacity.set(e, _cap);
jacint@575
    83
	    cost.update();
jacint@575
    84
	    cost.set(e, _cost);
jacint@575
    85
	  } else {
jacint@575
    86
	    is >> i >> j;
jacint@575
    87
	    getline(is, str);
jacint@575
    88
	    g.addEdge(nodes[i], nodes[j]);
jacint@575
    89
	  }
jacint@528
    90
	}
jacint@528
    91
	break;
jacint@528
    92
      }
jacint@528
    93
    }
jacint@528
    94
  }
jacint@528
    95
jacint@528
    96
jacint@575
    97
  /// Dimacs max flow reader function.
jacint@575
    98
jacint@575
    99
  /// This function reads a max flow instance from dimacs format,
jacint@575
   100
  /// i.e. from dimacs files having a line starting with \c p \c
jacint@575
   101
  /// "max".  At the beginning \c g is cleared by \c g.clear(). The
jacint@575
   102
  /// edge capacities are written to \c capacity and \c s and \c t are
jacint@575
   103
  /// set to the source and the target nodes.
jacint@575
   104
  ///
jacint@575
   105
  /// \author Marton Makai
jacint@575
   106
  template<typename Graph, typename CapacityMap>
jacint@575
   107
  void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity, 
jacint@575
   108
		  typename Graph::Node &s, typename Graph::Node &t) {
jacint@575
   109
    NullMap<typename Graph::Edge, int> n;
jacint@575
   110
    readDimacs(is, g, capacity, s, t, n);
jacint@575
   111
  }
jacint@575
   112
jacint@575
   113
jacint@575
   114
  /// Dimacs shortest path reader function.
jacint@575
   115
jacint@575
   116
  /// This function reads a shortest path instance from dimacs format,
jacint@575
   117
  /// i.e. from dimacs files having a line starting with \c p \c "sp".
jacint@575
   118
  /// At the beginning \c g is cleared by \c g.clear(). The edge
jacint@575
   119
  /// capacities are written to \c capacity and \c s is set to the
jacint@575
   120
  /// source node.
jacint@575
   121
  ///
jacint@575
   122
  /// \author Marton Makai
jacint@575
   123
  template<typename Graph, typename CapacityMap>
jacint@575
   124
  void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity, 
jacint@575
   125
		  typename Graph::Node &s) {
jacint@575
   126
    NullMap<typename Graph::Edge, int> n;
jacint@575
   127
    readDimacs(is, g, capacity, s, s, n);
jacint@575
   128
  }
jacint@575
   129
jacint@575
   130
jacint@575
   131
  /// Dimacs capacitated graph reader function.
jacint@575
   132
jacint@575
   133
  /// This function reads an edge capacitated graph instance from
jacint@575
   134
  /// dimacs format.  At the beginning \c g is cleared by \c g.clear()
jacint@575
   135
  /// and the edge capacities are written to \c capacity.
jacint@575
   136
  ///
jacint@575
   137
  /// \author Marton Makai
jacint@575
   138
  template<typename Graph, typename CapacityMap>
jacint@575
   139
  void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity) {
jacint@575
   140
    typename Graph::Node u;
jacint@575
   141
    NullMap<typename Graph::Edge, int> n;
jacint@575
   142
    readDimacs(is, g, capacity, u, u, n);
jacint@575
   143
  }
jacint@575
   144
jacint@575
   145
jacint@575
   146
  /// Dimacs plain graph reader function.
jacint@575
   147
jacint@575
   148
  /// This function reads a graph without any designated nodes and
jacint@575
   149
  /// maps from dimacs format, i.e. from dimacs files having a line
jacint@575
   150
  /// starting with \c p \c "mat".  At the beginning \c g is cleared
jacint@575
   151
  /// by \c g.clear().
jacint@575
   152
  ///
jacint@575
   153
  /// \author Marton Makai
jacint@575
   154
  template<typename Graph>
jacint@575
   155
  void readDimacs(std::istream& is, Graph &g) {
jacint@575
   156
    typename Graph::Node u;
jacint@575
   157
    NullMap<typename Graph::Edge, int> n;
jacint@575
   158
    readDimacs(is, g, n, u, u, n);
jacint@575
   159
  }
jacint@575
   160
  
jacint@575
   161
jacint@575
   162
marci@423
   163
  
jacint@528
   164
  /// write matching problem
jacint@528
   165
  template<typename Graph>
jacint@528
   166
  void writeDimacs(std::ostream& os, const Graph &g) {
jacint@528
   167
    typedef typename Graph::NodeIt NodeIt;
jacint@528
   168
    typedef typename Graph::EdgeIt EdgeIt;  
jacint@528
   169
    
jacint@528
   170
    typename Graph::template NodeMap<int> nodes(g);
jacint@528
   171
jacint@528
   172
    os << "c matching problem" << std::endl;
jacint@528
   173
jacint@528
   174
    int i=1;
jacint@528
   175
    NodeIt v;
jacint@528
   176
    for(g.first(v); g.valid(v); g.next(v)) {
jacint@528
   177
      nodes.set(v, i);
jacint@528
   178
      ++i;
jacint@528
   179
    }    
jacint@528
   180
    
jacint@528
   181
    os << "p mat " << g.nodeNum() << " " << g.edgeNum() << std::endl;
jacint@528
   182
jacint@528
   183
    EdgeIt e;
jacint@528
   184
    for(g.first(e); g.valid(e); g.next(e)) {
jacint@528
   185
      os << "a " << nodes[g.tail(e)] << " " << nodes[g.head(e)] << std::endl; 
jacint@528
   186
    }
jacint@528
   187
jacint@528
   188
  }
jacint@528
   189
jacint@528
   190
jacint@575
   191
  /// @}
jacint@528
   192
marci@423
   193
} //namespace hugo
marci@423
   194
marci@423
   195
#endif //HUGO_DIMACS_H
jacint@575
   196
jacint@575
   197
//  template<typename Graph, typename CapacityMap>
jacint@575
   198
//   void readDimacsMaxFlow(std::istream& is, Graph &g, 
jacint@575
   199
// 			 typename Graph::Node &s, typename Graph::Node &t, CapacityMap& capacity) {
jacint@575
   200
//     g.clear();
jacint@575
   201
//     int cap;
jacint@575
   202
//     char d;
jacint@575
   203
//     std::string problem;
jacint@575
   204
//     char c;
jacint@575
   205
//     int i, j;
jacint@575
   206
//     std::string str;
jacint@575
   207
//     int n, m; 
jacint@575
   208
//     typename Graph::Edge e;
jacint@575
   209
//     std::vector<typename Graph::Node> nodes;
jacint@575
   210
//     while (is>>c) {
jacint@575
   211
//       switch (c) {
jacint@575
   212
//       case 'c': //comment
jacint@575
   213
// 	getline(is, str);
jacint@575
   214
// 	break;
jacint@575
   215
//       case 'p': //problem definition
jacint@575
   216
// 	is >> problem >> n >> m;
jacint@575
   217
// 	getline(is, str);
jacint@575
   218
// 	nodes.resize(n+1);
jacint@575
   219
// 	for (int k=1; k<=n; ++k) nodes[k]=g.addNode();
jacint@575
   220
// 	break;
jacint@575
   221
//       case 'n': //node definition
jacint@575
   222
// 	if (problem=="sp") { //shortest path problem
jacint@575
   223
// 	  is >> i;
jacint@575
   224
// 	  getline(is, str);
jacint@575
   225
// 	  s=nodes[i];
jacint@575
   226
// 	}
jacint@575
   227
// 	if (problem=="max") { //max flow problem
jacint@575
   228
// 	  is >> i >> d;
jacint@575
   229
// 	  getline(is, str);
jacint@575
   230
// 	  if (d=='s') s=nodes[i];
jacint@575
   231
// 	  if (d=='t') t=nodes[i];
jacint@575
   232
// 	}
jacint@575
   233
// 	break;
jacint@575
   234
//       case 'a':
jacint@575
   235
// 	is >> i >> j >> cap;
jacint@575
   236
// 	getline(is, str);
jacint@575
   237
// 	e=g.addEdge(nodes[i], nodes[j]);
jacint@575
   238
// 	capacity.update();
jacint@575
   239
// 	capacity.set(e, cap);
jacint@575
   240
// 	break;
jacint@575
   241
//       }
jacint@575
   242
//     }
jacint@575
   243
//   }