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 6 line context
... ...
@@ -145,21 +145,20 @@
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
... ...
@@ -186,16 +185,19 @@
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;
... ...
@@ -240,17 +242,20 @@
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.
... ...
@@ -467,27 +472,27 @@
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);
... ...
@@ -512,22 +517,19 @@
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) {
... ...
@@ -535,18 +537,18 @@
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;
... ...
@@ -556,17 +558,17 @@
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;
... ...
@@ -581,21 +583,21 @@
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,
Ignore white space 6 line context
... ...
@@ -173,16 +173,19 @@
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;
... ...
@@ -225,19 +228,23 @@
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.
... ...
@@ -302,17 +309,17 @@
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;
... ...
@@ -441,17 +448,17 @@
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);
Ignore white space 16 line context
... ...
@@ -143,21 +143,20 @@
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
... ...
@@ -181,16 +180,19 @@
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 {
... ...
@@ -236,17 +238,20 @@
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.
... ...
@@ -453,27 +458,27 @@
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) {
... ...
@@ -488,22 +493,19 @@
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) {
... ...
@@ -511,34 +513,34 @@
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
        }
0 comments (0 inline)