src/hugo/dimacs.h
author alpar
Fri, 07 May 2004 06:58:24 +0000
changeset 568 ed0a4de23923
parent 542 69bde1d90c04
child 575 bdf7fb750e0e
permissions -rw-r--r--
An alternative dijkstra_test.cc
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
klao@442
    10
/// \file
klao@442
    11
/// \brief Dimacs file format reader.
klao@427
    12
marci@423
    13
namespace hugo {
marci@423
    14
klao@427
    15
  /// Dimacs flow file format reader function.
marci@423
    16
marci@423
    17
  /// This function reads a flow instance from dimacs flow format.
klao@427
    18
  /// At the beginning \c g is cleared by \c g.clear().
klao@427
    19
  /// If the data coming from \c is is a max flow problem instance, then 
klao@427
    20
  /// \c s and \c t will be respectively the source and target nodes 
marci@423
    21
  /// and \c capacity will contain the edge capacities.
klao@427
    22
  /// If the data is a shortest path problem instance then \c s will be the 
klao@427
    23
  /// source node and \c capacity will contain the edge lengths.
marci@465
    24
  ///
marci@465
    25
  ///\author Marton Makai
marci@423
    26
  template<typename Graph, typename CapacityMap>
jacint@528
    27
  void readDimacsMaxFlow(std::istream& is, Graph &g, 
jacint@528
    28
			 typename Graph::Node &s, typename Graph::Node &t, CapacityMap& capacity) {
marci@423
    29
    g.clear();
marci@423
    30
    int cap;
marci@423
    31
    char d;
marci@423
    32
    std::string problem;
marci@423
    33
    char c;
marci@423
    34
    int i, j;
marci@423
    35
    std::string str;
marci@423
    36
    int n, m; 
marci@423
    37
    typename Graph::Edge e;
marci@423
    38
    std::vector<typename Graph::Node> nodes;
marci@423
    39
    while (is>>c) {
marci@423
    40
      switch (c) {
marci@423
    41
      case 'c': //comment
marci@423
    42
	getline(is, str);
marci@423
    43
	break;
marci@423
    44
      case 'p': //problem definition
marci@423
    45
	is >> problem >> n >> m;
marci@423
    46
	getline(is, str);
marci@423
    47
	nodes.resize(n+1);
marci@423
    48
	for (int k=1; k<=n; ++k) nodes[k]=g.addNode();
marci@423
    49
	break;
marci@423
    50
      case 'n': //node definition
marci@423
    51
	if (problem=="sp") { //shortest path problem
marci@423
    52
	  is >> i;
marci@423
    53
	  getline(is, str);
marci@423
    54
	  s=nodes[i];
marci@423
    55
	}
marci@423
    56
	if (problem=="max") { //max flow problem
marci@423
    57
	  is >> i >> d;
marci@423
    58
	  getline(is, str);
marci@423
    59
	  if (d=='s') s=nodes[i];
marci@423
    60
	  if (d=='t') t=nodes[i];
marci@423
    61
	}
marci@423
    62
	break;
marci@423
    63
      case 'a':
marci@423
    64
	is >> i >> j >> cap;
marci@423
    65
	getline(is, str);
marci@423
    66
	e=g.addEdge(nodes[i], nodes[j]);
marci@423
    67
	capacity.update();
marci@423
    68
	capacity.set(e, cap);
marci@423
    69
	break;
marci@423
    70
      }
marci@423
    71
    }
marci@423
    72
  }
jacint@528
    73
jacint@528
    74
  /// matching problem
jacint@528
    75
  template<typename Graph>
jacint@528
    76
  void readDimacs(std::istream& is, Graph &g) {
jacint@528
    77
    typename Graph::Node u;
jacint@528
    78
    NullMap<typename Graph::Edge, int> n;
jacint@528
    79
    readDimacs(is, g, n, u, u, n);
jacint@528
    80
  }
jacint@528
    81
jacint@528
    82
  /// sg problem
jacint@528
    83
  template<typename Graph, typename CapacityMap>
jacint@528
    84
  void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity) {
jacint@528
    85
    typename Graph::Node u;
jacint@528
    86
    NullMap<typename Graph::Edge, int> n;
alpar@533
    87
    readDimacs(is, g, capacity, u, u, n);
jacint@528
    88
  }
jacint@528
    89
jacint@528
    90
  /// shortest path problem
jacint@528
    91
  template<typename Graph, typename CapacityMap>
jacint@528
    92
  void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity, 
jacint@528
    93
		  typename Graph::Node &s) {
jacint@528
    94
    NullMap<typename Graph::Edge, int> n;
jacint@528
    95
    readDimacs(is, g, capacity, s, s, n);
jacint@528
    96
  }
jacint@528
    97
jacint@528
    98
  /// max flow problem
jacint@528
    99
  template<typename Graph, typename CapacityMap>
jacint@528
   100
  void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity, 
jacint@528
   101
		  typename Graph::Node &s, typename Graph::Node &t) {
jacint@528
   102
    NullMap<typename Graph::Edge, int> n;
jacint@528
   103
    readDimacs(is, g, capacity, s, t, n);
jacint@528
   104
  }
