gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Simplify comparisons in min mean cycle classes (#179) using extreme INF values instead of bool flags.
0 3 0
default
3 files changed with 50 insertions and 39 deletions:
↑ Collapse diff ↑
Ignore white space 25165824 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 shortest_path
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 shortest_path
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
  ///
104 104
  /// \tparam GR The type of the digraph the algorithm runs on.
105 105
  /// \tparam LEN The type of the length map. The default
106 106
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
107 107
#ifdef DOXYGEN
108 108
  template <typename GR, typename LEN, typename TR>
109 109
#else
110 110
  template < typename GR,
111 111
             typename LEN = typename GR::template ArcMap<int>,
112 112
             typename TR = HartmannOrlinDefaultTraits<GR, LEN> >
113 113
#endif
114 114
  class HartmannOrlin
115 115
  {
116 116
  public:
117 117

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

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

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

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

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

	
146 146
  private:
147 147

	
148 148
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
149 149

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

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

	
163 162
  private:
164 163

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

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

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

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

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

	
192 191
    Tolerance _tolerance;
193 192

	
193
    // Infinite constant
194
    const LargeValue INF;
195

	
194 196
  public:
195 197

	
196 198
    /// \name Named Template Parameters
197 199
    /// @{
198 200

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

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

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

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

	
234 236
    /// @}
235 237

	
236 238
  public:
237 239

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

	
251 256
    /// Destructor.
252 257
    ~HartmannOrlin() {
253 258
      if (_local_path) delete _cycle_path;
254 259
    }
255 260

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

	
279 284
    /// \name Execution control
280 285
    /// The simplest way to execute the algorithm is to call the \ref run()
281 286
    /// function.\n
282 287
    /// If you only need the minimum mean length, you may call
283 288
    /// \ref findMinMean().
284 289

	
285 290
    /// @{
286 291

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

	
303 308
    /// \brief Find the minimum cycle mean.
304 309
    ///
305 310
    /// This function finds the minimum mean length of the directed
306 311
    /// cycles in the digraph.
307 312
    ///
308 313
    /// \return \c true if a directed cycle exists in the digraph.
309 314
    bool findMinMean() {
310 315
      // Initialization and find strongly connected components
311 316
      init();
312 317
      findComponents();
313 318
      
314 319
      // Find the minimum cycle mean in the components
315 320
      for (int comp = 0; comp < _comp_num; ++comp) {
316 321
        if (!initComponent(comp)) continue;
317 322
        processRounds();
318 323
        
319 324
        // Update the best cycle (global minimum mean cycle)
320 325
        if ( _curr_found && (!_best_found || 
321 326
             _curr_length * _best_size < _best_length * _curr_size) ) {
322 327
          _best_found = true;
323 328
          _best_length = _curr_length;
324 329
          _best_size = _curr_size;
325 330
          _best_node = _curr_node;
326 331
          _best_level = _curr_level;
327 332
        }
328 333
      }
329 334
      return _best_found;
330 335
    }
331 336

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

	
364 369
    /// @}
365 370

	
366 371
    /// \name Query Functions
367 372
    /// The results of the algorithm can be obtained using these
368 373
    /// functions.\n
369 374
    /// The algorithm should be executed before using them.
370 375

	
371 376
    /// @{
372 377

	
373 378
    /// \brief Return the total length of the found cycle.
374 379
    ///
375 380
    /// This function returns the total length of the found cycle.
376 381
    ///
377 382
    /// \pre \ref run() or \ref findMinMean() must be called before
378 383
    /// using this function.
379 384
    LargeValue cycleLength() const {
380 385
      return _best_length;
381 386
    }
382 387

	
383 388
    /// \brief Return the number of arcs on the found cycle.
384 389
    ///
385 390
    /// This function returns the number of arcs on the found cycle.
386 391
    ///
387 392
    /// \pre \ref run() or \ref findMinMean() must be called before
388 393
    /// using this function.
389 394
    int cycleArcNum() const {
390 395
      return _best_size;
391 396
    }
392 397

	
393 398
    /// \brief Return the mean length of the found cycle.
394 399
    ///
395 400
    /// This function returns the mean length of the found cycle.
396 401
    ///
397 402
    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
398 403
    /// following code.
399 404
    /// \code
400 405
    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
401 406
    /// \endcode
402 407
    ///
403 408
    /// \pre \ref run() or \ref findMinMean() must be called before
404 409
    /// using this function.
405 410
    double cycleMean() const {
406 411
      return static_cast<double>(_best_length) / _best_size;
407 412
    }
408 413

	
409 414
    /// \brief Return the found cycle.
410 415
    ///
411 416
    /// This function returns a const reference to the path structure
412 417
    /// storing the found cycle.
413 418
    ///
414 419
    /// \pre \ref run() or \ref findCycle() must be called before using
415 420
    /// this function.
416 421
    const Path& cycle() const {
417 422
      return *_cycle_path;
418 423
    }
419 424

	
420 425
    ///@}
421 426

	
422 427
  private:
423 428

	
424 429
    // Initialization
425 430
    void init() {
426 431
      if (!_cycle_path) {
427 432
        _local_path = true;
428 433
        _cycle_path = new Path;
429 434
      }
430 435
      _cycle_path->clear();
431 436
      _best_found = false;
432 437
      _best_length = 0;
433 438
      _best_size = 1;
434 439
      _cycle_path->clear();
435 440
      for (NodeIt u(_gr); u != INVALID; ++u)
436 441
        _data[u].clear();
437 442
    }
438 443

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

	
467 472
    // Initialize path data for the current component
468 473
    bool initComponent(int comp) {
469 474
      _nodes = &(_comp_nodes[comp]);
470 475
      int n = _nodes->size();
471 476
      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
472 477
        return false;
473 478
      }      
474 479
      for (int i = 0; i < n; ++i) {
475
        _data[(*_nodes)[i]].resize(n + 1);
480
        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
476 481
      }
477 482
      return true;
478 483
    }
479 484

	
480 485
    // Process all rounds of computing path data for the current component.
481 486
    // _data[v][k] is the length of a shortest directed walk from the root
482 487
    // node to node v containing exactly k arcs.
483 488
    void processRounds() {
484 489
      Node start = (*_nodes)[0];
485
      _data[start][0] = PathData(true, 0);
490
      _data[start][0] = PathData(0);
486 491
      _process.clear();
487 492
      _process.push_back(start);
488 493

	
489 494
      int k, n = _nodes->size();
490 495
      int next_check = 4;
491 496
      bool terminate = false;
492 497
      for (k = 1; k <= n && int(_process.size()) < n && !terminate; ++k) {
493 498
        processNextBuildRound(k);
494 499
        if (k == next_check || k == n) {
495 500
          terminate = checkTermination(k);
496 501
          next_check = next_check * 3 / 2;
497 502
        }
498 503
      }
499 504
      for ( ; k <= n && !terminate; ++k) {
500 505
        processNextFullRound(k);
501 506
        if (k == next_check || k == n) {
502 507
          terminate = checkTermination(k);
503 508
          next_check = next_check * 3 / 2;
504 509
        }
505 510
      }
506 511
    }
507 512

	
508 513
    // Process one round and rebuild _process
509 514
    void processNextBuildRound(int k) {
510 515
      std::vector<Node> next;
511 516
      Node u, v;
512 517
      Arc e;
513 518
      LargeValue d;
514 519
      for (int i = 0; i < int(_process.size()); ++i) {
515 520
        u = _process[i];
516 521
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
517 522
          e = _out_arcs[u][j];
518 523
          v = _gr.target(e);
519 524
          d = _data[u][k-1].dist + _length[e];
520
          if (!_data[v][k].found) {
521
            next.push_back(v);
522
            _data[v][k] = PathData(true, _data[u][k-1].dist + _length[e], e);
523
          }
524
          else if (_tolerance.less(d, _data[v][k].dist)) {
525
            _data[v][k] = PathData(true, d, e);
525
          if (_tolerance.less(d, _data[v][k].dist)) {
526
            if (_data[v][k].dist == INF) next.push_back(v);
527
            _data[v][k] = PathData(d, e);
526 528
          }
527 529
        }
528 530
      }
529 531
      _process.swap(next);
530 532
    }
531 533

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

	
583 585
      // If at least one cycle is found, check the optimality condition
584 586
      LargeValue d;
585 587
      if (_curr_found && k < n) {
586 588
        // Find node potentials
587 589
        for (int i = 0; i < n; ++i) {
588 590
          u = (*_nodes)[i];
589
          pi[u] = std::numeric_limits<LargeValue>::max();
591
          pi[u] = INF;
590 592
          for (int j = 0; j <= k; ++j) {
591
            d = _data[u][j].dist * _curr_size - j * _curr_length;
592
            if (_data[u][j].found && _tolerance.less(d, pi[u])) {
593
              pi[u] = d;
593
            if (_data[u][j].dist < INF) {
594
              d = _data[u][j].dist * _curr_size - j * _curr_length;
595
              if (_tolerance.less(d, pi[u])) pi[u] = d;
594 596
            }
595 597
          }
596 598
        }
597 599

	
598 600
        // Check the optimality condition for all arcs
599 601
        bool done = true;
600 602
        for (ArcIt a(_gr); a != INVALID; ++a) {
601 603
          if (_tolerance.less(_length[a] * _curr_size - _curr_length,
602 604
                              pi[_gr.target(a)] - pi[_gr.source(a)]) ) {
603 605
            done = false;
604 606
            break;
605 607
          }
606 608
        }
607 609
        return done;
608 610
      }
609 611
      return (k == n);
610 612
    }
611 613

	
612 614
  }; //class HartmannOrlin
