gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Add tolerance() functions for MMC classes (#179)
0 4 0
default
4 files changed with 57 insertions and 0 deletions:
↑ Collapse diff ↑
Ignore white space 768 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_HARTMANN_ORLIN_H
20 20
#define LEMON_HARTMANN_ORLIN_H
21 21

	
22 22
/// \ingroup min_mean_cycle
23 23
///
24 24
/// \file
25 25
/// \brief Hartmann-Orlin's algorithm for finding a minimum mean cycle.
26 26

	
27 27
#include <vector>
28 28
#include <limits>
29 29
#include <lemon/core.h>
30 30
#include <lemon/path.h>
31 31
#include <lemon/tolerance.h>
32 32
#include <lemon/connectivity.h>
33 33

	
34 34
namespace lemon {
35 35

	
36 36
  /// \brief Default traits class of HartmannOrlin algorithm.
37 37
  ///
38 38
  /// Default traits class of HartmannOrlin algorithm.
39 39
  /// \tparam GR The type of the digraph.
40 40
  /// \tparam LEN The type of the length map.
41 41
  /// It must conform to the \ref concepts::Rea_data "Rea_data" concept.
42 42
#ifdef DOXYGEN
43 43
  template <typename GR, typename LEN>
44 44
#else
45 45
  template <typename GR, typename LEN,
46 46
    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
47 47
#endif
48 48
  struct HartmannOrlinDefaultTraits
49 49
  {
50 50
    /// The type of the digraph
51 51
    typedef GR Digraph;
52 52
    /// The type of the length map
53 53
    typedef LEN LengthMap;
54 54
    /// The type of the arc lengths
55 55
    typedef typename LengthMap::Value Value;
56 56

	
57 57
    /// \brief The large value type used for internal computations
58 58
    ///
59 59
    /// The large value type used for internal computations.
60 60
    /// It is \c long \c long if the \c Value type is integer,
61 61
    /// otherwise it is \c double.
62 62
    /// \c Value must be convertible to \c LargeValue.
63 63
    typedef double LargeValue;
64 64

	
65 65
    /// The tolerance type used for internal computations
66 66
    typedef lemon::Tolerance<LargeValue> Tolerance;
67 67

	
68 68
    /// \brief The path type of the found cycles
69 69
    ///
70 70
    /// The path type of the found cycles.
71 71
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
72 72
    /// and it must have an \c addBack() function.
73 73
    typedef lemon::Path<Digraph> Path;
74 74
  };
75 75

	
76 76
  // Default traits class for integer value types
77 77
  template <typename GR, typename LEN>
78 78
  struct HartmannOrlinDefaultTraits<GR, LEN, true>
79 79
  {
80 80
    typedef GR Digraph;
81 81
    typedef LEN LengthMap;
82 82
    typedef typename LengthMap::Value Value;
83 83
#ifdef LEMON_HAVE_LONG_LONG
84 84
    typedef long long LargeValue;
85 85
#else
86 86
    typedef long LargeValue;
87 87
#endif
88 88
    typedef lemon::Tolerance<LargeValue> Tolerance;
89 89
    typedef lemon::Path<Digraph> Path;
90 90
  };
91 91

	
92 92

	
93 93
  /// \addtogroup min_mean_cycle
94 94
  /// @{
95 95

	
96 96
  /// \brief Implementation of the Hartmann-Orlin algorithm for finding
97 97
  /// a minimum mean cycle.
98 98
  ///
99 99
  /// This class implements the Hartmann-Orlin algorithm for finding
100 100
  /// a directed cycle of minimum mean length (cost) in a digraph.
101 101
  /// It is an improved version of \ref Karp "Karp"'s original algorithm,
102 102
  /// it applies an efficient early termination scheme.
103 103
  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
104 104
  ///
105 105
  /// \tparam GR The type of the digraph the algorithm runs on.
106 106
  /// \tparam LEN The type of the length map. The default
107 107
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
108 108
#ifdef DOXYGEN
109 109
  template <typename GR, typename LEN, typename TR>
110 110
#else
111 111
  template < typename GR,
112 112
             typename LEN = typename GR::template ArcMap<int>,
113 113
             typename TR = HartmannOrlinDefaultTraits<GR, LEN> >
114 114
#endif
115 115
  class HartmannOrlin
116 116
  {
117 117
  public:
118 118

	
119 119
    /// The type of the digraph
120 120
    typedef typename TR::Digraph Digraph;
121 121
    /// The type of the length map
122 122
    typedef typename TR::LengthMap LengthMap;
123 123
    /// The type of the arc lengths
124 124
    typedef typename TR::Value Value;
125 125

	
126 126
    /// \brief The large value type
127 127
    ///
128 128
    /// The large value type used for internal computations.
129 129
    /// Using the \ref HartmannOrlinDefaultTraits "default traits class",
130 130
    /// it is \c long \c long if the \c Value type is integer,
131 131
    /// otherwise it is \c double.
132 132
    typedef typename TR::LargeValue LargeValue;
133 133

	
134 134
    /// The tolerance type
135 135
    typedef typename TR::Tolerance Tolerance;
136 136

	
137 137
    /// \brief The path type of the found cycles
138 138
    ///
139 139
    /// The path type of the found cycles.
140 140
    /// Using the \ref HartmannOrlinDefaultTraits "default traits class",
141 141
    /// it is \ref lemon::Path "Path<Digraph>".
142 142
    typedef typename TR::Path Path;
143 143

	
144 144
    /// The \ref HartmannOrlinDefaultTraits "traits class" of the algorithm
145 145
    typedef TR Traits;
146 146

	
147 147
  private:
148 148

	
149 149
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
150 150

	
151 151
    // Data sturcture for path data
152 152
    struct PathData
153 153
    {
154 154
      LargeValue dist;
155 155
      Arc pred;
156 156
      PathData(LargeValue d, Arc p = INVALID) :
157 157
        dist(d), pred(p) {}
158 158
    };
159 159

	
160 160
    typedef typename Digraph::template NodeMap<std::vector<PathData> >
161 161
      PathDataNodeMap;
162 162

	
163 163
  private:
164 164

	
165 165
    // The digraph the algorithm runs on
166 166
    const Digraph &_gr;
167 167
    // The length of the arcs
168 168
    const LengthMap &_length;
169 169

	
170 170
    // Data for storing the strongly connected components
171 171
    int _comp_num;
172 172
    typename Digraph::template NodeMap<int> _comp;
173 173
    std::vector<std::vector<Node> > _comp_nodes;
174 174
    std::vector<Node>* _nodes;
175 175
    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
176 176

	
177 177
    // Data for the found cycles
178 178
    bool _curr_found, _best_found;
179 179
    LargeValue _curr_length, _best_length;
180 180
    int _curr_size, _best_size;
181 181
    Node _curr_node, _best_node;
182 182
    int _curr_level, _best_level;
183 183

	
184 184
    Path *_cycle_path;
185 185
    bool _local_path;
186 186

	
187 187
    // Node map for storing path data
188 188
    PathDataNodeMap _data;
189 189
    // The processed nodes in the last round
190 190
    std::vector<Node> _process;
191 191

	
192 192
    Tolerance _tolerance;
193 193

	
194 194
    // Infinite constant
195 195
    const LargeValue INF;
196 196

	
197 197
  public:
198 198

	
199 199
    /// \name Named Template Parameters
200 200
    /// @{
201 201

	
202 202
    template <typename T>
203 203
    struct SetLargeValueTraits : public Traits {
204 204
      typedef T LargeValue;
205 205
      typedef lemon::Tolerance<T> Tolerance;
206 206
    };
207 207

	
208 208
    /// \brief \ref named-templ-param "Named parameter" for setting
209 209
    /// \c LargeValue type.
210 210
    ///
211 211
    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
212 212
    /// type. It is used for internal computations in the algorithm.
213 213
    template <typename T>
214 214
    struct SetLargeValue
215 215
      : public HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > {
216 216
      typedef HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > Create;
217 217
    };
218 218

	
219 219
    template <typename T>
220 220
    struct SetPathTraits : public Traits {
221 221
      typedef T Path;
222 222
    };
223 223

	
224 224
    /// \brief \ref named-templ-param "Named parameter" for setting
225 225
    /// \c %Path type.
226 226
    ///
227 227
    /// \ref named-templ-param "Named parameter" for setting the \c %Path
228 228
    /// type of the found cycles.
229 229
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
230 230
    /// and it must have an \c addFront() function.
231 231
    template <typename T>
232 232
    struct SetPath
233 233
      : public HartmannOrlin<GR, LEN, SetPathTraits<T> > {
234 234
      typedef HartmannOrlin<GR, LEN, SetPathTraits<T> > Create;
235 235
    };
236 236

	
237 237
    /// @}
238 238

	
239 239
  public:
240 240

	
241 241
    /// \brief Constructor.
242 242
    ///
243 243
    /// The constructor of the class.
244 244
    ///
245 245
    /// \param digraph The digraph the algorithm runs on.
246 246
    /// \param length The lengths (costs) of the arcs.
247 247
    HartmannOrlin( const Digraph &digraph,
248 248
                   const LengthMap &length ) :
249 249
      _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
250 250
      _best_found(false), _best_length(0), _best_size(1),
251 251
      _cycle_path(NULL), _local_path(false), _data(digraph),
252 252
      INF(std::numeric_limits<LargeValue>::has_infinity ?
253 253
          std::numeric_limits<LargeValue>::infinity() :
254 254
          std::numeric_limits<LargeValue>::max())
255 255
    {}
256 256

	
257 257
    /// Destructor.
258 258
    ~HartmannOrlin() {
259 259
      if (_local_path) delete _cycle_path;
260 260
    }
261 261

	
262 262
    /// \brief Set the path structure for storing the found cycle.
263 263
    ///
264 264
    /// This function sets an external path structure for storing the
265 265
    /// found cycle.
266 266
    ///
267 267
    /// If you don't call this function before calling \ref run() or
268 268
    /// \ref findMinMean(), it will allocate a local \ref Path "path"
269 269
    /// structure. The destuctor deallocates this automatically
270 270
    /// allocated object, of course.
271 271
    ///
272 272
    /// \note The algorithm calls only the \ref lemon::Path::addFront()
273 273
    /// "addFront()" function of the given path structure.
274 274
    ///
275 275
    /// \return <tt>(*this)</tt>
276 276
    HartmannOrlin& cycle(Path &path) {
277 277
      if (_local_path) {
278 278
        delete _cycle_path;
279 279
        _local_path = false;
280 280
      }
281 281
      _cycle_path = &path;
282 282
      return *this;
283 283
    }
284 284

	
285
    /// \brief Set the tolerance used by the algorithm.
286
    ///
287
    /// This function sets the tolerance object used by the algorithm.
288
    ///
289
    /// \return <tt>(*this)</tt>
290
    HartmannOrlin& tolerance(const Tolerance& tolerance) {
291
      _tolerance = tolerance;
292
      return *this;
293
    }
294

	
295
    /// \brief Return a const reference to the tolerance.
296
    ///
297
    /// This function returns a const reference to the tolerance object
298
    /// used by the algorithm.
299
    const Tolerance& tolerance() const {
300
      return _tolerance;
301
    }
302

	
285 303
    /// \name Execution control
286 304
    /// The simplest way to execute the algorithm is to call the \ref run()
287 305
    /// function.\n
288 306
    /// If you only need the minimum mean length, you may call
289 307
    /// \ref findMinMean().
290 308

	
291 309
    /// @{
292 310

	
293 311
    /// \brief Run the algorithm.
294 312
    ///
295 313
    /// This function runs the algorithm.
296 314
    /// It can be called more than once (e.g. if the underlying digraph
297 315
    /// and/or the arc lengths have been modified).
298 316
    ///
299 317
    /// \return \c true if a directed cycle exists in the digraph.
300 318
    ///
301 319
    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
302 320
    /// \code
303 321
    ///   return mmc.findMinMean() && mmc.findCycle();
304 322
    /// \endcode
305 323
    bool run() {
306 324
      return findMinMean() && findCycle();
307 325
    }
308 326

	
309 327
    /// \brief Find the minimum cycle mean.
310 328
    ///
311 329
    /// This function finds the minimum mean length of the directed
312 330
    /// cycles in the digraph.
313 331
    ///
314 332
    /// \return \c true if a directed cycle exists in the digraph.
315 333
    bool findMinMean() {
316 334
      // Initialization and find strongly connected components
317 335
      init();
318 336
      findComponents();
319 337
      
320 338
      // Find the minimum cycle mean in the components
321 339
      for (int comp = 0; comp < _comp_num; ++comp) {
322 340
        if (!initComponent(comp)) continue;
323 341
        processRounds();
324 342
        
325 343
        // Update the best cycle (global minimum mean cycle)
326 344
        if ( _curr_found && (!_best_found || 
327 345
             _curr_length * _best_size < _best_length * _curr_size) ) {
328 346
          _best_found = true;
329 347
          _best_length = _curr_length;
330 348
          _best_size = _curr_size;
331 349
          _best_node = _curr_node;
332 350
          _best_level = _curr_level;
333 351
        }
334 352
      }
335 353
      return _best_found;
336 354
    }
337 355

	
338 356
    /// \brief Find a minimum mean directed cycle.
339 357
    ///
340 358
    /// This function finds a directed cycle of minimum mean length
341 359
    /// in the digraph using the data computed by findMinMean().
342 360
    ///
343 361
    /// \return \c true if a directed cycle exists in the digraph.
344 362
    ///
345 363
    /// \pre \ref findMinMean() must be called before using this function.
346 364
    bool findCycle() {
347 365
      if (!_best_found) return false;
348 366
      IntNodeMap reached(_gr, -1);
349 367
      int r = _best_level + 1;
350 368
      Node u = _best_node;
351 369
      while (reached[u] < 0) {
352 370
        reached[u] = --r;
353 371
        u = _gr.source(_data[u][r].pred);
354 372
      }
355 373
      r = reached[u];
356 374
      Arc e = _data[u][r].pred;
357 375
      _cycle_path->addFront(e);
358 376
      _best_length = _length[e];
359 377
      _best_size = 1;
360 378
      Node v;
361 379
      while ((v = _gr.source(e)) != u) {
362 380
        e = _data[v][--r].pred;
363 381
        _cycle_path->addFront(e);
364 382
        _best_length += _length[e];
365 383
        ++_best_size;
366 384
      }
367 385
      return true;
368 386
    }
369 387

	
370 388
    /// @}
371 389

	
372 390
    /// \name Query Functions
373 391
    /// The results of the algorithm can be obtained using these
374 392
    /// functions.\n
375 393
    /// The algorithm should be executed before using them.
376 394

	
377 395
    /// @{
378 396

	
379 397
    /// \brief Return the total length of the found cycle.
380 398
    ///
381 399
    /// This function returns the total length of the found cycle.
382 400
    ///
383 401
    /// \pre \ref run() or \ref findMinMean() must be called before
384 402
    /// using this function.
385 403
    LargeValue cycleLength() const {
386 404
      return _best_length;
387 405
    }
388 406

	
389 407
    /// \brief Return the number of arcs on the found cycle.
390 408
    ///
391 409
    /// This function returns the number of arcs on the found cycle.
392 410
    ///
393 411
    /// \pre \ref run() or \ref findMinMean() must be called before
394 412
    /// using this function.
395 413
    int cycleArcNum() const {
396 414
      return _best_size;
397 415
    }
398 416

	
399 417
    /// \brief Return the mean length of the found cycle.
400 418
    ///
401 419
    /// This function returns the mean length of the found cycle.
402 420
    ///
403 421
    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
404 422
    /// following code.
405 423
    /// \code
406 424
    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
407 425
    /// \endcode
408 426
    ///
409 427
    /// \pre \ref run() or \ref findMinMean() must be called before
410 428
    /// using this function.
411 429
    double cycleMean() const {
412 430
      return static_cast<double>(_best_length) / _best_size;
413 431
    }
414 432

	
415 433
    /// \brief Return the found cycle.
416 434
    ///
417 435
    /// This function returns a const reference to the path structure
418 436
    /// storing the found cycle.
419 437
    ///
420 438
    /// \pre \ref run() or \ref findCycle() must be called before using
421 439
    /// this function.
422 440
    const Path& cycle() const {
423 441
      return *_cycle_path;
424 442
    }
425 443

	
426 444
    ///@}
427 445

	
428 446
  private:
429 447

	
430 448
    // Initialization
431 449
    void init() {
432 450
      if (!_cycle_path) {
433 451
        _local_path = true;
434 452
        _cycle_path = new Path;
435 453
      }
436 454
      _cycle_path->clear();
437 455
      _best_found = false;
438 456
      _best_length = 0;
439 457
      _best_size = 1;
440 458
      _cycle_path->clear();
441 459
      for (NodeIt u(_gr); u != INVALID; ++u)
442 460
        _data[u].clear();
443 461
    }
444 462

	
445 463
    // Find strongly connected components and initialize _comp_nodes
446 464
    // and _out_arcs
447 465
    void findComponents() {
448 466
      _comp_num = stronglyConnectedComponents(_gr, _comp);
449 467
      _comp_nodes.resize(_comp_num);
450 468
      if (_comp_num == 1) {
451 469
        _comp_nodes[0].clear();
452 470
        for (NodeIt n(_gr); n != INVALID; ++n) {
453 471
          _comp_nodes[0].push_back(n);
454 472
          _out_arcs[n].clear();
455 473
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
456 474
            _out_arcs[n].push_back(a);
457 475
          }
458 476
        }
459 477
      } else {
460 478
        for (int i = 0; i < _comp_num; ++i)
461 479
          _comp_nodes[i].clear();
462 480
        for (NodeIt n(_gr); n != INVALID; ++n) {
463 481
          int k = _comp[n];
464 482
          _comp_nodes[k].push_back(n);
465 483
          _out_arcs[n].clear();
466 484
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
467 485
            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
468 486
          }
469 487
        }
470 488
      }
471 489
    }
472 490

	
473 491
    // Initialize path data for the current component
474 492
    bool initComponent(int comp) {
475 493
      _nodes = &(_comp_nodes[comp]);
476 494
      int n = _nodes->size();
477 495
      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
478 496
        return false;
479 497
      }      
480 498
      for (int i = 0; i < n; ++i) {
481 499
        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
482 500
      }
483 501
      return true;
484 502
    }
