gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Add a parameter to control arc mixing in NS (#298)
0 1 0
default
1 file changed with 19 insertions and 4 deletions:
↑ Collapse diff ↑
Show white space 96 line context
... ...
@@ -580,146 +580,161 @@
580 580
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
581 581
          if (_cand_cost[e] < 0) {
582 582
            _candidates[_curr_length++] = e;
583 583
          }
584 584
          if (--cnt == 0) {
585 585
            if (_curr_length > limit) goto search_end;
586 586
            limit = 0;
587 587
            cnt = _block_size;
588 588
          }
589 589
        }
590 590
        for (e = 0; e < _next_arc; ++e) {
591 591
          _cand_cost[e] = _state[e] *
592 592
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
593 593
          if (_cand_cost[e] < 0) {
594 594
            _candidates[_curr_length++] = e;
595 595
          }
596 596
          if (--cnt == 0) {
597 597
            if (_curr_length > limit) goto search_end;
598 598
            limit = 0;
599 599
            cnt = _block_size;
600 600
          }
601 601
        }
602 602
        if (_curr_length == 0) return false;
603 603
        
604 604
      search_end:
605 605

	
606 606
        // Make heap of the candidate list (approximating a partial sort)
607 607
        make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
608 608
                   _sort_func );
609 609

	
610 610
        // Pop the first element of the heap
611 611
        _in_arc = _candidates[0];
612 612
        _next_arc = e;
613 613
        pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
614 614
                  _sort_func );
615 615
        _curr_length = std::min(_head_length, _curr_length - 1);
616 616
        return true;
617 617
      }
618 618

	
619 619
    }; //class AlteringListPivotRule
620 620

	
621 621
  public:
622 622

	
623 623
    /// \brief Constructor.
624 624
    ///
625 625
    /// The constructor of the class.
626 626
    ///
627 627
    /// \param graph The digraph the algorithm runs on.
628
    NetworkSimplex(const GR& graph) :
628
    /// \param arc_mixing Indicate if the arcs have to be stored in a
629
    /// mixed order in the internal data structure. 
630
    /// In special cases, it could lead to better overall performance,
631
    /// but it is usually slower. Therefore it is disabled by default.
632
    NetworkSimplex(const GR& graph, bool arc_mixing = false) :
629 633
      _graph(graph), _node_id(graph), _arc_id(graph),
630 634
      INF(std::numeric_limits<Value>::has_infinity ?
631 635
          std::numeric_limits<Value>::infinity() :
632 636
          std::numeric_limits<Value>::max())
633 637
    {
634 638
      // Check the value types
635 639
      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
636 640
        "The flow type of NetworkSimplex must be signed");
637 641
      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
638 642
        "The cost type of NetworkSimplex must be signed");
639 643
        
640 644
      // Resize vectors
641 645
      _node_num = countNodes(_graph);
642 646
      _arc_num = countArcs(_graph);
643 647
      int all_node_num = _node_num + 1;
644 648
      int max_arc_num = _arc_num + 2 * _node_num;
645 649

	
646 650
      _source.resize(max_arc_num);
647 651
      _target.resize(max_arc_num);
648 652

	
649 653
      _lower.resize(_arc_num);
650 654
      _upper.resize(_arc_num);
651 655
      _cap.resize(max_arc_num);
652 656
      _cost.resize(max_arc_num);
653 657
      _supply.resize(all_node_num);
654 658
      _flow.resize(max_arc_num);
655 659
      _pi.resize(all_node_num);
656 660

	
657 661
      _parent.resize(all_node_num);
658 662
      _pred.resize(all_node_num);
659 663
      _forward.resize(all_node_num);
660 664
      _thread.resize(all_node_num);
661 665
      _rev_thread.resize(all_node_num);
662 666
      _succ_num.resize(all_node_num);
663 667
      _last_succ.resize(all_node_num);
664 668
      _state.resize(max_arc_num);
665 669

	
666
      // Copy the graph (store the arcs in a mixed order)
670
      // Copy the graph
667 671
      int i = 0;
668 672
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
669 673
        _node_id[n] = i;
670 674
      }
675
      if (arc_mixing) {
676
        // Store the arcs in a mixed order
671 677
      int k = std::max(int(std::sqrt(double(_arc_num))), 10);
672
      i = 0;
678
        int i = 0, j = 0;
673 679
      for (ArcIt a(_graph); a != INVALID; ++a) {
674 680
        _arc_id[a] = i;
675 681
        _source[i] = _node_id[_graph.source(a)];
676 682
        _target[i] = _node_id[_graph.target(a)];
677
        if ((i += k) >= _arc_num) i = (i % k) + 1;
683
          if ((i += k) >= _arc_num) i = ++j;
684
        }
685
      } else {
686
        // Store the arcs in the original order
687
        int i = 0;
688
        for (ArcIt a(_graph); a != INVALID; ++a, ++i) {
689
          _arc_id[a] = i;
690
          _source[i] = _node_id[_graph.source(a)];
691
          _target[i] = _node_id[_graph.target(a)];
692
        }
678 693
      }
679 694
      
680 695
      // Initialize maps
681 696
      for (int i = 0; i != _node_num; ++i) {
682 697
        _supply[i] = 0;
683 698
      }
684 699
      for (int i = 0; i != _arc_num; ++i) {
685 700
        _lower[i] = 0;
686 701
        _upper[i] = INF;
687 702
        _cost[i] = 1;
688 703
      }
689 704
      _have_lower = false;
690 705
      _stype = GEQ;
691 706
    }
692 707

	
693 708
    /// \name Parameters
694 709
    /// The parameters of the algorithm can be specified using these
695 710
    /// functions.
696 711

	
697 712
    /// @{
698 713

	
699 714
    /// \brief Set the lower bounds on the arcs.
700 715
    ///
701 716
    /// This function sets the lower bounds on the arcs.
702 717
    /// If it is not used before calling \ref run(), the lower bounds
703 718
    /// will be set to zero on all arcs.
704 719
    ///
705 720
    /// \param map An arc map storing the lower bounds.
706 721
    /// Its \c Value type must be convertible to the \c Value type
707 722
    /// of the algorithm.
708 723
    ///
709 724
    /// \return <tt>(*this)</tt>
710 725
    template <typename LowerMap>
711 726
    NetworkSimplex& lowerMap(const LowerMap& map) {
712 727
      _have_lower = true;
713 728
      for (ArcIt a(_graph); a != INVALID; ++a) {
714 729
        _lower[_arc_id[a]] = map[a];
715 730
      }
716 731
      return *this;
717 732
    }
718 733

	
719 734
    /// \brief Set the upper bounds (capacities) on the arcs.
720 735
    ///
721 736
    /// This function sets the upper bounds (capacities) on the arcs.
722 737
    /// If it is not used before calling \ref run(), the upper bounds
723 738
    /// will be set to \ref INF on all arcs (i.e. the flow value will be
724 739
    /// unbounded from above on each arc).
725 740
    ///
0 comments (0 inline)