Changes in / [731:0977046c60d2:726:3fc2a801c39e] in lemon-main
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/network_simplex.h
r730 r663 162 162 TEMPLATE_DIGRAPH_TYPEDEFS(GR); 163 163 164 typedef std::vector<Arc> ArcVector; 165 typedef std::vector<Node> NodeVector; 164 166 typedef std::vector<int> IntVector; 165 167 typedef std::vector<bool> BoolVector; … … 363 365 Cost c, min = 0; 364 366 int cnt = _block_size; 365 int e ;367 int e, min_arc = _next_arc; 366 368 for (e = _next_arc; e < _search_arc_num; ++e) { 367 369 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 368 370 if (c < min) { 369 371 min = c; 370 _in_arc = e;372 min_arc = e; 371 373 } 372 374 if (--cnt == 0) { 373 if (min < 0) goto search_end;375 if (min < 0) break; 374 376 cnt = _block_size; 375 377 } 376 378 } 377 for (e = 0; e < _next_arc; ++e) { 378 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 379 if (c < min) { 380 min = c; 381 _in_arc = e; 382 } 383 if (--cnt == 0) { 384 if (min < 0) goto search_end; 385 cnt = _block_size; 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 } 386 390 } 387 391 } 388 392 if (min >= 0) return false; 389 390 search_end: 393 _in_arc = min_arc; 391 394 _next_arc = e; 392 395 return true; … … 426 429 { 427 430 // The main parameters of the pivot rule 428 const double LIST_LENGTH_FACTOR = 0.25;431 const double LIST_LENGTH_FACTOR = 1.0; 429 432 const int MIN_LIST_LENGTH = 10; 430 433 const double MINOR_LIMIT_FACTOR = 0.1; … … 443 446 bool findEnteringArc() { 444 447 Cost min, c; 445 int e ;448 int e, min_arc = _next_arc; 446 449 if (_curr_length > 0 && _minor_count < _minor_limit) { 447 450 // Minor iteration: select the best eligible arc from the … … 454 457 if (c < min) { 455 458 min = c; 456 _in_arc = e;459 min_arc = e; 457 460 } 458 elseif (c >= 0) {461 if (c >= 0) { 459 462 _candidates[i--] = _candidates[--_curr_length]; 460 463 } 461 464 } 462 if (min < 0) return true; 465 if (min < 0) { 466 _in_arc = min_arc; 467 return true; 468 } 463 469 } 464 470 … … 472 478 if (c < min) { 473 479 min = c; 474 _in_arc = e;480 min_arc = e; 475 481 } 476 if (_curr_length == _list_length) goto search_end; 477 } 478 } 479 for (e = 0; e < _next_arc; ++e) { 480 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 481 if (c < 0) { 482 _candidates[_curr_length++] = e; 483 if (c < min) { 484 min = c; 485 _in_arc = e; 482 if (_curr_length == _list_length) break; 483 } 484 } 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; 486 495 } 487 if (_curr_length == _list_length) goto search_end;488 496 } 489 497 } 490 498 if (_curr_length == 0) return false; 491 492 search_end:493 499 _minor_count = 1; 500 _in_arc = min_arc; 494 501 _next_arc = e; 495 502 return true; … … 543 550 { 544 551 // The main parameters of the pivot rule 545 const double BLOCK_SIZE_FACTOR = 1. 0;552 const double BLOCK_SIZE_FACTOR = 1.5; 546 553 const int MIN_BLOCK_SIZE = 10; 547 554 const double HEAD_LENGTH_FACTOR = 0.1; … … 572 579 // Extend the list 573 580 int cnt = _block_size; 581 int last_arc = 0; 574 582 int limit = _head_length; 575 583 576 for ( e = _next_arc; e < _search_arc_num; ++e) {584 for (int e = _next_arc; e < _search_arc_num; ++e) { 577 585 _cand_cost[e] = _state[e] * 578 586 (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 579 587 if (_cand_cost[e] < 0) { 580 588 _candidates[_curr_length++] = e; 589 last_arc = e; 581 590 } 582 591 if (--cnt == 0) { 583 if (_curr_length > limit) goto search_end;592 if (_curr_length > limit) break; 584 593 limit = 0; 585 594 cnt = _block_size; 586 595 } 587 596 } 588 for (e = 0; e < _next_arc; ++e) { 589 _cand_cost[e] = _state[e] * 590 (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 591 if (_cand_cost[e] < 0) { 592 _candidates[_curr_length++] = e; 593 } 594 if (--cnt == 0) { 595 if (_curr_length > limit) goto search_end; 596 limit = 0; 597 cnt = _block_size; 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 } 598 610 } 599 611 } 600 612 if (_curr_length == 0) return false; 601 602 search_end: 613 _next_arc = last_arc + 1; 603 614 604 615 // Make heap of the candidate list (approximating a partial sort) … … 608 619 // Pop the first element of the heap 609 620 _in_arc = _candidates[0]; 610 _next_arc = e;611 621 pop_heap( _candidates.begin(), _candidates.begin() + _curr_length, 612 622 _sort_func ); … … 624 634 /// 625 635 /// \param graph The digraph the algorithm runs on. 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) : 636 NetworkSimplex(const GR& graph) : 631 637 _graph(graph), _node_id(graph), _arc_id(graph), 632 638 INF(std::numeric_limits<Value>::has_infinity ? … … 666 672 _state.resize(max_arc_num); 667 673 668 // Copy the graph 674 // Copy the graph (store the arcs in a mixed order) 669 675 int i = 0; 670 676 for (NodeIt n(_graph); n != INVALID; ++n, ++i) { 671 677 _node_id[n] = i; 672 678 } 673 if (arc_mixing) { 674 // Store the arcs in a mixed order 675 int k = std::max(int(std::sqrt(double(_arc_num))), 10); 676 int i = 0, j = 0; 677 for (ArcIt a(_graph); a != INVALID; ++a) { 678 _arc_id[a] = i; 679 _source[i] = _node_id[_graph.source(a)]; 680 _target[i] = _node_id[_graph.target(a)]; 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 } 679 int k = std::max(int(std::sqrt(double(_arc_num))), 10); 680 i = 0; 681 for (ArcIt a(_graph); a != INVALID; ++a) { 682 _arc_id[a] = i; 683 _source[i] = _node_id[_graph.source(a)]; 684 _target[i] = _node_id[_graph.target(a)]; 685 if ((i += k) >= _arc_num) i = (i % k) + 1; 691 686 } 692 687 693 // Reset parameters 694 reset(); 688 // Initialize maps 689 for (int i = 0; i != _node_num; ++i) { 690 _supply[i] = 0; 691 } 692 for (int i = 0; i != _arc_num; ++i) { 693 _lower[i] = 0; 694 _upper[i] = INF; 695 _cost[i] = 1; 696 } 697 _have_lower = false; 698 _stype = GEQ; 695 699 } 696 700 … … 765 769 /// If neither this function nor \ref stSupply() is used before 766 770 /// calling \ref run(), the supply of each node will be set to zero. 771 /// (It makes sense only if non-zero lower bounds are given.) 767 772 /// 768 773 /// \param map A node map storing the supply values. … … 785 790 /// If neither this function nor \ref supplyMap() is used before 786 791 /// calling \ref run(), the supply of each node will be set to zero. 792 /// (It makes sense only if non-zero lower bounds are given.) 787 793 /// 788 794 /// Using this function has the same effect as using \ref supplyMap()
Note: See TracChangeset
for help on using the changeset viewer.