gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
dimacs.h reads MAT files to both dir and undir graphs (#231)
0 1 0
default
1 file changed with 46 insertions and 8 deletions:
↑ Collapse diff ↑
Ignore white space 96 line context
... ...
@@ -250,108 +250,146 @@
250 250

	
251 251
  /// DIMACS shortest path reader function.
252 252
  ///
253 253
  /// This function reads a shortest path instance from DIMACS format,
254 254
  /// i.e. from a DIMACS file having a line starting with
255 255
  /// \code
256 256
  ///   p sp
257 257
  /// \endcode
258 258
  /// At the beginning, \c g is cleared by \c g.clear(). The arc
259 259
  /// lengths are written to \c length and \c s is set to the
260 260
  /// source node.
261 261
  ///
262 262
  /// If the file type was previously evaluated by dimacsType(), then
263 263
  /// the descriptor struct should be given by the \c dest parameter.
264 264
  template<typename Digraph, typename LengthMap>
265 265
  void readDimacsSp(std::istream& is,
266 266
                    Digraph &g,
267 267
                    LengthMap& length,
268 268
                    typename Digraph::Node &s,
269 269
                    DimacsDescriptor desc=DimacsDescriptor()) {
270 270
    typename Digraph::Node t;
271 271
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
272 272
    if(desc.type!=DimacsDescriptor::SP)
273 273
      throw FormatError("Problem type mismatch");
274 274
    _readDimacs(is, g, length, s, t,desc);
275 275
  }
276 276

	
277 277
  /// DIMACS capacitated digraph reader function.
278 278
  ///
279 279
  /// This function reads an arc capacitated digraph instance from
280 280
  /// DIMACS 'mat' or 'sp' format.
281 281
  /// At the beginning, \c g is cleared by \c g.clear()
282 282
  /// and the arc capacities/lengths are written to \c capacity.
283 283
  ///
284 284
  /// If the file type was previously evaluated by dimacsType(), then
285 285
  /// the descriptor struct should be given by the \c dest parameter.
286 286
  template<typename Digraph, typename CapacityMap>
287 287
  void readDimacsCap(std::istream& is,
288 288
                     Digraph &g,
289 289
                     CapacityMap& capacity,
290 290
                     DimacsDescriptor desc=DimacsDescriptor()) {
291 291
    typename Digraph::Node u,v;
292 292
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
293 293
    if(desc.type!=DimacsDescriptor::MAX || desc.type!=DimacsDescriptor::SP)
294 294
      throw FormatError("Problem type mismatch");
295 295
    _readDimacs(is, g, capacity, u, v, desc);
296 296
  }
297 297

	
298
  /// DIMACS plain digraph reader function.
298
  template<typename Graph>
299
  typename enable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
300
  _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
301
              dummy<0> = 0)
302
  {
303
    g.addEdge(s,t);
304
  }
305
  template<typename Graph>
306
  typename disable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
307
  _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
308
              dummy<1> = 1)
309
  {
310
    g.addArc(s,t);
311
  }
312
  
313
  /// DIMACS plain (di)graph reader function.
299 314
  ///
300
  /// This function reads a digraph without any designated nodes and
315
  /// This function reads a (di)graph without any designated nodes and
301 316
  /// maps from DIMACS format, i.e. from DIMACS files having a line
302 317
  /// starting with
303 318
  /// \code
304 319
  ///   p mat
305 320
  /// \endcode
306 321
  /// At the beginning, \c g is cleared by \c g.clear().
307 322
  ///
308 323
  /// If the file type was previously evaluated by dimacsType(), then
309 324
  /// the descriptor struct should be given by the \c dest parameter.
310
  template<typename Digraph>
311
  void readDimacsMat(std::istream& is, Digraph &g,
312
                     DimacsDescriptor desc=DimacsDescriptor()) {
313
    typename Digraph::Node u,v;
314
    NullMap<typename Digraph::Arc, int> n;
325
  template<typename Graph>
326
  void readDimacsMat(std::istream& is, Graph &g,
327
                     DimacsDescriptor desc=DimacsDescriptor())
328
  {
315 329
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
316 330
    if(desc.type!=DimacsDescriptor::MAT)
317 331
      throw FormatError("Problem type mismatch");
318
    _readDimacs(is, g, n, u, v, desc);
332

	
333
    g.clear();
334
    std::vector<typename Graph::Node> nodes;
335
    char c;
336
    int i, j;
337
    std::string str;
338
    nodes.resize(desc.nodeNum + 1);
339
    for (int k = 1; k <= desc.nodeNum; ++k) {
340
      nodes[k] = g.addNode();
341
    }
342
    
343
    while (is >> c) {
344
      switch (c) {
345
      case 'c': // comment line
346
        getline(is, str);
347
        break;
348
      case 'n': // node definition line
349
        break;
350
      case 'a': // arc (arc) definition line
351
        is >> i >> j;
352
        getline(is, str);
353
        _addArcEdge(g,nodes[i], nodes[j]);
354
        break;
355
      }
356
    }
319 357
  }
320 358

	
321 359
  /// DIMACS plain digraph writer function.
322 360
  ///
323 361
  /// This function writes a digraph without any designated nodes and
324 362
  /// maps into DIMACS format, i.e. into DIMACS file having a line
325 363
  /// starting with
326 364
  /// \code
327 365
  ///   p mat
328 366
  /// \endcode
329 367
  /// If \c comment is not empty, then it will be printed in the first line
330 368
  /// prefixed by 'c'.
331 369
  template<typename Digraph>
332 370
  void writeDimacsMat(std::ostream& os, const Digraph &g,
333 371
                      std::string comment="") {
334 372
    typedef typename Digraph::NodeIt NodeIt;
335 373
    typedef typename Digraph::ArcIt ArcIt;
336 374

	
337 375
    if(!comment.empty())
338 376
      os << "c " << comment << std::endl;
339 377
    os << "p mat " << g.nodeNum() << " " << g.arcNum() << std::endl;
340 378

	
341 379
    typename Digraph::template NodeMap<int> nodes(g);
342 380
    int i = 1;
343 381
    for(NodeIt v(g); v != INVALID; ++v) {
344 382
      nodes.set(v, i);
345 383
      ++i;
346 384
    }
347 385
    for(ArcIt e(g); e != INVALID; ++e) {
348 386
      os << "a " << nodes[g.source(e)] << " " << nodes[g.target(e)]
349 387
         << std::endl;
350 388
    }
351 389
  }
352 390

	
353 391
  /// @}
354 392

	
355 393
} //namespace lemon
356 394

	
357 395
#endif //LEMON_DIMACS_H
0 comments (0 inline)