485 503

	
486 504
    // Process all rounds of computing path data for the current component.
487 505
    // _data[v][k] is the length of a shortest directed walk from the root
488 506
    // node to node v containing exactly k arcs.
489 507
    void processRounds() {
490 508
      Node start = (*_nodes)[0];
491 509
      _data[start][0] = PathData(0);
492 510
      _process.clear();
493 511
      _process.push_back(start);
494 512

	
495 513
      int k, n = _nodes->size();
496 514
      int next_check = 4;
497 515
      bool terminate = false;
498 516
      for (k = 1; k <= n && int(_process.size()) < n && !terminate; ++k) {
499 517
        processNextBuildRound(k);
500 518
        if (k == next_check || k == n) {
501 519
          terminate = checkTermination(k);
502 520
          next_check = next_check * 3 / 2;
503 521
        }
504 522
      }
505 523
      for ( ; k <= n && !terminate; ++k) {
506 524
        processNextFullRound(k);
507 525
        if (k == next_check || k == n) {
508 526
          terminate = checkTermination(k);
509 527
          next_check = next_check * 3 / 2;
510 528
        }
511 529
      }
512 530
    }
513 531

	
514 532
    // Process one round and rebuild _process
515 533
    void processNextBuildRound(int k) {
516 534
      std::vector<Node> next;
517 535
      Node u, v;
518 536
      Arc e;
519 537
      LargeValue d;
520 538
      for (int i = 0; i < int(_process.size()); ++i) {
521 539
        u = _process[i];
522 540
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
523 541
          e = _out_arcs[u][j];
524 542
          v = _gr.target(e);
525 543
          d = _data[u][k-1].dist + _length[e];
526 544
          if (_tolerance.less(d, _data[v][k].dist)) {
527 545
            if (_data[v][k].dist == INF) next.push_back(v);
528 546
            _data[v][k] = PathData(d, e);
529 547
          }
530 548
        }
531 549
      }