613 615

	
614 616
  ///@}
615 617

	
616 618
} //namespace lemon
617 619

	
618 620
#endif //LEMON_HARTMANN_ORLIN_H
Ignore white space 25165824 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 shortest_path
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 shortest_path
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
  ///
102 102
  /// \tparam GR The type of the digraph the algorithm runs on.
103 103
  /// \tparam LEN The type of the length map. The default
104 104
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
105 105
#ifdef DOXYGEN
106 106
  template <typename GR, typename LEN, typename TR>
107 107
#else
108 108
  template < typename GR,
109 109
             typename LEN = typename GR::template ArcMap<int>,
110 110
             typename TR = HowardDefaultTraits<GR, LEN> >
111 111
#endif
112 112
  class Howard
113 113
  {
114 114
  public:
115 115
  
116 116
    /// The type of the digraph
117 117
    typedef typename TR::Digraph Digraph;
118 118
    /// The type of the length map
119 119
    typedef typename TR::LengthMap LengthMap;
120 120
    /// The type of the arc lengths
121 121
    typedef typename TR::Value Value;
122 122

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

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

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

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

	
144 144
  private:
145 145

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

	
153 153
    // Data for the found cycles
154 154
    bool _curr_found, _best_found;
155 155
    LargeValue _curr_length, _best_length;
156 156
    int _curr_size, _best_size;
157 157
    Node _curr_node, _best_node;
158 158

	
159 159
    Path *_cycle_path;
160 160
    bool _local_path;
161 161

	
162 162
    // Internal data used by the algorithm
163 163
    typename Digraph::template NodeMap<Arc> _policy;
164 164
    typename Digraph::template NodeMap<bool> _reached;
165 165
    typename Digraph::template NodeMap<int> _level;
166 166
    typename Digraph::template NodeMap<LargeValue> _dist;
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> > _in_arcs;
174 174
    
175 175
    // Queue used for BFS search
176 176
    std::vector<Node> _queue;
177 177
    int _qfront, _qback;
178 178

	
179 179
    Tolerance _tolerance;
180 180
  
181
    // Infinite constant
182
    const LargeValue INF;
183

	
181 184
  public:
182 185
  
183 186
    /// \name Named Template Parameters
184 187
    /// @{
185 188

	
186 189
    template <typename T>
187 190
    struct SetLargeValueTraits : public Traits {
188 191
      typedef T LargeValue;
189 192
      typedef lemon::Tolerance<T> Tolerance;
190 193
    };
191 194

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

	
203 206
    template <typename T>
204 207
    struct SetPathTraits : public Traits {
205 208
      typedef T Path;
206 209
    };
207 210

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

	
223 226
  public:
224 227

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

	
238 245
    /// Destructor.
239 246
    ~Howard() {
240 247
      if (_local_path) delete _cycle_path;
241 248
    }
242 249

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

	
266 273
    /// \name Execution control
267 274
    /// The simplest way to execute the algorithm is to call the \ref run()
268 275
    /// function.\n
269 276
    /// If you only need the minimum mean length, you may call
270 277
    /// \ref findMinMean().
271 278

	
272 279
    /// @{
273 280

	
274 281
    /// \brief Run the algorithm.
275 282
    ///
276 283
    /// This function runs the algorithm.
277 284
    /// It can be called more than once (e.g. if the underlying digraph
278 285
    /// and/or the arc lengths have been modified).
279 286
    ///
280 287
    /// \return \c true if a directed cycle exists in the digraph.
281 288
    ///
282 289
    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
283 290
    /// \code
284 291
    ///   return mmc.findMinMean() && mmc.findCycle();
285 292
    /// \endcode
286 293
    bool run() {
287 294
      return findMinMean() && findCycle();
288 295
    }
289 296

	
290 297
    /// \brief Find the minimum cycle mean.
291 298
    ///
292 299
    /// This function finds the minimum mean length of the directed
293 300
    /// cycles in the digraph.
294 301
    ///
295 302
    /// \return \c true if a directed cycle exists in the digraph.
296 303
    bool findMinMean() {
297 304
      // Initialize and find strongly connected components
298 305
      init();
299 306
      findComponents();
300 307
      
301 308
      // Find the minimum cycle mean in the components
302 309
      for (int comp = 0; comp < _comp_num; ++comp) {
303 310
        // Find the minimum mean cycle in the current component
304 311
        if (!buildPolicyGraph(comp)) continue;
305 312
        while (true) {
306 313
          findPolicyCycle();
307 314
          if (!computeNodeDistances()) break;
308 315
        }
309 316
        // Update the best cycle (global minimum mean cycle)
310
        if ( !_best_found || (_curr_found &&
317
        if ( _curr_found && (!_best_found ||
311 318
             _curr_length * _best_size < _best_length * _curr_size) ) {
312 319
          _best_found = true;
313 320
          _best_length = _curr_length;
314 321
          _best_size = _curr_size;
315 322
          _best_node = _curr_node;
316 323
        }
317 324
      }
318 325
      return _best_found;
319 326
    }
320 327

	
321 328
    /// \brief Find a minimum mean directed cycle.
322 329
    ///
323 330
    /// This function finds a directed cycle of minimum mean length
324 331
    /// in the digraph using the data computed by findMinMean().
325 332
    ///
326 333
    /// \return \c true if a directed cycle exists in the digraph.
327 334
    ///
328 335
    /// \pre \ref findMinMean() must be called before using this function.
329 336
    bool findCycle() {
330 337
      if (!_best_found) return false;
331 338
      _cycle_path->addBack(_policy[_best_node]);
332 339
      for ( Node v = _best_node;
333 340
            (v = _gr.target(_policy[v])) != _best_node; ) {
334 341
        _cycle_path->addBack(_policy[v]);
335 342
      }
336 343
      return true;
337 344
    }
338 345

	
339 346
    /// @}
340 347

	
341 348
    /// \name Query Functions
342 349
    /// The results of the algorithm can be obtained using these
343 350
    /// functions.\n
344 351
    /// The algorithm should be executed before using them.
345 352

	
346 353
    /// @{
347 354

	
348 355
    /// \brief Return the total length of the found cycle.
349 356
    ///
350 357
    /// This function returns the total length of the found cycle.
351 358
    ///
352 359
    /// \pre \ref run() or \ref findMinMean() must be called before
353 360
    /// using this function.
354 361
    LargeValue cycleLength() const {
355 362
      return _best_length;
356 363
    }
357 364

	
358 365
    /// \brief Return the number of arcs on the found cycle.
359 366
    ///
360 367
    /// This function returns the number of arcs on the found cycle.
361 368
    ///
362 369
    /// \pre \ref run() or \ref findMinMean() must be called before
363 370
    /// using this function.
364 371
    int cycleArcNum() const {
365 372
      return _best_size;
366 373
    }
367 374

	
368 375
    /// \brief Return the mean length of the found cycle.
369 376
    ///
370 377
    /// This function returns the mean length of the found cycle.
371 378
    ///
372 379
    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
373 380
    /// following code.
374 381
    /// \code
375 382
    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
376 383
    /// \endcode
377 384
    ///
378 385
    /// \pre \ref run() or \ref findMinMean() must be called before
379 386
    /// using this function.
380 387
    double cycleMean() const {
381 388
      return static_cast<double>(_best_length) / _best_size;
382 389
    }
383 390

	
384 391
    /// \brief Return the found cycle.
385 392
    ///
386 393
    /// This function returns a const reference to the path structure
387 394
    /// storing the found cycle.
388 395
    ///
389 396
    /// \pre \ref run() or \ref findCycle() must be called before using
390 397
    /// this function.
391 398
    const Path& cycle() const {
392 399
      return *_cycle_path;
393 400
    }
394 401

	
395 402
    ///@}
396 403

	
397 404
  private:
398 405

	
399 406
    // Initialize
400 407
    void init() {
401 408
      if (!_cycle_path) {
402 409
        _local_path = true;
403 410
        _cycle_path = new Path;
404 411
      }
405 412
      _queue.resize(countNodes(_gr));
406 413
      _best_found = false;
407 414
      _best_length = 0;
408 415
      _best_size = 1;
409 416
      _cycle_path->clear();
410 417
    }
411 418
    
412 419
    // Find strongly connected components and initialize _comp_nodes
413 420
    // and _in_arcs
414 421
    void findComponents() {
415 422
      _comp_num = stronglyConnectedComponents(_gr, _comp);
416 423
      _comp_nodes.resize(_comp_num);
417 424
      if (_comp_num == 1) {
418 425
        _comp_nodes[0].clear();
419 426
        for (NodeIt n(_gr); n != INVALID; ++n) {
420 427
          _comp_nodes[0].push_back(n);
421 428
          _in_arcs[n].clear();
422 429
          for (InArcIt a(_gr, n); a != INVALID; ++a) {
423 430
            _in_arcs[n].push_back(a);
424 431
          }
425 432
        }
426 433
      } else {
427 434
        for (int i = 0; i < _comp_num; ++i)
428 435
          _comp_nodes[i].clear();
429 436
        for (NodeIt n(_gr); n != INVALID; ++n) {
430 437
          int k = _comp[n];
431 438
          _comp_nodes[k].push_back(n);
432 439
          _in_arcs[n].clear();
433 440
          for (InArcIt a(_gr, n); a != INVALID; ++a) {
434 441
            if (_comp[_gr.source(a)] == k) _in_arcs[n].push_back(a);
435 442
          }
436 443
        }
437 444
      }
438 445
    }
439 446

	
440 447
    // Build the policy graph in the given strongly connected component
441 448
    // (the out-degree of every node is 1)
442 449
    bool buildPolicyGraph(int comp) {
443 450
      _nodes = &(_comp_nodes[comp]);
444 451
      if (_nodes->size() < 1 ||
445 452
          (_nodes->size() == 1 && _in_arcs[(*_nodes)[0]].size() == 0)) {
446 453
        return false;
447 454
      }
448 455
      for (int i = 0; i < int(_nodes->size()); ++i) {
449
        _dist[(*_nodes)[i]] = std::numeric_limits<LargeValue>::max();
456
        _dist[(*_nodes)[i]] = INF;
450 457
      }
451 458
      Node u, v;
452 459
      Arc e;
453 460
      for (int i = 0; i < int(_nodes->size()); ++i) {
454 461
        v = (*_nodes)[i];
455 462
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
456 463
          e = _in_arcs[v][j];
457 464
          u = _gr.source(e);
458 465
          if (_length[e] < _dist[u]) {
459 466
            _dist[u] = _length[e];
460 467
            _policy[u] = e;
461 468
          }
462 469
        }
463 470
      }
464 471
      return true;
465 472
    }
466 473

	
467 474
    // Find the minimum mean cycle in the policy graph
468 475
    void findPolicyCycle() {
469 476
      for (int i = 0; i < int(_nodes->size()); ++i) {
470 477
        _level[(*_nodes)[i]] = -1;
471 478
      }
472 479
      LargeValue clength;
473 480
      int csize;
474 481
      Node u, v;
475 482
      _curr_found = false;
476 483
      for (int i = 0; i < int(_nodes->size()); ++i) {
477 484
        u = (*_nodes)[i];
478 485
        if (_level[u] >= 0) continue;
479 486
        for (; _level[u] < 0; u = _gr.target(_policy[u])) {
480 487
          _level[u] = i;
481 488
        }
482 489
        if (_level[u] == i) {
483 490
          // A cycle is found
484 491
          clength = _length[_policy[u]];
485 492
          csize = 1;
486 493
          for (v = u; (v = _gr.target(_policy[v])) != u; ) {
487 494
            clength += _length[_policy[v]];
488 495
            ++csize;
489 496
          }
490 497
          if ( !_curr_found ||
491 498
               (clength * _curr_size < _curr_length * csize) ) {
492 499
            _curr_found = true;
493 500
            _curr_length = clength;
494 501
            _curr_size = csize;
495 502
            _curr_node = u;
496 503
          }
497 504
        }
498 505
      }
499 506
    }
500 507

	
501 508
    // Contract the policy graph and compute node distances
502 509
    bool computeNodeDistances() {
503 510
      // Find the component of the main cycle and compute node distances
504 511
      // using reverse BFS
505 512
      for (int i = 0; i < int(_nodes->size()); ++i) {
506 513
        _reached[(*_nodes)[i]] = false;
507 514
      }
508 515
      _qfront = _qback = 0;
509 516
      _queue[0] = _curr_node;
510 517
      _reached[_curr_node] = true;
511 518
      _dist[_curr_node] = 0;
512 519
      Node u, v;
513 520
      Arc e;
514 521
      while (_qfront <= _qback) {
515 522
        v = _queue[_qfront++];
516 523
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
517 524
          e = _in_arcs[v][j];
518 525
          u = _gr.source(e);
519 526
          if (_policy[u] == e && !_reached[u]) {
520 527
            _reached[u] = true;
521 528
            _dist[u] = _dist[v] + _length[e] * _curr_size - _curr_length;
522 529
            _queue[++_qback] = u;
523 530
          }
524 531
        }
525 532
      }
526 533

	
527 534
      // Connect all other nodes to this component and compute node
528 535
      // distances using reverse BFS
529 536
      _qfront = 0;
530 537
      while (_qback < int(_nodes->size())-1) {
531 538
        v = _queue[_qfront++];
532 539
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
533 540
          e = _in_arcs[v][j];
534 541
          u = _gr.source(e);
535 542
          if (!_reached[u]) {
536 543
            _reached[u] = true;
537 544
            _policy[u] = e;
538 545
            _dist[u] = _dist[v] + _length[e] * _curr_size - _curr_length;
539 546
            _queue[++_qback] = u;
540 547
          }
541 548
        }
542 549
      }
543 550

	
544 551
      // Improve node distances
545 552
      bool improved = false;
546 553
      for (int i = 0; i < int(_nodes->size()); ++i) {
547 554
        v = (*_nodes)[i];
548 555
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
549 556
          e = _in_arcs[v][j];
550 557
          u = _gr.source(e);
551 558
          LargeValue delta = _dist[v] + _length[e] * _curr_size - _curr_length;
552 559
          if (_tolerance.less(delta, _dist[u])) {
553 560
            _dist[u] = delta;
554 561
            _policy[u] = e;
555 562
            improved = true;
556 563
          }
557 564
        }
558 565
      }
