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