532 550
      _process.swap(next);
533 551
    }
534 552

	
535 553
    // Process one round using _nodes instead of _process
536 554
    void processNextFullRound(int k) {
537 555
      Node u, v;
538 556
      Arc e;
539 557
      LargeValue d;
540 558
      for (int i = 0; i < int(_nodes->size()); ++i) {
541 559
        u = (*_nodes)[i];
542 560
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
543 561
          e = _out_arcs[u][j];
544 562
          v = _gr.target(e);
545 563
          d = _data[u][k-1].dist + _length[e];
546 564
          if (_tolerance.less(d, _data[v][k].dist)) {
547 565
            _data[v][k] = PathData(d, e);
548 566
          }
549 567
        }
550 568
      }
551 569
    }
552 570
    
553 571
    // Check early termination
554 572
    bool checkTermination(int k) {
555 573
      typedef std::pair<int, int> Pair;
556 574
      typename GR::template NodeMap<Pair> level(_gr, Pair(-1, 0));
557 575
      typename GR::template NodeMap<LargeValue> pi(_gr);
558 576
      int n = _nodes->size();
559 577
      LargeValue length;
560 578
      int size;
561 579
      Node u;
562 580
      
563 581
      // Search for cycles that are already found
564 582
      _curr_found = false;
565 583
      for (int i = 0; i < n; ++i) {
566 584
        u = (*_nodes)[i];
567 585
        if (_data[u][k].dist == INF) continue;
568 586
        for (int j = k; j >= 0; --j) {
569 587
          if (level[u].first == i && level[u].second > 0) {
570 588
            // A cycle is found
571 589
            length = _data[u][level[u].second].dist - _data[u][j].dist;
572 590
            size = level[u].second - j;
573 591
            if (!_curr_found || length * _curr_size < _curr_length * size) {
574 592
              _curr_length = length;
575 593
              _curr_size = size;
576 594
              _curr_node = u;
577 595
              _curr_level = level[u].second;
578 596
              _curr_found = true;
579 597
            }
580 598
          }
581 599
          level[u] = Pair(i, j);
582 600
          u = _gr.source(_data[u][j].pred);
583 601
        }
584 602
      }
585 603

	
586 604
      // If at least one cycle is found, check the optimality condition
587 605
      LargeValue d;
588 606
      if (_curr_found && k < n) {
589 607
        // Find node potentials
590 608
        for (int i = 0; i < n; ++i) {
591 609
          u = (*_nodes)[i];
592 610
          pi[u] = INF;
593 611
          for (int j = 0; j <= k; ++j) {
594 612
            if (_data[u][j].dist < INF) {
595 613
              d = _data[u][j].dist * _curr_size - j * _curr_length;
596 614
              if (_tolerance.less(d, pi[u])) pi[u] = d;
597 615
            }
598 616
          }
599 617
        }
600 618

	
601 619
        // Check the optimality condition for all arcs
602 620
        bool done = true;
603 621
        for (ArcIt a(_gr); a != INVALID; ++a) {
604 622
          if (_tolerance.less(_length[a] * _curr_size - _curr_length,
605 623
                              pi[_gr.target(a)] - pi[_gr.source(a)]) ) {
606 624
            done = false;
607 625
            break;
608 626
          }
609 627
        }
610 628
        return done;
611 629
      }
612 630
      return (k == n);
613 631
    }
614 632

	
615 633
  }; //class HartmannOrlin
616 634

	
617 635
  ///@}