559 566
      return improved;
560 567
    }
561 568

	
562 569
  }; //class Howard
563 570

	
564 571
  ///@}
565 572

	
566 573
} //namespace lemon
567 574

	
568 575
#endif //LEMON_HOWARD_H
Ignore white space 25165824 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 shortest_path
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 shortest_path
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
  ///
102 102
  /// \tparam GR The type of the digraph the algorithm runs on.
103 103
  /// \tparam LEN The type of the length map. The default
104 104
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
105 105
#ifdef DOXYGEN
106 106
  template <typename GR, typename LEN, typename TR>
107 107
#else
108 108
  template < typename GR,
109 109
             typename LEN = typename GR::template ArcMap<int>,
110 110
             typename TR = KarpDefaultTraits<GR, LEN> >
111 111
#endif
112 112
  class Karp
113 113
  {
114 114
  public:
115 115

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

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

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

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

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

	
144 144
  private:
145 145

	
146 146
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
147 147

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

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

	
161 160
  private:
162 161

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

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

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

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

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

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

	
190 192
  public:
191 193

	
192 194
    /// \name Named Template Parameters
193 195
    /// @{
194 196

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

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

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

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

	
230 232
    /// @}
231 233

	
232 234
  public:
233 235

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

	
247 252
    /// Destructor.
248 253
    ~Karp() {
249 254
      if (_local_path) delete _cycle_path;
250 255
    }
251 256

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

	
275 280
    /// \name Execution control
276 281
    /// The simplest way to execute the algorithm is to call the \ref run()
277 282
    /// function.\n
278 283
    /// If you only need the minimum mean length, you may call
279 284
    /// \ref findMinMean().
280 285

	
281 286
    /// @{
282 287

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

	
299 304
    /// \brief Find the minimum cycle mean.
300 305
    ///
301 306
    /// This function finds the minimum mean length of the directed
302 307
    /// cycles in the digraph.
303 308
    ///
304 309
    /// \return \c true if a directed cycle exists in the digraph.
305 310
    bool findMinMean() {
306 311
      // Initialization and find strongly connected components
307 312
      init();
308 313
      findComponents();
309 314
      
310 315
      // Find the minimum cycle mean in the components
311 316
      for (int comp = 0; comp < _comp_num; ++comp) {
312 317
        if (!initComponent(comp)) continue;
313 318
        processRounds();
314 319
        updateMinMean();
315 320
      }
316 321
      return (_cycle_node != INVALID);
317 322
    }
318 323

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

	
351 356
    /// @}
352 357

	
353 358
    /// \name Query Functions
354 359
    /// The results of the algorithm can be obtained using these
355 360
    /// functions.\n
356 361
    /// The algorithm should be executed before using them.
357 362

	
358 363
    /// @{
359 364

	
360 365
    /// \brief Return the total length of the found cycle.
361 366
    ///
362 367
    /// This function returns the total length of the found cycle.
363 368
    ///
364 369
    /// \pre \ref run() or \ref findMinMean() must be called before
365 370
    /// using this function.
366 371
    LargeValue cycleLength() const {
367 372
      return _cycle_length;
368 373
    }
369 374

	
370 375
    /// \brief Return the number of arcs on the found cycle.
371 376
    ///
372 377
    /// This function returns the number of arcs on the found cycle.
373 378
    ///
374 379
    /// \pre \ref run() or \ref findMinMean() must be called before
375 380
    /// using this function.
376 381
    int cycleArcNum() const {
377 382
      return _cycle_size;
378 383
    }
379 384

	
380 385
    /// \brief Return the mean length of the found cycle.
381 386
    ///
382 387
    /// This function returns the mean length of the found cycle.
383 388
    ///
384 389
    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
385 390
    /// following code.
386 391
    /// \code
387 392
    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
388 393
    /// \endcode
389 394
    ///
390 395
    /// \pre \ref run() or \ref findMinMean() must be called before
391 396
    /// using this function.
392 397
    double cycleMean() const {
393 398
      return static_cast<double>(_cycle_length) / _cycle_size;
394 399
    }
395 400

	
396 401
    /// \brief Return the found cycle.
397 402
    ///
398 403
    /// This function returns a const reference to the path structure
399 404
    /// storing the found cycle.
400 405
    ///
401 406
    /// \pre \ref run() or \ref findCycle() must be called before using
402 407
    /// this function.
403 408
    const Path& cycle() const {
404 409
      return *_cycle_path;
405 410
    }
406 411

	
407 412
    ///@}
408 413

	
409 414
  private:
410 415

	
411 416
    // Initialization
412 417
    void init() {
413 418
      if (!_cycle_path) {
414 419
        _local_path = true;
415 420
        _cycle_path = new Path;
416 421
      }
417 422
      _cycle_path->clear();
418 423
      _cycle_length = 0;
419 424
      _cycle_size = 1;
420 425
      _cycle_node = INVALID;
421 426
      for (NodeIt u(_gr); u != INVALID; ++u)
422 427
        _data[u].clear();
423 428
    }
424 429

	
425 430
    // Find strongly connected components and initialize _comp_nodes
426 431
    // and _out_arcs
427 432
    void findComponents() {
428 433
      _comp_num = stronglyConnectedComponents(_gr, _comp);
429 434
      _comp_nodes.resize(_comp_num);
430 435
      if (_comp_num == 1) {
431 436
        _comp_nodes[0].clear();
432 437
        for (NodeIt n(_gr); n != INVALID; ++n) {
433 438
          _comp_nodes[0].push_back(n);
434 439
          _out_arcs[n].clear();
435 440
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
436 441
            _out_arcs[n].push_back(a);
437 442
          }
438 443
        }
439 444
      } else {
440 445
        for (int i = 0; i < _comp_num; ++i)
441 446
          _comp_nodes[i].clear();
442 447
        for (NodeIt n(_gr); n != INVALID; ++n) {
443 448
          int k = _comp[n];
444 449
          _comp_nodes[k].push_back(n);
445 450
          _out_arcs[n].clear();
446 451
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
447 452
            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
448 453
          }
449 454
        }
450 455
      }
