... |
... |
@@ -18,66 +18,58 @@
|
18 |
18 |
|
19 |
19 |
#ifndef LEMON_DIMACS_H
|
20 |
20 |
#define LEMON_DIMACS_H
|
21 |
21 |
|
22 |
22 |
#include <iostream>
|
23 |
23 |
#include <string>
|
24 |
24 |
#include <vector>
|
25 |
25 |
#include <lemon/maps.h>
|
26 |
26 |
#include <lemon/error.h>
|
27 |
27 |
|
28 |
28 |
/// \ingroup dimacs_group
|
29 |
29 |
/// \file
|
30 |
30 |
/// \brief DIMACS file format reader.
|
31 |
31 |
|
32 |
32 |
namespace lemon {
|
33 |
33 |
|
34 |
|
///@defgroup dimacs_group DIMACS format
|
35 |
|
///\brief Read and write files in DIMACS format
|
36 |
|
///
|
37 |
|
///Tools to read a digraph from or write it to a file in DIMACS format
|
38 |
|
///data
|
39 |
|
///\ingroup io_group
|
40 |
|
|
41 |
34 |
/// \addtogroup dimacs_group
|
42 |
35 |
/// @{
|
43 |
36 |
|
44 |
|
|
45 |
37 |
/// DIMACS file type descriptor.
|
46 |
38 |
struct DimacsDescriptor
|
47 |
39 |
{
|
48 |
40 |
///File type enum
|
49 |
41 |
enum Type
|
50 |
42 |
{
|
51 |
43 |
NONE, MIN, MAX, SP, MAT
|
52 |
44 |
};
|
53 |
45 |
///The file type
|
54 |
46 |
Type type;
|
55 |
|
///The number of nodes on the graph
|
|
47 |
///The number of nodes in the graph
|
56 |
48 |
int nodeNum;
|
57 |
|
///The number of edges on the graph
|
|
49 |
///The number of edges in the graph
|
58 |
50 |
int edgeNum;
|
59 |
51 |
int lineShift;
|
60 |
52 |
/// Constructor. Sets the type to NONE.
|
61 |
53 |
DimacsDescriptor() : type(NONE) {}
|
62 |
54 |
};
|
63 |
55 |
|
64 |
56 |
///Discover the type of a DIMACS file
|
65 |
57 |
|
66 |
58 |
///It starts seeking the begining of the file for the problem type
|
67 |
|
///and size info. The found date is returned in a special struct
|
|
59 |
///and size info. The found data is returned in a special struct
|
68 |
60 |
///that can be evaluated and passed to the appropriate reader
|
69 |
61 |
///function.
|
70 |
62 |
DimacsDescriptor dimacsType(std::istream& is)
|
71 |
63 |
{
|
72 |
64 |
DimacsDescriptor r;
|
73 |
65 |
std::string problem,str;
|
74 |
66 |
char c;
|
75 |
67 |
r.lineShift=0;
|
76 |
68 |
while (is >> c)
|
77 |
69 |
switch(c)
|
78 |
70 |
{
|
79 |
71 |
case 'p':
|
80 |
72 |
if(is >> problem >> r.nodeNum >> r.edgeNum)
|
81 |
73 |
{
|
82 |
74 |
getline(is, str);
|
83 |
75 |
r.lineShift++;
|
... |
... |
@@ -92,36 +84,36 @@
|
92 |
84 |
{
|
93 |
85 |
throw FormatError("Missing or wrong problem type declaration.");
|
94 |
86 |
}
|
95 |
87 |
break;
|
96 |
88 |
case 'c':
|
97 |
89 |
getline(is, str);
|
98 |
90 |
r.lineShift++;
|
99 |
91 |
break;
|
100 |
92 |
default:
|
101 |
93 |
throw FormatError("Unknown DIMACS declaration.");
|
102 |
94 |
}
|
103 |
95 |
throw FormatError("Missing problem type declaration.");
|
104 |
96 |
}
|
105 |
97 |
|
106 |
98 |
|
107 |
99 |
|
108 |
|
/// DIMACS min cost flow reader function.
|
|
100 |
/// DIMACS minimum cost flow reader function.
|
109 |
101 |
///
|
110 |
|
/// This function reads a min cost flow instance from DIMACS format,
|
111 |
|
/// i.e. from DIMACS files having a line starting with
|
|
102 |
/// This function reads a minimum cost flow instance from DIMACS format,
|
|
103 |
/// i.e. from a DIMACS file having a line starting with
|
112 |
104 |
/// \code
|
113 |
105 |
/// p min
|
114 |
106 |
/// \endcode
|
115 |
107 |
/// At the beginning, \c g is cleared by \c g.clear(). The supply
|
116 |
108 |
/// amount of the nodes are written to \c supply (signed). The
|
117 |
109 |
/// lower bounds, capacities and costs of the arcs are written to
|
118 |
110 |
/// \c lower, \c capacity and \c cost.
|
119 |
111 |
///
|
120 |
112 |
/// If the file type was previously evaluated by dimacsType(), then
|
121 |
113 |
/// the descriptor struct should be given by the \c dest parameter.
|
122 |
114 |
template <typename Digraph, typename LowerMap,
|
123 |
115 |
typename CapacityMap, typename CostMap,
|
124 |
116 |
typename SupplyMap>
|
125 |
117 |
void readDimacsMin(std::istream& is,
|
126 |
118 |
Digraph &g,
|
127 |
119 |
LowerMap& lower,
|
... |
... |
@@ -217,67 +209,67 @@
|
217 |
209 |
if (desc.type==DimacsDescriptor::SP ||
|
218 |
210 |
desc.type==DimacsDescriptor::MAX) {
|
219 |
211 |
is >> i >> j >> _cap;
|
220 |
212 |
getline(is, str);
|
221 |
213 |
e = g.addArc(nodes[i], nodes[j]);
|
222 |
214 |
capacity.set(e, _cap);
|
223 |
215 |
} else {
|
224 |
216 |
is >> i >> j;
|
225 |
217 |
getline(is, str);
|
226 |
218 |
g.addArc(nodes[i], nodes[j]);
|
227 |
219 |
}
|
228 |
220 |
break;
|
229 |
221 |
}
|
230 |
222 |
}
|
231 |
223 |
}
|
232 |
224 |
|
233 |
|
/// DIMACS max flow reader function.
|
|
225 |
/// DIMACS maximum flow reader function.
|
234 |
226 |
///
|
235 |
|
/// This function reads a max flow instance from DIMACS format,
|
236 |
|
/// i.e. from DIMACS files having a line starting with
|
|
227 |
/// This function reads a maximum flow instance from DIMACS format,
|
|
228 |
/// i.e. from a DIMACS file having a line starting with
|
237 |
229 |
/// \code
|
238 |
230 |
/// p max
|
239 |
231 |
/// \endcode
|
240 |
232 |
/// At the beginning, \c g is cleared by \c g.clear(). The arc
|
241 |
233 |
/// capacities are written to \c capacity and \c s and \c t are
|
242 |
234 |
/// set to the source and the target nodes.
|
243 |
235 |
///
|
244 |
236 |
/// If the file type was previously evaluated by dimacsType(), then
|
245 |
237 |
/// the descriptor struct should be given by the \c dest parameter.
|
246 |
238 |
template<typename Digraph, typename CapacityMap>
|
247 |
239 |
void readDimacsMax(std::istream& is,
|
248 |
240 |
Digraph &g,
|
249 |
241 |
CapacityMap& capacity,
|
250 |
242 |
typename Digraph::Node &s,
|
251 |
243 |
typename Digraph::Node &t,
|
252 |
244 |
DimacsDescriptor desc=DimacsDescriptor()) {
|
253 |
245 |
if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
|
254 |
246 |
if(desc.type!=DimacsDescriptor::MAX)
|
255 |
247 |
throw FormatError("Problem type mismatch");
|
256 |
248 |
_readDimacs(is,g,capacity,s,t,desc);
|
257 |
249 |
}
|
258 |
250 |
|
259 |
251 |
/// DIMACS shortest path reader function.
|
260 |
252 |
///
|
261 |
253 |
/// This function reads a shortest path instance from DIMACS format,
|
262 |
|
/// i.e. from DIMACS files having a line starting with
|
|
254 |
/// i.e. from a DIMACS file having a line starting with
|
263 |
255 |
/// \code
|
264 |
256 |
/// p sp
|
265 |
257 |
/// \endcode
|
266 |
258 |
/// At the beginning, \c g is cleared by \c g.clear(). The arc
|
267 |
|
/// lengths are written to \c lenght and \c s is set to the
|
|
259 |
/// lengths are written to \c length and \c s is set to the
|
268 |
260 |
/// source node.
|
269 |
261 |
///
|
270 |
262 |
/// If the file type was previously evaluated by dimacsType(), then
|
271 |
263 |
/// the descriptor struct should be given by the \c dest parameter.
|
272 |
264 |
template<typename Digraph, typename LengthMap>
|
273 |
265 |
void readDimacsSp(std::istream& is,
|
274 |
266 |
Digraph &g,
|
275 |
267 |
LengthMap& length,
|
276 |
268 |
typename Digraph::Node &s,
|
277 |
269 |
DimacsDescriptor desc=DimacsDescriptor()) {
|
278 |
270 |
typename Digraph::Node t;
|
279 |
271 |
if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
|
280 |
272 |
if(desc.type!=DimacsDescriptor::SP)
|
281 |
273 |
throw FormatError("Problem type mismatch");
|
282 |
274 |
_readDimacs(is, g, length, s, t,desc);
|
283 |
275 |
}
|