gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Small improvements in NS pivot rules (#298)
0 1 0
default
1 file changed with 26 insertions and 34 deletions:
↑ Collapse diff ↑
Show white space 8 line context
... ...
@@ -363,35 +363,34 @@
363 363
      // Find next entering arc
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 379
          for (e = 0; e < _next_arc; ++e) {
381 380
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
382 381
            if (c < min) {
383 382
              min = c;
384
              min_arc = e;
383
            _in_arc = e;
385 384
            }
386 385
            if (--cnt == 0) {
387
              if (min < 0) break;
386
            if (min < 0) goto search_end;
388 387
              cnt = _block_size;
389 388
            }
390 389
          }
391
        }
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
      }
397 396

	
... ...
@@ -427,9 +426,9 @@
427 426
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
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;
435 434

	
... ...
@@ -444,9 +443,9 @@
444 443

	
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
452 451
          ++_minor_count;
... ...
@@ -455,18 +454,15 @@
455 454
            e = _candidates[i];
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
472 468
        min = 0;
... ...
@@ -476,29 +472,28 @@
476 472
          if (c < 0) {
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 481
          for (e = 0; e < _next_arc; ++e) {
487 482
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
488 483
            if (c < 0) {
489 484
              _candidates[_curr_length++] = e;
490 485
              if (c < min) {
491 486
                min = c;
492
                min_arc = e;
487
              _in_arc = e;
493 488
              }
494
              if (_curr_length == _list_length) break;
495
            }
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
      }
504 499

	
... ...
@@ -548,9 +543,9 @@
548 543
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
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;
556 551

	
... ...
@@ -577,48 +572,45 @@
577 572
        }
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) {
590
        for (e = 0; e < _next_arc; ++e) {
599 591
            _cand_cost[e] = _state[e] *
600 592
              (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
601 593
            if (_cand_cost[e] < 0) {
602 594
              _candidates[_curr_length++] = e;
603
              last_arc = e;
604 595
            }
605 596
            if (--cnt == 0) {
606
              if (_curr_length > limit) break;
597
            if (_curr_length > limit) goto search_end;
607 598
              limit = 0;
608 599
              cnt = _block_size;
609 600
            }
610 601
          }
611
        }
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,
617 608
                   _sort_func );
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);
624 616
        return true;
0 comments (0 inline)