451 456
    }
452 457

	
453 458
    // Initialize path data for the current component
454 459
    bool initComponent(int comp) {
455 460
      _nodes = &(_comp_nodes[comp]);
456 461
      int n = _nodes->size();
457 462
      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
458 463
        return false;
459 464
      }      
460 465
      for (int i = 0; i < n; ++i) {
461
        _data[(*_nodes)[i]].resize(n + 1);
466
        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
462 467
      }
463 468
      return true;
464 469
    }
465 470

	
466 471
    // Process all rounds of computing path data for the current component.
467 472
    // _data[v][k] is the length of a shortest directed walk from the root
468 473
    // node to node v containing exactly k arcs.
469 474
    void processRounds() {
470 475
      Node start = (*_nodes)[0];
471
      _data[start][0] = PathData(true, 0);
476
      _data[start][0] = PathData(0);
472 477
      _process.clear();
473 478
      _process.push_back(start);
474 479

	
475 480
      int k, n = _nodes->size();
476 481
      for (k = 1; k <= n && int(_process.size()) < n; ++k) {
477 482
        processNextBuildRound(k);
478 483
      }
479 484
      for ( ; k <= n; ++k) {
480 485
        processNextFullRound(k);
481 486
      }
482 487
    }
483 488

	
484 489
    // Process one round and rebuild _process