618 636

	
619 637
} //namespace lemon
620 638

	
621 639
#endif //LEMON_HARTMANN_ORLIN_H
Ignore white space 6 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_HOWARD_H
20 20
#define LEMON_HOWARD_H
21 21

	
22 22
/// \ingroup min_mean_cycle
23 23
///
24 24
/// \file
25 25
/// \brief Howard's algorithm for finding a minimum mean cycle.
26 26

	
27 27
#include <vector>
28 28
#include <limits>
29 29
#include <lemon/core.h>
30 30
#include <lemon/path.h>
31 31
#include <lemon/tolerance.h>
32 32
#include <lemon/connectivity.h>
33 33

	
34 34
namespace lemon {
35 35

	
36 36
  /// \brief Default traits class of Howard class.
37 37
  ///
38 38
  /// Default traits class of Howard class.
39 39
  /// \tparam GR The type of the digraph.
40 40
  /// \tparam LEN The type of the length map.
41 41
  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
42 42
#ifdef DOXYGEN
43 43
  template <typename GR, typename LEN>
44 44
#else
45 45
  template <typename GR, typename LEN,
46 46
    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
47 47
#endif
48 48
  struct HowardDefaultTraits
49 49
  {
50 50
    /// The type of the digraph
51 51
    typedef GR Digraph;
52 52
    /// The type of the length map
53 53
    typedef LEN LengthMap;
54 54
    /// The type of the arc lengths
55 55
    typedef typename LengthMap::Value Value;
56 56

	
57 57
    /// \brief The large value type used for internal computations
58 58
    ///
59 59
    /// The large value type used for internal computations.
60 60
    /// It is \c long \c long if the \c Value type is integer,
61 61
    /// otherwise it is \c double.
62 62
    /// \c Value must be convertible to \c LargeValue.
63 63
    typedef double LargeValue;
64 64

	
65 65
    /// The tolerance type used for internal computations
66 66
    typedef lemon::Tolerance<LargeValue> Tolerance;
67 67

	
68 68
    /// \brief The path type of the found cycles
69 69
    ///
70 70
    /// The path type of the found cycles.
71 71
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
72 72
    /// and it must have an \c addBack() function.
73 73
    typedef lemon::Path<Digraph> Path;
74 74
  };
75 75

	
76 76
  // Default traits class for integer value types
77 77
  template <typename GR, typename LEN>
78 78
  struct HowardDefaultTraits<GR, LEN, true>
79 79
  {
80 80
    typedef GR Digraph;
81 81
    typedef LEN LengthMap;
82 82
    typedef typename LengthMap::Value Value;
83 83
#ifdef LEMON_HAVE_LONG_LONG
84 84
    typedef long long LargeValue;
85 85
#else
86 86
    typedef long LargeValue;
87 87
#endif
88 88
    typedef lemon::Tolerance<LargeValue> Tolerance;
89 89
    typedef lemon::Path<Digraph> Path;
90 90
  };
91 91

	
92 92

	
93 93
  /// \addtogroup min_mean_cycle
94 94
  /// @{
95 95

	
96 96
  /// \brief Implementation of Howard's algorithm for finding a minimum
97 97
  /// mean cycle.
98 98
  ///
99 99
  /// This class implements Howard's policy iteration algorithm for finding
100 100
  /// a directed cycle of minimum mean length (cost) in a digraph.
101 101
  /// This class provides the most efficient algorithm for the
102 102
  /// minimum mean cycle problem, though the best known theoretical
103 103
  /// bound on its running time is exponential.
104 104
  ///
105 105
  /// \tparam GR The type of the digraph the algorithm runs on.
106 106
  /// \tparam LEN The type of the length map. The default
107 107
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
108 108
#ifdef DOXYGEN
109 109
  template <typename GR, typename LEN, typename TR>
110 110
#else
111 111
  template < typename GR,
112 112
             typename LEN = typename GR::template ArcMap<int>,
113 113
             typename TR = HowardDefaultTraits<GR, LEN> >
114 114
#endif
115 115
  class Howard
116 116
  {
117 117
  public:
118 118
  
119 119
    /// The type of the digraph
120 120
    typedef typename TR::Digraph Digraph;
121 121
    /// The type of the length map
122 122
    typedef typename TR::LengthMap LengthMap;
123 123
    /// The type of the arc lengths
124 124
    typedef typename TR::Value Value;
125 125

	
126 126
    /// \brief The large value type
127 127
    ///
128 128
    /// The large value type used for internal computations.
129 129
    /// Using the \ref HowardDefaultTraits "default traits class",
130 130
    /// it is \c long \c long if the \c Value type is integer,
131 131
    /// otherwise it is \c double.
132 132
    typedef typename TR::LargeValue LargeValue;
133 133

	
134 134
    /// The tolerance type
135 135
    typedef typename TR::Tolerance Tolerance;
136 136

	
137 137
    /// \brief The path type of the found cycles
138 138
    ///
139 139
    /// The path type of the found cycles.
140 140
    /// Using the \ref HowardDefaultTraits "default traits class",
141 141
    /// it is \ref lemon::Path "Path<Digraph>".
142 142
    typedef typename TR::Path Path;
143 143

	
144 144
    /// The \ref HowardDefaultTraits "traits class" of the algorithm
145 145
    typedef TR Traits;
146 146

	
147 147
  private:
148 148

	
149 149
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
150 150
  
151 151
    // The digraph the algorithm runs on
152 152
    const Digraph &_gr;
153 153
    // The length of the arcs
154 154
    const LengthMap &_length;
155 155

	
156 156
    // Data for the found cycles
157 157
    bool _curr_found, _best_found;
158 158
    LargeValue _curr_length, _best_length;
159 159
    int _curr_size, _best_size;
160 160
    Node _curr_node, _best_node;
161 161

	
162 162
    Path *_cycle_path;
163 163
    bool _local_path;
164 164

	
165 165
    // Internal data used by the algorithm
166 166
    typename Digraph::template NodeMap<Arc> _policy;
167 167
    typename Digraph::template NodeMap<bool> _reached;
168 168
    typename Digraph::template NodeMap<int> _level;
169 169
    typename Digraph::template NodeMap<LargeValue> _dist;
170 170

	
171 171
    // Data for storing the strongly connected components
172 172
    int _comp_num;
173 173
    typename Digraph::template NodeMap<int> _comp;
174 174
    std::vector<std::vector<Node> > _comp_nodes;
175 175
    std::vector<Node>* _nodes;
176 176
    typename Digraph::template NodeMap<std::vector<Arc> > _in_arcs;
177 177
    
178 178
    // Queue used for BFS search
179 179
    std::vector<Node> _queue;
180 180
    int _qfront, _qback;
181 181

	
182 182
    Tolerance _tolerance;
183 183
  
184 184
    // Infinite constant
185 185
    const LargeValue INF;
186 186

	
187 187
  public:
188 188
  
189 189
    /// \name Named Template Parameters
190 190
    /// @{
191 191

	
192 192
    template <typename T>
193 193
    struct SetLargeValueTraits : public Traits {
194 194
      typedef T LargeValue;
195 195
      typedef lemon::Tolerance<T> Tolerance;
196 196
    };
197 197

	
198 198
    /// \brief \ref named-templ-param "Named parameter" for setting
199 199
    /// \c LargeValue type.
200 200
    ///
201 201
    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
202 202
    /// type. It is used for internal computations in the algorithm.
203 203
    template <typename T>
204 204
    struct SetLargeValue
205 205
      : public Howard<GR, LEN, SetLargeValueTraits<T> > {
206 206
      typedef Howard<GR, LEN, SetLargeValueTraits<T> > Create;
207 207
    };
208 208

	
209 209
    template <typename T>
210 210
    struct SetPathTraits : public Traits {
211 211
      typedef T Path;
212 212
    };
213 213

	
214 214
    /// \brief \ref named-templ-param "Named parameter" for setting
215 215
    /// \c %Path type.
216 216
    ///
217 217
    /// \ref named-templ-param "Named parameter" for setting the \c %Path
218 218
    /// type of the found cycles.
219 219
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
220 220
    /// and it must have an \c addBack() function.
221 221
    template <typename T>
222 222
    struct SetPath
223 223
      : public Howard<GR, LEN, SetPathTraits<T> > {
224 224
      typedef Howard<GR, LEN, SetPathTraits<T> > Create;
225 225
    };
226 226
    
227 227
    /// @}
228 228

	
229 229
  public:
230 230

	
231 231
    /// \brief Constructor.
232 232
    ///
233 233
    /// The constructor of the class.
234 234
    ///
235 235
    /// \param digraph The digraph the algorithm runs on.
236 236
    /// \param length The lengths (costs) of the arcs.
237 237
    Howard( const Digraph &digraph,
238 238
            const LengthMap &length ) :
239 239
      _gr(digraph), _length(length), _best_found(false),
240 240
      _best_length(0), _best_size(1), _cycle_path(NULL), _local_path(false),
241 241
      _policy(digraph), _reached(digraph), _level(digraph), _dist(digraph),
242 242
      _comp(digraph), _in_arcs(digraph),
243 243
      INF(std::numeric_limits<LargeValue>::has_infinity ?
244 244
          std::numeric_limits<LargeValue>::infinity() :
245 245
          std::numeric_limits<LargeValue>::max())
246 246
    {}
247 247

	
248 248
    /// Destructor.
249 249
    ~Howard() {
250 250
      if (_local_path) delete _cycle_path;
251 251
    }
252 252

	
253 253
    /// \brief Set the path structure for storing the found cycle.
254 254
    ///
255 255
    /// This function sets an external path structure for storing the
256 256
    /// found cycle.
257 257
    ///
258 258
    /// If you don't call this function before calling \ref run() or
259 259
    /// \ref findMinMean(), it will allocate a local \ref Path "path"
260 260
    /// structure. The destuctor deallocates this automatically
261 261
    /// allocated object, of course.
262 262
    ///
263 263
    /// \note The algorithm calls only the \ref lemon::Path::addBack()
264 264
    /// "addBack()" function of the given path structure.
265 265
    ///
266 266
    /// \return <tt>(*this)</tt>
267 267
    Howard& cycle(Path &path) {
268 268
      if (_local_path) {
269 269
        delete _cycle_path;
270 270
        _local_path = false;
271 271
      }
272 272
      _cycle_path = &path;
273 273
      return *this;
274 274
    }
275 275

	
276
    /// \brief Set the tolerance used by the algorithm.
277
    ///
278
    /// This function sets the tolerance object used by the algorithm.
279
    ///
280
    /// \return <tt>(*this)</tt>
281
    Howard& tolerance(const Tolerance& tolerance) {
282
      _tolerance = tolerance;
283
      return *this;
284
    }
285

	
286
    /// \brief Return a const reference to the tolerance.
287
    ///
288
    /// This function returns a const reference to the tolerance object
289
    /// used by the algorithm.
290
    const Tolerance& tolerance() const {
291
      return _tolerance;
292
    }
293

	
276 294
    /// \name Execution control
277 295
    /// The simplest way to execute the algorithm is to call the \ref run()
278 296
    /// function.\n
279 297
    /// If you only need the minimum mean length, you may call
280 298
    /// \ref findMinMean().
281 299

	
282 300
    /// @{
283 301

	
284 302
    /// \brief Run the algorithm.
285 303
    ///
286 304
    /// This function runs the algorithm.
287 305
    /// It can be called more than once (e.g. if the underlying digraph
288 306
    /// and/or the arc lengths have been modified).
289 307
    ///
290 308
    /// \return \c true if a directed cycle exists in the digraph.
291 309
    ///
292 310
    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
293 311
    /// \code
294 312
    ///   return mmc.findMinMean() && mmc.findCycle();
295 313
    /// \endcode
296 314
    bool run() {
297 315
      return findMinMean() && findCycle();
298 316
    }
299 317

	
300 318
    /// \brief Find the minimum cycle mean.
301 319
    ///
302 320
    /// This function finds the minimum mean length of the directed
303 321
    /// cycles in the digraph.
304 322
    ///
305 323
    /// \return \c true if a directed cycle exists in the digraph.
306 324
    bool findMinMean() {
307 325
      // Initialize and find strongly connected components
308 326
      init();
309 327
      findComponents();
310 328
      
311 329
      // Find the minimum cycle mean in the components
312 330
      for (int comp = 0; comp < _comp_num; ++comp) {
313 331
        // Find the minimum mean cycle in the current component
314 332
        if (!buildPolicyGraph(comp)) continue;
315 333
        while (true) {
316 334
          findPolicyCycle();
317 335
          if (!computeNodeDistances()) break;
318 336
        }
319 337
        // Update the best cycle (global minimum mean cycle)
320 338
        if ( _curr_found && (!_best_found ||
321 339
             _curr_length * _best_size < _best_length * _curr_size) ) {
322 340
          _best_found = true;
323 341
          _best_length = _curr_length;
324 342
          _best_size = _curr_size;
325 343
          _best_node = _curr_node;
326 344
        }
327 345
      }
328 346
      return _best_found;
329 347
    }
330 348

	
331 349
    /// \brief Find a minimum mean directed cycle.
332 350
    ///
333 351
    /// This function finds a directed cycle of minimum mean length
334 352
    /// in the digraph using the data computed by findMinMean().
335 353
    ///
336 354
    /// \return \c true if a directed cycle exists in the digraph.
337 355
    ///
338 356
    /// \pre \ref findMinMean() must be called before using this function.
339 357
    bool findCycle() {
340 358
      if (!_best_found) return false;
341 359
      _cycle_path->addBack(_policy[_best_node]);
342 360
      for ( Node v = _best_node;
343 361
            (v = _gr.target(_policy[v])) != _best_node; ) {
344 362
        _cycle_path->addBack(_policy[v]);
345 363
      }
346 364
      return true;
347 365
    }
348 366

	
349 367
    /// @}
350 368

	
351 369
    /// \name Query Functions
352 370
    /// The results of the algorithm can be obtained using these
353 371
    /// functions.\n
354 372
    /// The algorithm should be executed before using them.
355 373

	
356 374
    /// @{
357 375

	
358 376
    /// \brief Return the total length of the found cycle.
359 377
    ///
360 378
    /// This function returns the total length of the found cycle.
361 379
    ///
362 380
    /// \pre \ref run() or \ref findMinMean() must be called before
363 381
    /// using this function.
364 382
    LargeValue cycleLength() const {
365 383
      return _best_length;
366 384
    }
367 385

	
368 386
    /// \brief Return the number of arcs on the found cycle.
369 387
    ///
370 388
    /// This function returns the number of arcs on the found cycle.
371 389
    ///
372 390
    /// \pre \ref run() or \ref findMinMean() must be called before
373 391
    /// using this function.
374 392
    int cycleArcNum() const {
375 393
      return _best_size;
376 394
    }
377 395

	
378 396
    /// \brief Return the mean length of the found cycle.
379 397
    ///
380 398
    /// This function returns the mean length of the found cycle.
381 399
    ///
382 400
    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
383 401
    /// following code.
384 402
    /// \code
385 403
    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
386 404
    /// \endcode
387 405
    ///
388 406
    /// \pre \ref run() or \ref findMinMean() must be called before
389 407
    /// using this function.
390 408
    double cycleMean() const {
391 409
      return static_cast<double>(_best_length) / _best_size;
392 410
    }
393 411

	
394 412
    /// \brief Return the found cycle.
395 413
    ///
396 414
    /// This function returns a const reference to the path structure
397 415
    /// storing the found cycle.
398 416
    ///
399 417
    /// \pre \ref run() or \ref findCycle() must be called before using
400 418
    /// this function.
401 419
    const Path& cycle() const {
402 420
      return *_cycle_path;
403 421
    }
404 422

	
405 423
    ///@}
406 424

	
407 425
  private:
408 426

	
409 427
    // Initialize
410 428
    void init() {
411 429
      if (!_cycle_path) {
412 430
        _local_path = true;
413 431
        _cycle_path = new Path;
414 432
      }
415 433
      _queue.resize(countNodes(_gr));
416 434
      _best_found = false;
417 435
      _best_length = 0;
418 436
      _best_size = 1;
419 437
      _cycle_path->clear();
420 438
    }
421 439
    
422 440
    // Find strongly connected components and initialize _comp_nodes
423 441
    // and _in_arcs
424 442
    void findComponents() {
425 443
      _comp_num = stronglyConnectedComponents(_gr, _comp);
426 444
      _comp_nodes.resize(_comp_num);
427 445
      if (_comp_num == 1) {
428 446
        _comp_nodes[0].clear();
429 447
        for (NodeIt n(_gr); n != INVALID; ++n) {
430 448
          _comp_nodes[0].push_back(n);
431 449
          _in_arcs[n].clear();
432 450
          for (InArcIt a(_gr, n); a != INVALID; ++a) {
433 451
            _in_arcs[n].push_back(a);
434 452
          }
435 453
        }
436 454
      } else {
437 455
        for (int i = 0; i < _comp_num; ++i)
438 456
          _comp_nodes[i].clear();
439 457
        for (NodeIt n(_gr); n != INVALID; ++n) {
440 458
          int k = _comp[n];
441 459
          _comp_nodes[k].push_back(n);
442 460
          _in_arcs[n].clear();
443 461
          for (InArcIt a(_gr, n); a != INVALID; ++a) {
444 462
            if (_comp[_gr.source(a)] == k) _in_arcs[n].push_back(a);
445 463
          }
446 464
        }
447 465
      }
448 466
    }
449 467

	
450 468
    // Build the policy graph in the given strongly connected component
451 469
    // (the out-degree of every node is 1)
452 470
    bool buildPolicyGraph(int comp) {
453 471
      _nodes = &(_comp_nodes[comp]);
454 472
      if (_nodes->size() < 1 ||
455 473
          (_nodes->size() == 1 && _in_arcs[(*_nodes)[0]].size() == 0)) {
456 474
        return false;
457 475
      }
458 476
      for (int i = 0; i < int(_nodes->size()); ++i) {
459 477
        _dist[(*_nodes)[i]] = INF;
460 478
      }
461 479
      Node u, v;
462 480
      Arc e;
463 481
      for (int i = 0; i < int(_nodes->size()); ++i) {
464 482
        v = (*_nodes)[i];
465 483
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
466 484
          e = _in_arcs[v][j];
467 485
          u = _gr.source(e);
468 486
          if (_length[e] < _dist[u]) {
469 487
            _dist[u] = _length[e];
470 488
            _policy[u] = e;
471 489
          }
472 490
        }
473 491
      }
474 492
      return true;
475 493
    }
476 494

	
477 495
    // Find the minimum mean cycle in the policy graph
478 496
    void findPolicyCycle() {
479 497
      for (int i = 0; i < int(_nodes->size()); ++i) {
480 498
        _level[(*_nodes)[i]] = -1;
481 499
      }
482 500
      LargeValue clength;
483 501
      int csize;
484 502
      Node u, v;
485 503
      _curr_found = false;
486 504
      for (int i = 0; i < int(_nodes->size()); ++i) {
487 505
        u = (*_nodes)[i];
488 506
        if (_level[u] >= 0) continue;
489 507
        for (; _level[u] < 0; u = _gr.target(_policy[u])) {
490 508
          _level[u] = i;
491 509
        }
492 510
        if (_level[u] == i) {
493 511
          // A cycle is found
494 512
          clength = _length[_policy[u]];
495 513
          csize = 1;
496 514
          for (v = u; (v = _gr.target(_policy[v])) != u; ) {
497 515
            clength += _length[_policy[v]];
498 516
            ++csize;
499 517
          }
500 518
          if ( !_curr_found ||
501 519
               (clength * _curr_size < _curr_length * csize) ) {
502 520
            _curr_found = true;
503 521
            _curr_length = clength;
504 522
            _curr_size = csize;
505 523
            _curr_node = u;
506 524
          }
507 525
        }
508 526
      }
509 527
    }
510 528

	
511 529
    // Contract the policy graph and compute node distances
512 530
    bool computeNodeDistances() {
513 531
      // Find the component of the main cycle and compute node distances
514 532
      // using reverse BFS
515 533
      for (int i = 0; i < int(_nodes->size()); ++i) {
516 534
        _reached[(*_nodes)[i]] = false;
517 535
      }
518 536
      _qfront = _qback = 0;
519 537
      _queue[0] = _curr_node;
520 538
      _reached[_curr_node] = true;
521 539
      _dist[_curr_node] = 0;
522 540
      Node u, v;
523 541
      Arc e;
524 542
      while (_qfront <= _qback) {
525 543
        v = _queue[_qfront++];
526 544
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
527 545
          e = _in_arcs[v][j];
528 546
          u = _gr.source(e);
529 547
          if (_policy[u] == e && !_reached[u]) {
530 548
            _reached[u] = true;
531 549
            _dist[u] = _dist[v] + _length[e] * _curr_size - _curr_length;
532 550
            _queue[++_qback] = u;
533 551
          }
534 552
        }
535 553
      }
536 554

	
537 555
      // Connect all other nodes to this component and compute node
538 556
      // distances using reverse BFS
539 557
      _qfront = 0;
540 558
      while (_qback < int(_nodes->size())-1) {
541 559
        v = _queue[_qfront++];
542 560
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
543 561
          e = _in_arcs[v][j];
544 562
          u = _gr.source(e);
545 563
          if (!_reached[u]) {
546 564
            _reached[u] = true;
547 565
            _policy[u] = e;
548 566
            _dist[u] = _dist[v] + _length[e] * _curr_size - _curr_length;
549 567
            _queue[++_qback] = u;
550 568
          }
551 569
        }
552 570
      }
