# HG changeset patch
# User Peter Kovacs <kpeter@inf.elte.hu>
# Date 1246458841 7200
# Node ID cab85bd7859b6b89eee29e8db1619888a513e6a6
# Parent 257e91516e09d8d6be58236c587e3e0199770412
Small improvements in NS pivot rules (#298)
diff git a/lemon/network_simplex.h b/lemon/network_simplex.h
a

b


364  364  bool findEnteringArc() { 
365  365  Cost c, min = 0; 
366  366  int cnt = _block_size; 
367   int e, min_arc = _next_arc; 
 367  int e; 
368  368  for (e = _next_arc; e < _search_arc_num; ++e) { 
369  369  c = _state[e] * (_cost[e] + _pi[_source[e]]  _pi[_target[e]]); 
370  370  if (c < min) { 
371  371  min = c; 
372   min_arc = e; 
 372  _in_arc = e; 
373  373  } 
374  374  if (cnt == 0) { 
375   if (min < 0) break; 
 375  if (min < 0) goto search_end; 
376  376  cnt = _block_size; 
377  377  } 
378  378  } 
379   if (min == 0  cnt > 0) { 
380   for (e = 0; e < _next_arc; ++e) { 
381   c = _state[e] * (_cost[e] + _pi[_source[e]]  _pi[_target[e]]); 
382   if (c < min) { 
383   min = c; 
384   min_arc = e; 
385   } 
386   if (cnt == 0) { 
387   if (min < 0) break; 
388   cnt = _block_size; 
389   } 
 379  for (e = 0; e < _next_arc; ++e) { 
 380  c = _state[e] * (_cost[e] + _pi[_source[e]]  _pi[_target[e]]); 
 381  if (c < min) { 
 382  min = c; 
 383  _in_arc = e; 
 384  } 
 385  if (cnt == 0) { 
 386  if (min < 0) goto search_end; 
 387  cnt = _block_size; 
390  388  } 
391  389  } 
392  390  if (min >= 0) return false; 
393   _in_arc = min_arc; 
 391  
 392  search_end: 
394  393  _next_arc = e; 
395  394  return true; 
396  395  } 
… 
… 

428  427  _next_arc(0) 
429  428  { 
430  429  // The main parameters of the pivot rule 
431   const double LIST_LENGTH_FACTOR = 1.0; 
 430  const double LIST_LENGTH_FACTOR = 0.25; 
432  431  const int MIN_LIST_LENGTH = 10; 
433  432  const double MINOR_LIMIT_FACTOR = 0.1; 
434  433  const int MIN_MINOR_LIMIT = 3; 
… 
… 

445  444  /// Find next entering arc 
446  445  bool findEnteringArc() { 
447  446  Cost min, c; 
448   int e, min_arc = _next_arc; 
 447  int e; 
449  448  if (_curr_length > 0 && _minor_count < _minor_limit) { 
450  449  // Minor iteration: select the best eligible arc from the 
451  450  // current candidate list 
… 
… 

456  455  c = _state[e] * (_cost[e] + _pi[_source[e]]  _pi[_target[e]]); 
457  456  if (c < min) { 
458  457  min = c; 
459   min_arc = e; 
 458  _in_arc = e; 
460  459  } 
461   if (c >= 0) { 
 460  else if (c >= 0) { 
462  461  _candidates[i] = _candidates[_curr_length]; 
463  462  } 
464  463  } 
465   if (min < 0) { 
466   _in_arc = min_arc; 
467   return true; 
468   } 
 464  if (min < 0) return true; 
469  465  } 
470  466  
471  467  // Major iteration: build a new candidate list 
… 
… 

477  473  _candidates[_curr_length++] = e; 
478  474  if (c < min) { 
479  475  min = c; 
480   min_arc = e; 
 476  _in_arc = e; 
481  477  } 
482   if (_curr_length == _list_length) break; 
 478  if (_curr_length == _list_length) goto search_end; 
483  479  } 
484  480  } 
485   if (_curr_length < _list_length) { 
486   for (e = 0; e < _next_arc; ++e) { 
487   c = _state[e] * (_cost[e] + _pi[_source[e]]  _pi[_target[e]]); 
488   if (c < 0) { 
489   _candidates[_curr_length++] = e; 
490   if (c < min) { 
491   min = c; 
492   min_arc = e; 
493   } 
494   if (_curr_length == _list_length) break; 
 481  for (e = 0; e < _next_arc; ++e) { 
 482  c = _state[e] * (_cost[e] + _pi[_source[e]]  _pi[_target[e]]); 
 483  if (c < 0) { 
 484  _candidates[_curr_length++] = e; 
 485  if (c < min) { 
 486  min = c; 
 487  _in_arc = e; 
495  488  } 
 489  if (_curr_length == _list_length) goto search_end; 
496  490  } 
497  491  } 
498  492  if (_curr_length == 0) return false; 
 493  
 494  search_end: 
499  495  _minor_count = 1; 
500   _in_arc = min_arc; 
501  496  _next_arc = e; 
502  497  return true; 
503  498  } 
… 
… 

549  544  _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost) 
550  545  { 
551  546  // The main parameters of the pivot rule 
552   const double BLOCK_SIZE_FACTOR = 1.5; 
 547  const double BLOCK_SIZE_FACTOR = 1.0; 
553  548  const int MIN_BLOCK_SIZE = 10; 
554  549  const double HEAD_LENGTH_FACTOR = 0.1; 
555  550  const int MIN_HEAD_LENGTH = 3; 
… 
… 

578  573  
579  574  // Extend the list 
580  575  int cnt = _block_size; 
581   int last_arc = 0; 
582  576  int limit = _head_length; 
583  577  
584   for (int e = _next_arc; e < _search_arc_num; ++e) { 
 578  for (e = _next_arc; e < _search_arc_num; ++e) { 
585  579  _cand_cost[e] = _state[e] * 
586  580  (_cost[e] + _pi[_source[e]]  _pi[_target[e]]); 
587  581  if (_cand_cost[e] < 0) { 
588  582  _candidates[_curr_length++] = e; 
589   last_arc = e; 
590  583  } 
591  584  if (cnt == 0) { 
592   if (_curr_length > limit) break; 
 585  if (_curr_length > limit) goto search_end; 
593  586  limit = 0; 
594  587  cnt = _block_size; 
595  588  } 
596  589  } 
597   if (_curr_length <= limit) { 
598   for (int e = 0; e < _next_arc; ++e) { 
599   _cand_cost[e] = _state[e] * 
600   (_cost[e] + _pi[_source[e]]  _pi[_target[e]]); 
601   if (_cand_cost[e] < 0) { 
602   _candidates[_curr_length++] = e; 
603   last_arc = e; 
604   } 
605   if (cnt == 0) { 
606   if (_curr_length > limit) break; 
607   limit = 0; 
608   cnt = _block_size; 
609   } 
 590  for (e = 0; e < _next_arc; ++e) { 
 591  _cand_cost[e] = _state[e] * 
 592  (_cost[e] + _pi[_source[e]]  _pi[_target[e]]); 
 593  if (_cand_cost[e] < 0) { 
 594  _candidates[_curr_length++] = e; 
 595  } 
 596  if (cnt == 0) { 
 597  if (_curr_length > limit) goto search_end; 
 598  limit = 0; 
 599  cnt = _block_size; 
610  600  } 
611  601  } 
612  602  if (_curr_length == 0) return false; 
613   _next_arc = last_arc + 1; 
 603  
 604  search_end: 
614  605  
615  606  // Make heap of the candidate list (approximating a partial sort) 
616  607  make_heap( _candidates.begin(), _candidates.begin() + _curr_length, 
… 
… 

618  609  
619  610  // Pop the first element of the heap 
620  611  _in_arc = _candidates[0]; 
 612  _next_arc = e; 
621  613  pop_heap( _candidates.begin(), _candidates.begin() + _curr_length, 
622  614  _sort_func ); 
623  615  _curr_length = std::min(_head_length, _curr_length  1); 