485 490
    void processNextBuildRound(int k) {
486 491
      std::vector<Node> next;
487 492
      Node u, v;
488 493
      Arc e;
489 494
      LargeValue d;
490 495
      for (int i = 0; i < int(_process.size()); ++i) {
491 496
        u = _process[i];
492 497
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
493 498
          e = _out_arcs[u][j];
494 499
          v = _gr.target(e);
495 500
          d = _data[u][k-1].dist + _length[e];
496
          if (!_data[v][k].found) {
497
            next.push_back(v);
498
            _data[v][k] = PathData(true, _data[u][k-1].dist + _length[e], e);
499
          }
500
          else if (_tolerance.less(d, _data[v][k].dist)) {
501
            _data[v][k] = PathData(true, d, e);
501
          if (_tolerance.less(d, _data[v][k].dist)) {
502
            if (_data[v][k].dist == INF) next.push_back(v);
503
            _data[v][k] = PathData(d, e);
502 504
          }
503 505
        }
504 506
      }
505 507
      _process.swap(next);
506 508
    }
507 509

	
508 510
    // Process one round using _nodes instead of _process
509 511
    void processNextFullRound(int k) {
510 512
      Node u, v;
511 513
      Arc e;
512 514
      LargeValue d;
513 515
      for (int i = 0; i < int(_nodes->size()); ++i) {
514 516
        u = (*_nodes)[i];
515 517
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
516 518
          e = _out_arcs[u][j];
517 519
          v = _gr.target(e);
518 520
          d = _data[u][k-1].dist + _length[e];
519
          if (!_data[v][k].found || _tolerance.less(d, _data[v][k].dist)) {
520
            _data[v][k] = PathData(true, d, e);
521
          if (_tolerance.less(d, _data[v][k].dist)) {
522
            _data[v][k] = PathData(d, e);
521 523
          }
522 524
        }
523 525
      }
524 526
    }