553 571

	
554 572
      // Improve node distances
555 573
      bool improved = false;
556 574
      for (int i = 0; i < int(_nodes->size()); ++i) {
557 575
        v = (*_nodes)[i];
558 576
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
559 577
          e = _in_arcs[v][j];
560 578
          u = _gr.source(e);
561 579
          LargeValue delta = _dist[v] + _length[e] * _curr_size - _curr_length;
562 580
          if (_tolerance.less(delta, _dist[u])) {
563 581
            _dist[u] = delta;
564 582
            _policy[u] = e;
565 583
            improved = true;
566 584
          }
567 585
        }
568 586
      }
569 587
      return improved;
570 588
    }
571 589

	
572 590
  }; //class Howard
573 591

	
574 592
  ///@}
575 593

	
576 594
} //namespace lemon
577 595

	
578 596
#endif //LEMON_HOWARD_H
Ignore white space 6 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_KARP_H
20 20
#define LEMON_KARP_H
21 21

	
22 22
/// \ingroup min_mean_cycle
23 23
///
24 24
/// \file
25 25
/// \brief Karp's algorithm for finding a minimum mean cycle.
26 26

	
27 27
#include <vector>
28 28
#include <limits>
29 29
#include <lemon/core.h>
30 30
#include <lemon/path.h>
31 31
#include <lemon/tolerance.h>
32 32
#include <lemon/connectivity.h>
33 33

	
34 34
namespace lemon {
35 35

	
36 36
  /// \brief Default traits class of Karp algorithm.
37 37
  ///
38 38
  /// Default traits class of Karp algorithm.
39 39
  /// \tparam GR The type of the digraph.
40 40
  /// \tparam LEN The type of the length map.
41 41
  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
42 42
#ifdef DOXYGEN
43 43
  template <typename GR, typename LEN>
44 44
#else
45 45
  template <typename GR, typename LEN,
46 46
    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
47 47
#endif
48 48
  struct KarpDefaultTraits
49 49
  {
50 50
    /// The type of the digraph
51 51
    typedef GR Digraph;
52 52
    /// The type of the length map
53 53
    typedef LEN LengthMap;
54 54
    /// The type of the arc lengths
55 55
    typedef typename LengthMap::Value Value;
56 56

	
57 57
    /// \brief The large value type used for internal computations
58 58
    ///
59 59
    /// The large value type used for internal computations.
60 60
    /// It is \c long \c long if the \c Value type is integer,
61 61
    /// otherwise it is \c double.
62 62
    /// \c Value must be convertible to \c LargeValue.
63 63
    typedef double LargeValue;
64 64

	
65 65
    /// The tolerance type used for internal computations
66 66
    typedef lemon::Tolerance<LargeValue> Tolerance;
67 67

	
68 68
    /// \brief The path type of the found cycles
69 69
    ///
70 70
    /// The path type of the found cycles.
71 71
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
72 72
    /// and it must have an \c addBack() function.
73 73
    typedef lemon::Path<Digraph> Path;
74 74
  };
75 75

	
76 76
  // Default traits class for integer value types
77 77
  template <typename GR, typename LEN>
78 78
  struct KarpDefaultTraits<GR, LEN, true>
79 79
  {
80 80
    typedef GR Digraph;
81 81
    typedef LEN LengthMap;
82 82
    typedef typename LengthMap::Value Value;
83 83
#ifdef LEMON_HAVE_LONG_LONG
84 84
    typedef long long LargeValue;
85 85
#else
86 86
    typedef long LargeValue;
87 87
#endif
88 88
    typedef lemon::Tolerance<LargeValue> Tolerance;
89 89
    typedef lemon::Path<Digraph> Path;
90 90
  };
91 91

	
92 92

	
93 93
  /// \addtogroup min_mean_cycle
94 94
  /// @{
95 95

	
96 96
  /// \brief Implementation of Karp's algorithm for finding a minimum
97 97
  /// mean cycle.
98 98
  ///
99 99
  /// This class implements Karp's algorithm for finding a directed
100 100
  /// cycle of minimum mean length (cost) in a digraph.
101 101
  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
102 102
  ///
103 103
  /// \tparam GR The type of the digraph the algorithm runs on.
104 104
  /// \tparam LEN The type of the length map. The default
105 105
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
106 106
#ifdef DOXYGEN
107 107
  template <typename GR, typename LEN, typename TR>
108 108
#else
109 109
  template < typename GR,
110 110
             typename LEN = typename GR::template ArcMap<int>,
111 111
             typename TR = KarpDefaultTraits<GR, LEN> >
112 112
#endif
113 113
  class Karp
114 114
  {
115 115
  public:
116 116

	
117 117
    /// The type of the digraph
118 118
    typedef typename TR::Digraph Digraph;
119 119
    /// The type of the length map
120 120
    typedef typename TR::LengthMap LengthMap;
121 121
    /// The type of the arc lengths
122 122
    typedef typename TR::Value Value;
123 123

	
124 124
    /// \brief The large value type
125 125
    ///
126 126
    /// The large value type used for internal computations.
127 127
    /// Using the \ref KarpDefaultTraits "default traits class",
128 128
    /// it is \c long \c long if the \c Value type is integer,
129 129
    /// otherwise it is \c double.
130 130
    typedef typename TR::LargeValue LargeValue;
131 131

	
132 132
    /// The tolerance type
133 133
    typedef typename TR::Tolerance Tolerance;
134 134

	
135 135
    /// \brief The path type of the found cycles
136 136
    ///
137 137
    /// The path type of the found cycles.
138 138
    /// Using the \ref KarpDefaultTraits "default traits class",
139 139
    /// it is \ref lemon::Path "Path<Digraph>".
140 140
    typedef typename TR::Path Path;
141 141

	
142 142
    /// The \ref KarpDefaultTraits "traits class" of the algorithm
143 143
    typedef TR Traits;
144 144

	
145 145
  private:
146 146

	
147 147
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
148 148

	
149 149
    // Data sturcture for path data
150 150
    struct PathData
151 151
    {
152 152
      LargeValue dist;
153 153
      Arc pred;
154 154
      PathData(LargeValue d, Arc p = INVALID) :
155 155
        dist(d), pred(p) {}
156 156
    };
157 157

	
158 158
    typedef typename Digraph::template NodeMap<std::vector<PathData> >
159 159
      PathDataNodeMap;
160 160

	
161 161
  private:
162 162

	
163 163
    // The digraph the algorithm runs on
164 164
    const Digraph &_gr;
165 165
    // The length of the arcs
166 166
    const LengthMap &_length;
167 167

	
168 168
    // Data for storing the strongly connected components
169 169
    int _comp_num;
170 170
    typename Digraph::template NodeMap<int> _comp;
171 171
    std::vector<std::vector<Node> > _comp_nodes;
172 172
    std::vector<Node>* _nodes;
173 173
    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
174 174

	
175 175
    // Data for the found cycle
176 176
    LargeValue _cycle_length;
177 177
    int _cycle_size;
178 178
    Node _cycle_node;
179 179

	
180 180
    Path *_cycle_path;
181 181
    bool _local_path;
182 182

	
183 183
    // Node map for storing path data
184 184
    PathDataNodeMap _data;
185 185
    // The processed nodes in the last round
186 186
    std::vector<Node> _process;
187 187

	
188 188
    Tolerance _tolerance;
189 189
    
190 190
    // Infinite constant
191 191
    const LargeValue INF;
192 192

	
193 193
  public:
194 194

	
195 195
    /// \name Named Template Parameters
196 196
    /// @{
197 197

	
198 198
    template <typename T>
199 199
    struct SetLargeValueTraits : public Traits {
200 200
      typedef T LargeValue;
201 201
      typedef lemon::Tolerance<T> Tolerance;
202 202
    };
203 203

	
204 204
    /// \brief \ref named-templ-param "Named parameter" for setting
205 205
    /// \c LargeValue type.
206 206
    ///
207 207
    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
208 208
    /// type. It is used for internal computations in the algorithm.
209 209
    template <typename T>
210 210
    struct SetLargeValue
211 211
      : public Karp<GR, LEN, SetLargeValueTraits<T> > {
212 212
      typedef Karp<GR, LEN, SetLargeValueTraits<T> > Create;
213 213
    };
214 214

	
215 215
    template <typename T>
216 216
    struct SetPathTraits : public Traits {
217 217
      typedef T Path;
218 218
    };
219 219

	
220 220
    /// \brief \ref named-templ-param "Named parameter" for setting
221 221
    /// \c %Path type.
222 222
    ///
223 223
    /// \ref named-templ-param "Named parameter" for setting the \c %Path
224 224
    /// type of the found cycles.
225 225
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
226 226
    /// and it must have an \c addFront() function.
227 227
    template <typename T>
228 228
    struct SetPath
229 229
      : public Karp<GR, LEN, SetPathTraits<T> > {
230 230
      typedef Karp<GR, LEN, SetPathTraits<T> > Create;
231 231
    };
232 232

	
233 233
    /// @}
234 234

	
235 235
  public:
236 236

	
237 237
    /// \brief Constructor.
238 238
    ///
239 239
    /// The constructor of the class.
240 240
    ///
241 241
    /// \param digraph The digraph the algorithm runs on.
242 242
    /// \param length The lengths (costs) of the arcs.
243 243
    Karp( const Digraph &digraph,
244 244
          const LengthMap &length ) :
245 245
      _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
246 246
      _cycle_length(0), _cycle_size(1), _cycle_node(INVALID),
247 247
      _cycle_path(NULL), _local_path(false), _data(digraph),
248 248
      INF(std::numeric_limits<LargeValue>::has_infinity ?
249 249
          std::numeric_limits<LargeValue>::infinity() :
250 250
          std::numeric_limits<LargeValue>::max())
251 251
    {}
252 252

	
253 253
    /// Destructor.
254 254
    ~Karp() {
255 255
      if (_local_path) delete _cycle_path;
256 256
    }
257 257

	
258 258
    /// \brief Set the path structure for storing the found cycle.
259 259
    ///
260 260
    /// This function sets an external path structure for storing the
261 261
    /// found cycle.
262 262
    ///
263 263
    /// If you don't call this function before calling \ref run() or
264 264
    /// \ref findMinMean(), it will allocate a local \ref Path "path"
265 265
    /// structure. The destuctor deallocates this automatically
266 266
    /// allocated object, of course.
267 267
    ///
268 268
    /// \note The algorithm calls only the \ref lemon::Path::addFront()
269 269
    /// "addFront()" function of the given path structure.
270 270
    ///
271 271
    /// \return <tt>(*this)</tt>
272 272
    Karp& cycle(Path &path) {
273 273
      if (_local_path) {
274 274
        delete _cycle_path;
275 275
        _local_path = false;
276 276
      }
277 277
      _cycle_path = &path;
278 278
      return *this;
279 279
    }
280 280

	
281
    /// \brief Set the tolerance used by the algorithm.
282
    ///
283
    /// This function sets the tolerance object used by the algorithm.
284
    ///
285
    /// \return <tt>(*this)</tt>
286
    Karp& tolerance(const Tolerance& tolerance) {
287
      _tolerance = tolerance;
288
      return *this;
289
    }
290

	
291
    /// \brief Return a const reference to the tolerance.
292
    ///
293
    /// This function returns a const reference to the tolerance object
294
    /// used by the algorithm.
295
    const Tolerance& tolerance() const {
296
      return _tolerance;
297
    }
298

	
281 299
    /// \name Execution control
282 300
    /// The simplest way to execute the algorithm is to call the \ref run()
283 301
    /// function.\n
284 302
    /// If you only need the minimum mean length, you may call
285 303
    /// \ref findMinMean().
286 304

	
287 305
    /// @{
288 306

	
289 307
    /// \brief Run the algorithm.
290 308
    ///
291 309
    /// This function runs the algorithm.
292 310
    /// It can be called more than once (e.g. if the underlying digraph
293 311
    /// and/or the arc lengths have been modified).
294 312
    ///
295 313
    /// \return \c true if a directed cycle exists in the digraph.
296 314
    ///
297 315
    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
298 316
    /// \code
299 317
    ///   return mmc.findMinMean() && mmc.findCycle();
300 318
    /// \endcode
301 319
    bool run() {
302 320
      return findMinMean() && findCycle();
303 321
    }
304 322

	
305 323
    /// \brief Find the minimum cycle mean.
306 324
    ///
307 325
    /// This function finds the minimum mean length of the directed
308 326
    /// cycles in the digraph.
309 327
    ///
310 328
    /// \return \c true if a directed cycle exists in the digraph.
311 329
    bool findMinMean() {
312 330
      // Initialization and find strongly connected components
313 331
      init();
314 332
      findComponents();
315 333
      
316 334
      // Find the minimum cycle mean in the components
317 335
      for (int comp = 0; comp < _comp_num; ++comp) {
318 336
        if (!initComponent(comp)) continue;
319 337
        processRounds();
320 338
        updateMinMean();
321 339
      }
322 340
      return (_cycle_node != INVALID);
323 341
    }
324 342

	
325 343
    /// \brief Find a minimum mean directed cycle.
326 344
    ///
327 345
    /// This function finds a directed cycle of minimum mean length
328 346
    /// in the digraph using the data computed by findMinMean().
329 347
    ///
330 348
    /// \return \c true if a directed cycle exists in the digraph.
331 349
    ///
332 350
    /// \pre \ref findMinMean() must be called before using this function.
333 351
    bool findCycle() {
334 352
      if (_cycle_node == INVALID) return false;
335 353
      IntNodeMap reached(_gr, -1);
336 354
      int r = _data[_cycle_node].size();
337 355
      Node u = _cycle_node;
338 356
      while (reached[u] < 0) {
339 357
        reached[u] = --r;
340 358
        u = _gr.source(_data[u][r].pred);
341 359
      }
342 360
      r = reached[u];
343 361
      Arc e = _data[u][r].pred;
344 362
      _cycle_path->addFront(e);
345 363
      _cycle_length = _length[e];
346 364
      _cycle_size = 1;
347 365
      Node v;
348 366
      while ((v = _gr.source(e)) != u) {
349 367
        e = _data[v][--r].pred;
350 368
        _cycle_path->addFront(e);
351 369
        _cycle_length += _length[e];
352 370
        ++_cycle_size;
353 371
      }
354 372
      return true;
355 373
    }
356 374

	
357 375
    /// @}
358 376

	
359 377
    /// \name Query Functions
360 378
    /// The results of the algorithm can be obtained using these
361 379
    /// functions.\n
362 380
    /// The algorithm should be executed before using them.
363 381

	
364 382
    /// @{
365 383

	
366 384
    /// \brief Return the total length of the found cycle.
367 385
    ///
368 386
    /// This function returns the total length of the found cycle.
369 387
    ///
370 388
    /// \pre \ref run() or \ref findMinMean() must be called before
371 389
    /// using this function.
372 390
    LargeValue cycleLength() const {
373 391
      return _cycle_length;
374 392
    }
375 393

	
376 394
    /// \brief Return the number of arcs on the found cycle.
377 395
    ///
378 396
    /// This function returns the number of arcs on the found cycle.
379 397
    ///
380 398
    /// \pre \ref run() or \ref findMinMean() must be called before
381 399
    /// using this function.
382 400
    int cycleArcNum() const {
383 401
      return _cycle_size;
384 402
    }
385 403

	
386 404
    /// \brief Return the mean length of the found cycle.
387 405
    ///
388 406
    /// This function returns the mean length of the found cycle.
389 407
    ///
390 408
    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
391 409
    /// following code.
392 410
    /// \code
393 411
    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
394 412
    /// \endcode
395 413
    ///
396 414
    /// \pre \ref run() or \ref findMinMean() must be called before
397 415
    /// using this function.
398 416
    double cycleMean() const {
399 417
      return static_cast<double>(_cycle_length) / _cycle_size;
400 418
    }
401 419

	
402 420
    /// \brief Return the found cycle.
403 421
    ///
404 422
    /// This function returns a const reference to the path structure
405 423
    /// storing the found cycle.
406 424
    ///
407 425
    /// \pre \ref run() or \ref findCycle() must be called before using
408 426
    /// this function.
409 427
    const Path& cycle() const {
410 428
      return *_cycle_path;
411 429
    }
412 430

	
413 431
    ///@}
414 432

	
415 433
  private:
416 434

	
417 435
    // Initialization
418 436
    void init() {
419 437
      if (!_cycle_path) {
420 438
        _local_path = true;
421 439
        _cycle_path = new Path;
422 440
      }
423 441
      _cycle_path->clear();
424 442
      _cycle_length = 0;
425 443
      _cycle_size = 1;
426 444
      _cycle_node = INVALID;
427 445
      for (NodeIt u(_gr); u != INVALID; ++u)
428 446
        _data[u].clear();
429 447
    }
430 448

	
431 449
    // Find strongly connected components and initialize _comp_nodes
432 450
    // and _out_arcs
433 451
    void findComponents() {
434 452
      _comp_num = stronglyConnectedComponents(_gr, _comp);
435 453
      _comp_nodes.resize(_comp_num);
436 454
      if (_comp_num == 1) {
437 455
        _comp_nodes[0].clear();
438 456
        for (NodeIt n(_gr); n != INVALID; ++n) {
439 457
          _comp_nodes[0].push_back(n);
440 458
          _out_arcs[n].clear();
441 459
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
442 460
            _out_arcs[n].push_back(a);
443 461
          }
444 462
        }
445 463
      } else {
446 464
        for (int i = 0; i < _comp_num; ++i)
447 465
          _comp_nodes[i].clear();
448 466
        for (NodeIt n(_gr); n != INVALID; ++n) {
449 467
          int k = _comp[n];
450 468
          _comp_nodes[k].push_back(n);
451 469
          _out_arcs[n].clear();
452 470
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
453 471
            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
454 472
          }
455 473
        }
456 474
      }
457 475
    }
