COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/dimacs.h @ 2413:21eb3ccdc3df

Last change on this file since 2413:21eb3ccdc3df was 2413:21eb3ccdc3df, checked in by Balazs Dezso, 17 years ago

Right dimacs format for min cost flows
Bug fixes in tolerance and min_mean_cycle

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