525 527

	
526 528
    // Update the minimum cycle mean
527 529
    void updateMinMean() {
528 530
      int n = _nodes->size();
529 531
      for (int i = 0; i < n; ++i) {
530 532
        Node u = (*_nodes)[i];
531
        if (!_data[u][n].found) continue;
533
        if (_data[u][n].dist == INF) continue;
532 534
        LargeValue length, max_length = 0;
533 535
        int size, max_size = 1;
534 536
        bool found_curr = false;
535 537
        for (int k = 0; k < n; ++k) {
536
          if (!_data[u][k].found) continue;
538
          if (_data[u][k].dist == INF) continue;
537 539
          length = _data[u][n].dist - _data[u][k].dist;
538 540
          size = n - k;
539 541
          if (!found_curr || length * max_size > max_length * size) {
540 542
            found_curr = true;
541 543
            max_length = length;
542 544
            max_size = size;
543 545
          }
544 546
        }
545 547
        if ( found_curr && (_cycle_node == INVALID ||
546 548
             max_length * _cycle_size < _cycle_length * max_size) ) {
547 549
          _cycle_length = max_length;
548 550
          _cycle_size = max_size;
549 551
          _cycle_node = u;
550 552
        }
551 553
      }
552 554
    }
553 555

	
554 556
  }; //class Karp
555 557

	
556 558
  ///@}
557 559

	
558 560
} //namespace lemon
559 561

	
560 562
#endif //LEMON_KARP_H
0 comments (0 inline)