458 476

	
459 477
    // Initialize path data for the current component
460 478
    bool initComponent(int comp) {
461 479
      _nodes = &(_comp_nodes[comp]);
462 480
      int n = _nodes->size();
463 481
      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
464 482
        return false;
465 483
      }      
466 484
      for (int i = 0; i < n; ++i) {
467 485
        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
468 486
      }
469 487
      return true;
470 488
    }
471 489

	
472 490
    // Process all rounds of computing path data for the current component.
473 491
    // _data[v][k] is the length of a shortest directed walk from the root
474 492
    // node to node v containing exactly k arcs.
475 493
    void processRounds() {
476 494
      Node start = (*_nodes)[0];
477 495
      _data[start][0] = PathData(0);
478 496
      _process.clear();
479 497
      _process.push_back(start);
480 498

	
481 499
      int k, n = _nodes->size();
482 500
      for (k = 1; k <= n && int(_process.size()) < n; ++k) {
483 501
        processNextBuildRound(k);
484 502
      }
485 503
      for ( ; k <= n; ++k) {
486 504
        processNextFullRound(k);
487 505
      }
488 506
    }
489 507

	
490 508
    // Process one round and rebuild _process
491 509
    void processNextBuildRound(int k) {
492 510
      std::vector<Node> next;
493 511
      Node u, v;
494 512
      Arc e;
495 513
      LargeValue d;
496 514
      for (int i = 0; i < int(_process.size()); ++i) {
497 515
        u = _process[i];
498 516
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
499 517
          e = _out_arcs[u][j];
500 518
          v = _gr.target(e);
501 519
          d = _data[u][k-1].dist + _length[e];
502 520
          if (_tolerance.less(d, _data[v][k].dist)) {
503 521
            if (_data[v][k].dist == INF) next.push_back(v);
504 522
            _data[v][k] = PathData(d, e);
505 523
          }
506 524
        }
507 525
      }
