gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 1 0
merge default
1 file changed with 45 insertions and 38 deletions:
↑ Collapse diff ↑
Show white space 6 line context
... ...
@@ -362,33 +362,32 @@
362 362
      bool findEnteringArc() {
363 363
        Cost c, min = 0;
364 364
        int cnt = _block_size;
365
        int e, min_arc = _next_arc;
365
        int e;
366 366
        for (e = _next_arc; e < _search_arc_num; ++e) {
367 367
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
368 368
          if (c < min) {
369 369
            min = c;
370
            min_arc = e;
370
            _in_arc = e;
371 371
          }
372 372
          if (--cnt == 0) {
373
            if (min < 0) break;
373
            if (min < 0) goto search_end;
374 374
            cnt = _block_size;
375 375
          }
376 376
        }
377
        if (min == 0 || cnt > 0) {
378 377
          for (e = 0; e < _next_arc; ++e) {
379 378
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
380 379
            if (c < min) {
381 380
              min = c;
382
              min_arc = e;
381
            _in_arc = e;
383 382
            }
384 383
            if (--cnt == 0) {
385
              if (min < 0) break;
384
            if (min < 0) goto search_end;
386 385
              cnt = _block_size;
387 386
            }
388 387
          }
389
        }
390 388
        if (min >= 0) return false;
391
        _in_arc = min_arc;
389

	
390
      search_end:
392 391
        _next_arc = e;
393 392
        return true;
394 393
      }
... ...
@@ -426,7 +425,7 @@
426 425
        _next_arc(0)
427 426
      {
428 427
        // The main parameters of the pivot rule
429
        const double LIST_LENGTH_FACTOR = 1.0;
428
        const double LIST_LENGTH_FACTOR = 0.25;
430 429
        const int MIN_LIST_LENGTH = 10;
431 430
        const double MINOR_LIMIT_FACTOR = 0.1;
432 431
        const int MIN_MINOR_LIMIT = 3;
... ...
@@ -443,7 +442,7 @@
443 442
      /// Find next entering arc
444 443
      bool findEnteringArc() {
445 444
        Cost min, c;
446
        int e, min_arc = _next_arc;
445
        int e;
447 446
        if (_curr_length > 0 && _minor_count < _minor_limit) {
448 447
          // Minor iteration: select the best eligible arc from the
449 448
          // current candidate list
... ...
@@ -454,16 +453,13 @@
454 453
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
455 454
            if (c < min) {
456 455
              min = c;
457
              min_arc = e;
456
              _in_arc = e;
458 457
            }
459
            if (c >= 0) {
458
            else if (c >= 0) {
460 459
              _candidates[i--] = _candidates[--_curr_length];
461 460
            }
462 461
          }
463
          if (min < 0) {
464
            _in_arc = min_arc;
465
            return true;
466
          }
462
          if (min < 0) return true;
467 463
        }
468 464

	
469 465
        // Major iteration: build a new candidate list
... ...
@@ -475,27 +471,26 @@
475 471
            _candidates[_curr_length++] = e;
476 472
            if (c < min) {
477 473
              min = c;
478
              min_arc = e;
474
              _in_arc = e;
479 475
            }
480
            if (_curr_length == _list_length) break;
476
            if (_curr_length == _list_length) goto search_end;
481 477
          }
482 478
        }
483
        if (_curr_length < _list_length) {
484 479
          for (e = 0; e < _next_arc; ++e) {
485 480
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
486 481
            if (c < 0) {
487 482
              _candidates[_curr_length++] = e;
488 483
              if (c < min) {
489 484
                min = c;
490
                min_arc = e;
485
              _in_arc = e;
491 486
              }
492
              if (_curr_length == _list_length) break;
493
            }
487
            if (_curr_length == _list_length) goto search_end;
494 488
          }
495 489
        }
496 490
        if (_curr_length == 0) return false;
491
      
492
      search_end:        
497 493
        _minor_count = 1;
498
        _in_arc = min_arc;
499 494
        _next_arc = e;
500 495
        return true;
501 496
      }
... ...
@@ -547,7 +542,7 @@
547 542
        _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost)