jacint@528
   105
jacint@528
   106
  /// min cost flow problem
jacint@528
   107
  template<typename Graph, typename CapacityMap, typename CostMap>
jacint@528
   108
  void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity, 
jacint@528
   109
		  typename Graph::Node &s, typename Graph::Node &t, 
jacint@528
   110
		  CostMap& cost) {
jacint@528
   111
    g.clear();
jacint@528
   112
    typename CapacityMap::ValueType _cap;
jacint@528
   113
    typename CostMap::ValueType _cost;
jacint@528
   114
    char d;
jacint@528
   115
    std::string problem;
jacint@528
   116
    char c;
jacint@528
   117
    int i, j;
jacint@528
   118
    std::string str;
jacint@528
   119
    int n, m; 
jacint@528
   120
    typename Graph::Edge e;
jacint@528
   121
    std::vector<typename Graph::Node> nodes;
jacint@528
   122
    while (is>>c) {
jacint@528
   123
      switch (c) {
jacint@528
   124
      case 'c': //comment
jacint@528
   125
	getline(is, str);
jacint@528
   126
	break;
jacint@528
   127
      case 'p': //problem definition
jacint@528
   128
	is >> problem >> n >> m;
jacint@528
   129
	getline(is, str);
jacint@528
   130
	nodes.resize(n+1);
jacint@528
   131
	for (int k=1; k<=n; ++k) nodes[k]=g.addNode();
jacint@528
   132
	break;
jacint@528
   133
      case 'n': //node definition
jacint@528
   134
	if (problem=="sp") { //shortest path problem
jacint@528
   135
	  is >> i;
jacint@528
   136
	  getline(is, str);
jacint@528
   137
	  s=nodes[i];
jacint@528
   138
	}
jacint@528
   139
	if (problem=="max" || problem=="min") { //((max) or (min cost)) flow problem
jacint@528
   140
	  is >> i >> d;
jacint@528
   141
	  getline(is, str);
jacint@528
   142
	  if (d=='s') s=nodes[i];
jacint@528
   143
	  if (d=='t') t=nodes[i];
jacint@528
   144
	}
jacint@528
   145
	break;
jacint@528
   146
      case 'a':
jacint@528
   147
	if ( problem == "mat" ) {
jacint@528
   148
	  is >> i >> j;
jacint@528
   149
	  getline(is, str);
jacint@528
   150
	  g.addEdge(nodes[i], nodes[j]);
jacint@528
   151
	}
jacint@528
   152
	if ( problem == "max" || problem == "sp") {
jacint@528
   153
	  is >> i >> j >> _cap;
jacint@528
   154
	  getline(is, str);
jacint@528
   155
	  e=g.addEdge(nodes[i], nodes[j]);
jacint@528
   156
	  capacity.update();
jacint@528
   157
	  capacity.set(e, _cap);
jacint@528
   158
	}
jacint@528
   159
	if ( problem == "min" ) {
jacint@528
   160
	  is >> i >> j >> _cap >> _cost;
jacint@528
   161
	  getline(is, str);
jacint@528
   162
	  e=g.addEdge(nodes[i], nodes[j]);
jacint@528
   163
	  capacity.update();
jacint@528
   164
	  capacity.set(e, _cap);
jacint@528
   165
	  cost.update();
jacint@528
   166
	  cost.set(e, _cost);
jacint@528
   167
	}
jacint@528
   168
	break;
jacint@528
   169
      }
jacint@528
   170
    }
jacint@528
   171
  }
jacint@528
   172
jacint@528
   173
marci@423
   174
  
jacint@528
   175
  /// write matching problem
jacint@528
   176
  template<typename Graph>
jacint@528
   177
  void writeDimacs(std::ostream& os, const Graph &g) {
jacint@528
   178
    typedef typename Graph::NodeIt NodeIt;
jacint@528
   179
    typedef typename Graph::EdgeIt EdgeIt;  
jacint@528
   180
    
jacint@528
   181
    typename Graph::template NodeMap<int> nodes(g);
jacint@528
   182
jacint@528
   183
    os << "c matching problem" << std::endl;
jacint@528
   184
jacint@528
   185
    int i=1;
jacint@528
   186
    NodeIt v;
jacint@528
   187
    for(g.first(v); g.valid(v); g.next(v)) {
jacint@528
   188
      nodes.set(v, i);
jacint@528
   189
      ++i;
jacint@528
   190
    }    
jacint@528
   191
    
jacint@528
   192
    os << "p mat " << g.nodeNum() << " " << g.edgeNum() << std::endl;
jacint@528
   193
jacint@528
   194
    EdgeIt e;
jacint@528
   195
    for(g.first(e); g.valid(e); g.next(e)) {
jacint@528
   196
      os << "a " << nodes[g.tail(e)] << " " << nodes[g.head(e)] << std::endl; 
jacint@528
   197
    }
jacint@528
   198
jacint@528
   199
  }
jacint@528
   200
jacint@528
   201
jacint@528
   202
marci@423
   203
} //namespace hugo
marci@423
   204
marci@423
   205
#endif //HUGO_DIMACS_H