508 526
      _process.swap(next);
509 527
    }
510 528

	
511 529
    // Process one round using _nodes instead of _process
512 530
    void processNextFullRound(int k) {
513 531
      Node u, v;
514 532
      Arc e;
515 533
      LargeValue d;
516 534
      for (int i = 0; i < int(_nodes->size()); ++i) {
517 535
        u = (*_nodes)[i];
518 536
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
519 537
          e = _out_arcs[u][j];
520 538
          v = _gr.target(e);
521 539
          d = _data[u][k-1].dist + _length[e];
522 540
          if (_tolerance.less(d, _data[v][k].dist)) {
523 541
            _data[v][k] = PathData(d, e);
524 542
          }
525 543
        }
526 544
      }
527 545
    }
528 546

	
529 547
    // Update the minimum cycle mean
530 548
    void updateMinMean() {
531 549
      int n = _nodes->size();
532 550
      for (int i = 0; i < n; ++i) {
533 551
        Node u = (*_nodes)[i];
534 552
        if (_data[u][n].dist == INF) continue;
535 553
        LargeValue length, max_length = 0;
536 554
        int size, max_size = 1;
537 555
        bool found_curr = false;
538 556
        for (int k = 0; k < n; ++k) {
539 557
          if (_data[u][k].dist == INF) continue;
540 558
          length = _data[u][n].dist - _data[u][k].dist;
541 559
          size = n - k;
542 560
          if (!found_curr || length * max_size > max_length * size) {
543 561
            found_curr = true;
544 562
            max_length = length;
545 563
            max_size = size;
546 564
          }
547 565
        }
548 566
        if ( found_curr && (_cycle_node == INVALID ||
549 567
             max_length * _cycle_size < _cycle_length * max_size) ) {
550 568
          _cycle_length = max_length;
551 569
          _cycle_size = max_size;
552 570
          _cycle_node = u;
553 571
        }
554 572
      }
555 573
    }
