lemon/dimacs.h
author deba
Wed, 01 Mar 2006 10:25:30 +0000
changeset 1991 d7442141d9ef
parent 1946 17eb3eaad9f8
child 1993 2115143eceea
permissions -rw-r--r--
The graph adadptors can be alteration observed.
In most cases it uses the adapted graph alteration notifiers.
Only special case is now the UndirGraphAdaptor, where
we have to proxy the signals from the graph.

The SubBidirGraphAdaptor is removed, because it doest not
gives more feature than the EdgeSubGraphAdaptor<UndirGraphAdaptor<Graph>>.

The ResGraphAdaptor is based on this composition.
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@1190
    26
#include <lemon/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