548 543
      {
549 544
        // The main parameters of the pivot rule
550
        const double BLOCK_SIZE_FACTOR = 1.5;
545
        const double BLOCK_SIZE_FACTOR = 1.0;
551 546
        const int MIN_BLOCK_SIZE = 10;
552 547
        const double HEAD_LENGTH_FACTOR = 0.1;
553 548
        const int MIN_HEAD_LENGTH = 3;
... ...
@@ -576,39 +571,35 @@
576 571

	
577 572
        // Extend the list
578 573
        int cnt = _block_size;
579
        int last_arc = 0;
580 574
        int limit = _head_length;
581 575

	
582
        for (int e = _next_arc; e < _search_arc_num; ++e) {
576
        for (e = _next_arc; e < _search_arc_num; ++e) {
583 577
          _cand_cost[e] = _state[e] *
584 578
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
585 579
          if (_cand_cost[e] < 0) {
586 580
            _candidates[_curr_length++] = e;
587
            last_arc = e;
588 581
          }
589 582
          if (--cnt == 0) {
590
            if (_curr_length > limit) break;
583
            if (_curr_length > limit) goto search_end;
591 584
            limit = 0;
592 585
            cnt = _block_size;
593 586
          }
594 587
        }
595
        if (_curr_length <= limit) {
596
          for (int e = 0; e < _next_arc; ++e) {
588
        for (e = 0; e < _next_arc; ++e) {
597 589
            _cand_cost[e] = _state[e] *
598 590
              (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
599 591
            if (_cand_cost[e] < 0) {
600 592
              _candidates[_curr_length++] = e;
601
              last_arc = e;
602 593
            }
603 594
            if (--cnt == 0) {
604
              if (_curr_length > limit) break;
595
            if (_curr_length > limit) goto search_end;
605 596
              limit = 0;
606 597
              cnt = _block_size;
607 598
            }
608 599
          }
609
        }
610 600
        if (_curr_length == 0) return false;
611
        _next_arc = last_arc + 1;
601
        
602
      search_end:
612 603

	
613 604
        // Make heap of the candidate list (approximating a partial sort)
614 605
        make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
... ...
@@ -616,6 +607,7 @@
616 607

	
617 608
        // Pop the first element of the heap
618 609
        _in_arc = _candidates[0];
610
        _next_arc = e;
619 611
        pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
620 612
                  _sort_func );
621 613
        _curr_length = std::min(_head_length, _curr_length - 1);
... ...
@@ -631,7 +623,11 @@
631 623
    /// The constructor of the class.
632 624
    ///
633 625
    /// \param graph The digraph the algorithm runs on.
634
    NetworkSimplex(const GR& graph) :
626
    /// \param arc_mixing Indicate if the arcs have to be stored in a
627
    /// mixed order in the internal data structure. 
628
    /// In special cases, it could lead to better overall performance,
629
    /// but it is usually slower. Therefore it is disabled by default.
630
    NetworkSimplex(const GR& graph, bool arc_mixing = false) :
635 631
      _graph(graph), _node_id(graph), _arc_id(graph),
636 632
      INF(std::numeric_limits<Value>::has_infinity ?
637 633
          std::numeric_limits<Value>::infinity() :
... ...
@@ -669,18 +665,29 @@
669 665
      _last_succ.resize(all_node_num);
670 666
      _state.resize(max_arc_num);
671 667

	
672
      // Copy the graph (store the arcs in a mixed order)
668
      // Copy the graph
673 669
      int i = 0;
674 670
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
675 671
        _node_id[n] = i;
676 672
      }
673
      if (arc_mixing) {
674
        // Store the arcs in a mixed order
677 675
      int k = std::max(int(std::sqrt(double(_arc_num))), 10);
678
      i = 0;
676
        int i = 0, j = 0;
679 677
      for (ArcIt a(_graph); a != INVALID; ++a) {
680 678
        _arc_id[a] = i;
681 679
        _source[i] = _node_id[_graph.source(a)];
682 680
        _target[i] = _node_id[_graph.target(a)];
683
        if ((i += k) >= _arc_num) i = (i % k) + 1;
681
          if ((i += k) >= _arc_num) i = ++j;
682
        }
683
      } else {
684
        // Store the arcs in the original order
685
        int i = 0;
686
        for (ArcIt a(_graph); a != INVALID; ++a, ++i) {
687
          _arc_id[a] = i;
688
          _source[i] = _node_id[_graph.source(a)];
689
          _target[i] = _node_id[_graph.target(a)];
690
        }
684 691
      }
685 692
      
686 693
      // Reset parameters
0 comments (0 inline)