| ... | ... | 
		@@ -119,20 +119,23 @@  | 
| 119 | 119 | 
		 | 
| 120 | 120 | 
		/// \brief Constants for selecting the pivot rule.  | 
| 121 | 121 | 
		///  | 
| 122 | 122 | 
		/// Enum type containing constants for selecting the pivot rule for  | 
| 123 | 123 | 
		/// the \ref run() function.  | 
| 124 | 124 | 
		///  | 
| 125 | 
		/// \ref NetworkSimplex provides five different pivot rule  | 
|
| 126 | 
		/// implementations that significantly affect the running time  | 
|
| 125 | 
		/// \ref NetworkSimplex provides five different implementations for  | 
|
| 126 | 
		/// the pivot strategy that significantly affects the running time  | 
|
| 127 | 127 | 
		/// of the algorithm.  | 
| 128 | 
		/// By default, \ref BLOCK_SEARCH "Block Search" is used, which  | 
|
| 129 | 
		/// turend out to be the most efficient and the most robust on various  | 
|
| 130 | 
		/// test inputs.  | 
|
| 131 | 
		/// However, another pivot rule can be selected using the \ref run()  | 
|
| 132 | 
		///  | 
|
| 128 | 
		/// According to experimental tests conducted on various problem  | 
|
| 129 | 
		/// instances, \ref BLOCK_SEARCH "Block Search" and  | 
|
| 130 | 
		/// \ref ALTERING_LIST "Altering Candidate List" rules turned out  | 
|
| 131 | 
		/// to be the most efficient.  | 
|
| 132 | 
		/// Since \ref BLOCK_SEARCH "Block Search" is a simpler strategy that  | 
|
| 133 | 
		/// seemed to be slightly more robust, it is used by default.  | 
|
| 134 | 
		/// However, another pivot rule can easily be selected using the  | 
|
| 135 | 
		/// \ref run() function with the proper parameter.  | 
|
| 133 | 136 | 
		    enum PivotRule {
	 | 
| 134 | 137 | 
		 | 
| 135 | 138 | 
		/// The \e First \e Eligible pivot rule.  | 
| 136 | 139 | 
		/// The next eligible arc is selected in a wraparound fashion  | 
| 137 | 140 | 
		/// in every iteration.  | 
| 138 | 141 | 
		FIRST_ELIGIBLE,  | 
| ... | ... | 
		@@ -152,13 +155,13 @@  | 
| 152 | 155 | 
		/// in a wraparound fashion and in the following minor iterations  | 
| 153 | 156 | 
		/// the best eligible arc is selected from this list.  | 
| 154 | 157 | 
		CANDIDATE_LIST,  | 
| 155 | 158 | 
		 | 
| 156 | 159 | 
		/// The \e Altering \e Candidate \e List pivot rule.  | 
| 157 | 160 | 
		/// It is a modified version of the Candidate List method.  | 
| 158 | 
		/// It keeps only  | 
|
| 161 | 
		/// It keeps only a few of the best eligible arcs from the former  | 
|
| 159 | 162 | 
		/// candidate list and extends this list in every iteration.  | 
| 160 | 163 | 
		ALTERING_LIST  | 
| 161 | 164 | 
		};  | 
| 162 | 165 | 
		 | 
| 163 | 166 | 
		private:  | 
| 164 | 167 | 
		 | 
| ... | ... | 
		@@ -535,13 +538,13 @@  | 
| 535 | 538 | 
		      {
	 | 
| 536 | 539 | 
		private:  | 
| 537 | 540 | 
		const CostVector &_map;  | 
| 538 | 541 | 
		public:  | 
| 539 | 542 | 
		        SortFunc(const CostVector &map) : _map(map) {}
	 | 
| 540 | 543 | 
		        bool operator()(int left, int right) {
	 | 
| 541 | 
		return _map[left]  | 
|
| 544 | 
		return _map[left] < _map[right];  | 
|
| 542 | 545 | 
		}  | 
| 543 | 546 | 
		};  | 
| 544 | 547 | 
		 | 
| 545 | 548 | 
		SortFunc _sort_func;  | 
| 546 | 549 | 
		 | 
| 547 | 550 | 
		public:  | 