556 574

	
557 575
  }; //class Karp
558 576

	
559 577
  ///@}
560 578

	
561 579
} //namespace lemon
562 580

	
563 581
#endif //LEMON_KARP_H
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <iostream>
20 20
#include <sstream>
21 21

	
22 22
#include <lemon/smart_graph.h>
23 23
#include <lemon/lgf_reader.h>
24 24
#include <lemon/path.h>
25 25
#include <lemon/concepts/digraph.h>
26 26
#include <lemon/concept_check.h>
27 27

	
28 28
#include <lemon/karp.h>
29 29
#include <lemon/hartmann_orlin.h>
30 30
#include <lemon/howard.h>
31 31

	
32 32
#include "test_tools.h"
33 33

	
34 34
using namespace lemon;
35 35

	
36 36
char test_lgf[] =
37 37
  "@nodes\n"
38 38
  "label\n"
39 39
  "1\n"
40 40
  "2\n"
41 41
  "3\n"
42 42
  "4\n"
43 43
  "5\n"
44 44
  "6\n"
45 45
  "7\n"
46 46
  "@arcs\n"
47 47
  "    len1 len2 len3 len4  c1 c2 c3 c4\n"
48 48
  "1 2    1    1    1    1   0  0  0  0\n"
49 49
  "2 4    5    5    5    5   1  0  0  0\n"
50 50
  "2 3    8    8    8    8   0  0  0  0\n"
51 51
  "3 2   -2    0    0    0   1  0  0  0\n"
52 52
  "3 4    4    4    4    4   0  0  0  0\n"
53 53
  "3 7   -4   -4   -4   -4   0  0  0  0\n"
54 54
  "4 1    2    2    2    2   0  0  0  0\n"
55 55
  "4 3    3    3    3    3   1  0  0  0\n"
56 56
  "4 4    3    3    0    0   0  0  1  0\n"
57 57
  "5 2    4    4    4    4   0  0  0  0\n"
58 58
  "5 6    3    3    3    3   0  1  0  0\n"
59 59
  "6 5    2    2    2    2   0  1  0  0\n"
60 60
  "6 4   -1   -1   -1   -1   0  0  0  0\n"
61 61
  "6 7    1    1    1    1   0  0  0  0\n"
62 62
  "7 7    4    4    4   -1   0  0  0  1\n";
63 63

	
64 64
                        
65 65
// Check the interface of an MMC algorithm
66 66
template <typename GR, typename Value>
67 67
struct MmcClassConcept
68 68
{
69 69
  template <typename MMC>
70 70
  struct Constraints {
71 71
    void constraints() {
72 72
      const Constraints& me = *this;
73 73

	
74 74
      typedef typename MMC
75 75
        ::template SetPath<ListPath<GR> >
76 76
        ::template SetLargeValue<Value>
77 77
        ::Create MmcAlg;
78 78
      MmcAlg mmc(me.g, me.length);
79 79
      const MmcAlg& const_mmc = mmc;
80 80
      
81
      typename MmcAlg::Tolerance tol = const_mmc.tolerance();
82
      mmc.tolerance(tol);
83
      
81 84
      b = mmc.cycle(p).run();
82 85
      b = mmc.findMinMean();
83 86
      b = mmc.findCycle();
84 87

	
85 88
      v = const_mmc.cycleLength();
86 89
      i = const_mmc.cycleArcNum();
87 90
      d = const_mmc.cycleMean();
88 91
      p = const_mmc.cycle();
89 92
    }
90 93

	
91 94
    typedef concepts::ReadMap<typename GR::Arc, Value> LM;
92 95
  
93 96
    GR g;
94 97
    LM length;
95 98
    ListPath<GR> p;
96 99
    Value v;
97 100
    int i;
98 101
    double d;
99 102
    bool b;
100 103
  };
101 104
};
102 105

	
103 106
// Perform a test with the given parameters
104 107
template <typename MMC>
105 108
void checkMmcAlg(const SmartDigraph& gr,
106 109
                 const SmartDigraph::ArcMap<int>& lm,
107 110
                 const SmartDigraph::ArcMap<int>& cm,
108 111
                 int length, int size) {
109 112
  MMC alg(gr, lm);
110 113
  alg.findMinMean();
111 114
  check(alg.cycleMean() == static_cast<double>(length) / size,
112 115
        "Wrong cycle mean");
113 116
  alg.findCycle();
114 117
  check(alg.cycleLength() == length && alg.cycleArcNum() == size,
115 118
        "Wrong path");
116 119
  SmartDigraph::ArcMap<int> cycle(gr, 0);
117 120
  for (typename MMC::Path::ArcIt a(alg.cycle()); a != INVALID; ++a) {
118 121
    ++cycle[a];
119 122
  }
120 123
  for (SmartDigraph::ArcIt a(gr); a != INVALID; ++a) {
121 124
    check(cm[a] == cycle[a], "Wrong path");
122 125
  }
123 126
}
124 127

	
125 128
// Class for comparing types
126 129
template <typename T1, typename T2>
127 130
struct IsSameType {
128 131
  static const int result = 0;
129 132
};
130 133

	
131 134
template <typename T>
132 135
struct IsSameType<T,T> {
133 136
  static const int result = 1;
134 137
};
135 138

	
136 139

	
137 140
int main() {
138 141
  #ifdef LEMON_HAVE_LONG_LONG
139 142
    typedef long long long_int;
140 143
  #else
141 144
    typedef long long_int;
142 145
  #endif
143 146

	
144 147
  // Check the interface
145 148
  {
146 149
    typedef concepts::Digraph GR;
147 150

	
148 151
    // Karp
149 152
    checkConcept< MmcClassConcept<GR, int>,
150 153
                  Karp<GR, concepts::ReadMap<GR::Arc, int> > >();
151 154
    checkConcept< MmcClassConcept<GR, float>,
152 155
                  Karp<GR, concepts::ReadMap<GR::Arc, float> > >();
153 156
    
154 157
    // HartmannOrlin
155 158
    checkConcept< MmcClassConcept<GR, int>,
156 159
                  HartmannOrlin<GR, concepts::ReadMap<GR::Arc, int> > >();
157 160
    checkConcept< MmcClassConcept<GR, float>,
158 161
                  HartmannOrlin<GR, concepts::ReadMap<GR::Arc, float> > >();
159 162
    
160 163
    // Howard
161 164
    checkConcept< MmcClassConcept<GR, int>,
162 165
                  Howard<GR, concepts::ReadMap<GR::Arc, int> > >();
163 166
    checkConcept< MmcClassConcept<GR, float>,
164 167
                  Howard<GR, concepts::ReadMap<GR::Arc, float> > >();
165 168

	
166 169
    if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, int> >::LargeValue,
167 170
          long_int>::result == 0) check(false, "Wrong LargeValue type");
168 171
    if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, float> >::LargeValue,
169 172
          double>::result == 0) check(false, "Wrong LargeValue type");
170 173
  }
171 174

	
172 175
  // Run various tests
173 176
  {
174 177
    typedef SmartDigraph GR;
175 178
    DIGRAPH_TYPEDEFS(GR);
176 179
    
177 180
    GR gr;
178 181
    IntArcMap l1(gr), l2(gr), l3(gr), l4(gr);
179 182
    IntArcMap c1(gr), c2(gr), c3(gr), c4(gr);
180 183
    
181 184
    std::istringstream input(test_lgf);
182 185
    digraphReader(gr, input).
183 186
      arcMap("len1", l1).
184 187
      arcMap("len2", l2).
185 188
      arcMap("len3", l3).
186 189
      arcMap("len4", l4).
187 190
      arcMap("c1", c1).
188 191
      arcMap("c2", c2).
189 192
      arcMap("c3", c3).
190 193
      arcMap("c4", c4).
191 194
      run();
192 195

	
193 196
    // Karp
194 197
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l1, c1,  6, 3);
195 198
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l2, c2,  5, 2);
196 199
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l3, c3,  0, 1);
197 200
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l4, c4, -1, 1);
198 201

	
199 202
    // HartmannOrlin
200 203
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l1, c1,  6, 3);
201 204
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l2, c2,  5, 2);
202 205
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l3, c3,  0, 1);
203 206
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l4, c4, -1, 1);
204 207

	
205 208
    // Howard
206 209
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l1, c1,  6, 3);
207 210
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l2, c2,  5, 2);
208 211
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l3, c3,  0, 1);
209 212
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l4, c4, -1, 1);
210 213
  }
211 214

	
212 215
  return 0;
213 216
}
0 comments (0 inline)