| ... | ... | 
		@@ -553,13 +556,13 @@  | 
| 553 | 556 | 
		_in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),  | 
| 554 | 557 | 
		_next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost)  | 
| 555 | 558 | 
		      {
	 | 
| 556 | 559 | 
		// The main parameters of the pivot rule  | 
| 557 | 560 | 
		const double BLOCK_SIZE_FACTOR = 1.0;  | 
| 558 | 561 | 
		const int MIN_BLOCK_SIZE = 10;  | 
| 559 | 
		const double HEAD_LENGTH_FACTOR = 0.  | 
|
| 562 | 
		const double HEAD_LENGTH_FACTOR = 0.01;  | 
|
| 560 | 563 | 
		const int MIN_HEAD_LENGTH = 3;  | 
| 561 | 564 | 
		 | 
| 562 | 565 | 
		_block_size = std::max( int(BLOCK_SIZE_FACTOR *  | 
| 563 | 566 | 
		std::sqrt(double(_search_arc_num))),  | 
| 564 | 567 | 
		MIN_BLOCK_SIZE );  | 
| 565 | 568 | 
		_head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size),  | 
| ... | ... | 
		@@ -597,37 +600,37 @@  | 
| 597 | 600 | 
		if (_curr_length > limit) goto search_end;  | 
| 598 | 601 | 
		limit = 0;  | 
| 599 | 602 | 
		cnt = _block_size;  | 
| 600 | 603 | 
		}  | 
| 601 | 604 | 
		}  | 
| 602 | 605 | 
		        for (e = 0; e != _next_arc; ++e) {
	 | 
| 603 | 
		_cand_cost[e] = _state[e] *  | 
|
| 604 | 
		(_cost[e] + _pi[_source[e]] - _pi[_target[e]]);  | 
|
| 605 | 
		
  | 
|
| 606 | 
		c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);  | 
|
| 607 | 
		          if (c < 0) {
	 | 
|
| 608 | 
		_cand_cost[e] = c;  | 
|
| 606 | 609 | 
		_candidates[_curr_length++] = e;  | 
| 607 | 610 | 
		}  | 
| 608 | 611 | 
		          if (--cnt == 0) {
	 | 
| 609 | 612 | 
		if (_curr_length > limit) goto search_end;  | 
| 610 | 613 | 
		limit = 0;  | 
| 611 | 614 | 
		cnt = _block_size;  | 
| 612 | 615 | 
		}  | 
| 613 | 616 | 
		}  | 
| 614 | 617 | 
		if (_curr_length == 0) return false;  | 
| 615 | 618 | 
		 | 
| 616 | 619 | 
		search_end:  | 
| 617 | 620 | 
		 | 
| 618 | 
		// Make heap of the candidate list (approximating a partial sort)  | 
|
| 619 | 
		make_heap( _candidates.begin(), _candidates.begin() + _curr_length,  | 
|
| 620 | 
		
  | 
|
| 621 | 
		// Perform partial sort operation on the candidate list  | 
|
| 622 | 
		int new_length = std::min(_head_length + 1, _curr_length);  | 
|
| 623 | 
		std::partial_sort(_candidates.begin(), _candidates.begin() + new_length,  | 
|
| 624 | 
		_candidates.begin() + _curr_length, _sort_func);  | 
|
| 621 | 625 | 
		 | 
| 622 | 
		//  | 
|
| 626 | 
		// Select the entering arc and remove it from the list  | 
|
| 623 | 627 | 
		_in_arc = _candidates[0];  | 
| 624 | 628 | 
		_next_arc = e;  | 
| 625 | 
		pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,  | 
|
| 626 | 
		_sort_func );  | 
|
| 627 | 
		
  | 
|
| 629 | 
		_candidates[0] = _candidates[new_length - 1];  | 
|
| 630 | 
		_curr_length = new_length - 1;  | 
|
| 628 | 631 | 
		return true;  | 
| 629 | 632 | 
		}  | 
| 630 | 633 | 
		 | 
| 631 | 634 | 
		}; //class AlteringListPivotRule  | 
| 632 | 635 | 
		 | 
| 633 | 636 | 
		public:  | 
0 comments (0 inline)