gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Fixing presolver and basis handling (#255)
0 2 0
default
2 files changed with 60 insertions and 6 deletions:
↑ Collapse diff ↑
Ignore white space 192 line context
... ...
@@ -440,261 +440,294 @@
440 440
        break;
441 441
      case GLP_LO:
442 442
      case GLP_DB:
443 443
      case GLP_FX:
444 444
        if (lo == up)
445 445
          glp_set_row_bnds(lp, i, GLP_FX, lo, up);
446 446
        else
447 447
          glp_set_row_bnds(lp, i, GLP_DB, lo, up);
448 448
        break;
449 449
      default:
450 450
        break;
451 451
      }
452 452
    }
453 453
  }
454 454

	
455 455
  GlpkBase::Value GlpkBase::_getRowUpperBound(int i) const {
456 456
    int b = glp_get_row_type(lp, i);
457 457
    switch (b) {
458 458
    case GLP_UP:
459 459
    case GLP_DB:
460 460
    case GLP_FX:
461 461
      return glp_get_row_ub(lp, i);
462 462
    default:
463 463
      return INF;
464 464
    }
465 465
  }
466 466

	
467 467
  void GlpkBase::_setObjCoeffs(ExprIterator b, ExprIterator e) {
468 468
    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
469 469
      glp_set_obj_coef(lp, i, 0.0);
470 470
    }
471 471
    for (ExprIterator it = b; it != e; ++it) {
472 472
      glp_set_obj_coef(lp, it->first, it->second);
473 473
    }
474 474
  }
475 475

	
476 476
  void GlpkBase::_getObjCoeffs(InsertIterator b) const {
477 477
    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
478 478
      Value val = glp_get_obj_coef(lp, i);
479 479
      if (val != 0.0) {
480 480
        *b = std::make_pair(i, val);
481 481
        ++b;
482 482
      }
483 483
    }
484 484
  }
485 485

	
486 486
  void GlpkBase::_setObjCoeff(int i, Value obj_coef) {
487 487
    //i = 0 means the constant term (shift)
488 488
    glp_set_obj_coef(lp, i, obj_coef);
489 489
  }
490 490

	
491 491
  GlpkBase::Value GlpkBase::_getObjCoeff(int i) const {
492 492
    //i = 0 means the constant term (shift)
493 493
    return glp_get_obj_coef(lp, i);
494 494
  }
495 495

	
496 496
  void GlpkBase::_setSense(GlpkBase::Sense sense) {
497 497
    switch (sense) {
498 498
    case MIN:
499 499
      glp_set_obj_dir(lp, GLP_MIN);
500 500
      break;
501 501
    case MAX:
502 502
      glp_set_obj_dir(lp, GLP_MAX);
503 503
      break;
504 504
    }
505 505
  }
506 506

	
507 507
  GlpkBase::Sense GlpkBase::_getSense() const {
508 508
    switch(glp_get_obj_dir(lp)) {
509 509
    case GLP_MIN:
510 510
      return MIN;
511 511
    case GLP_MAX:
512 512
      return MAX;
513 513
    default:
514 514
      LEMON_ASSERT(false, "Wrong sense");
515 515
      return GlpkBase::Sense();
516 516
    }
517 517
  }
518 518

	
519 519
  void GlpkBase::_clear() {
520 520
    glp_erase_prob(lp);
521 521
    rows.clear();
522 522
    cols.clear();
523 523
  }
524 524

	
525 525
  void GlpkBase::freeEnv() {
526 526
    glp_free_env();
527 527
  }
528 528

	
529 529
  GlpkBase::FreeEnvHelper GlpkBase::freeEnvHelper;
530 530

	
531 531
  // GlpkLp members
532 532

	
533 533
  GlpkLp::GlpkLp()
534 534
    : LpBase(), LpSolver(), GlpkBase() {
535 535
    messageLevel(MESSAGE_NO_OUTPUT);
536
    presolver(false);
536 537
  }
537 538

	
538 539
  GlpkLp::GlpkLp(const GlpkLp& other)
539 540
    : LpBase(other), LpSolver(other), GlpkBase(other) {
540 541
    messageLevel(MESSAGE_NO_OUTPUT);
542
    presolver(false);
541 543
  }
542 544

	
543 545
  GlpkLp* GlpkLp::newSolver() const { return new GlpkLp; }
544 546
  GlpkLp* GlpkLp::cloneSolver() const { return new GlpkLp(*this); }
545 547

	
546 548
  const char* GlpkLp::_solverName() const { return "GlpkLp"; }
547 549

	
548 550
  void GlpkLp::_clear_temporals() {
549 551
    _primal_ray.clear();
550 552
    _dual_ray.clear();
551 553
  }
552 554

	
553 555
  GlpkLp::SolveExitStatus GlpkLp::_solve() {
554 556
    return solvePrimal();
555 557
  }
556 558

	
557 559
  GlpkLp::SolveExitStatus GlpkLp::solvePrimal() {
558 560
    _clear_temporals();
559 561

	
560 562
    glp_smcp smcp;
561 563
    glp_init_smcp(&smcp);
562 564

	
563 565
    switch (_message_level) {
564 566
    case MESSAGE_NO_OUTPUT:
565 567
      smcp.msg_lev = GLP_MSG_OFF;
566 568
      break;
567 569
    case MESSAGE_ERROR_MESSAGE:
568 570
      smcp.msg_lev = GLP_MSG_ERR;
569 571
      break;
570 572
    case MESSAGE_NORMAL_OUTPUT:
571 573
      smcp.msg_lev = GLP_MSG_ON;
572 574
      break;
573 575
    case MESSAGE_FULL_OUTPUT:
574 576
      smcp.msg_lev = GLP_MSG_ALL;
575 577
      break;
576 578
    }
579
    smcp.presolve = _presolve;
577 580

	
578
    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
581
    // If the basis is not valid we get an error return value.
582
    // In this case we can try to create a new basis.
583
    switch (glp_simplex(lp, &smcp)) {
584
    case 0:
585
      break;
586
    case GLP_EBADB:
587
    case GLP_ESING:
588
    case GLP_ECOND:
589
      lpx_set_int_parm(lp, LPX_K_MSGLEV, smcp.msg_lev);
590
      glp_adv_basis(lp, 0);
591
      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
592
      break;
593
    default:
594
      return UNSOLVED;
595
    }
596

	
579 597
    return SOLVED;
580 598
  }
581 599

	
582 600
  GlpkLp::SolveExitStatus GlpkLp::solveDual() {
583 601
    _clear_temporals();
584 602

	
585 603
    glp_smcp smcp;
586 604
    glp_init_smcp(&smcp);
587 605

	
588 606
    switch (_message_level) {
589 607
    case MESSAGE_NO_OUTPUT:
590 608
      smcp.msg_lev = GLP_MSG_OFF;
591 609
      break;
592 610
    case MESSAGE_ERROR_MESSAGE:
593 611
      smcp.msg_lev = GLP_MSG_ERR;
594 612
      break;
595 613
    case MESSAGE_NORMAL_OUTPUT:
596 614
      smcp.msg_lev = GLP_MSG_ON;
597 615
      break;
598 616
    case MESSAGE_FULL_OUTPUT:
599 617
      smcp.msg_lev = GLP_MSG_ALL;
600 618
      break;
601 619
    }
602 620
    smcp.meth = GLP_DUAL;
621
    smcp.presolve = _presolve;
603 622

	
604
    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
623
    // If the basis is not valid we get an error return value.
624
    // In this case we can try to create a new basis.
625
    switch (glp_simplex(lp, &smcp)) {
626
    case 0:
627
      break;
628
    case GLP_EBADB:
629
    case GLP_ESING:
630
    case GLP_ECOND:
631
      lpx_set_int_parm(lp, LPX_K_MSGLEV, smcp.msg_lev);
632
      glp_adv_basis(lp, 0);
633
      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
634
      break;
635
    default:
636
      return UNSOLVED;
637
    }
605 638
    return SOLVED;
606 639
  }
607 640

	
608 641
  GlpkLp::Value GlpkLp::_getPrimal(int i) const {
609 642
    return glp_get_col_prim(lp, i);
610 643
  }
611 644

	
612 645
  GlpkLp::Value GlpkLp::_getDual(int i) const {
613 646
    return glp_get_row_dual(lp, i);
614 647
  }
615 648

	
616 649
  GlpkLp::Value GlpkLp::_getPrimalValue() const {
617 650
    return glp_get_obj_val(lp);
618 651
  }
619 652

	
620 653
  GlpkLp::VarStatus GlpkLp::_getColStatus(int i) const {
621 654
    switch (glp_get_col_stat(lp, i)) {
622 655
    case GLP_BS:
623 656
      return BASIC;
624 657
    case GLP_UP:
625 658
      return UPPER;
626 659
    case GLP_LO:
627 660
      return LOWER;
628 661
    case GLP_NF:
629 662
      return FREE;
630 663
    case GLP_NS:
631 664
      return FIXED;
632 665
    default:
633 666
      LEMON_ASSERT(false, "Wrong column status");
634 667
      return GlpkLp::VarStatus();
635 668
    }
636 669
  }
637 670

	
638 671
  GlpkLp::VarStatus GlpkLp::_getRowStatus(int i) const {
639 672
    switch (glp_get_row_stat(lp, i)) {
640 673
    case GLP_BS:
641 674
      return BASIC;
642 675
    case GLP_UP:
643 676
      return UPPER;
644 677
    case GLP_LO:
645 678
      return LOWER;
646 679
    case GLP_NF:
647 680
      return FREE;
648 681
    case GLP_NS:
649 682
      return FIXED;
650 683
    default:
651 684
      LEMON_ASSERT(false, "Wrong row status");
652 685
      return GlpkLp::VarStatus();
653 686
    }
654 687
  }
655 688

	
656 689
  GlpkLp::Value GlpkLp::_getPrimalRay(int i) const {
657 690
    if (_primal_ray.empty()) {
658 691
      int row_num = glp_get_num_rows(lp);
659 692
      int col_num = glp_get_num_cols(lp);
660 693

	
661 694
      _primal_ray.resize(col_num + 1, 0.0);
662 695

	
663 696
      int index = glp_get_unbnd_ray(lp);
664 697
      if (index != 0) {
665 698
        // The primal ray is found in primal simplex second phase
666 699
        LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) :
667 700
                      glp_get_col_stat(lp, index - row_num)) != GLP_BS,
668 701
                     "Wrong primal ray");
669 702

	
670 703
        bool negate = glp_get_obj_dir(lp) == GLP_MAX;
671 704

	
672 705
        if (index > row_num) {
673 706
          _primal_ray[index - row_num] = 1.0;
674 707
          if (glp_get_col_dual(lp, index - row_num) > 0) {
675 708
            negate = !negate;
676 709
          }
677 710
        } else {
678 711
          if (glp_get_row_dual(lp, index) > 0) {
679 712
            negate = !negate;
680 713
          }
681 714
        }
682 715

	
683 716
        std::vector<int> ray_indexes(row_num + 1);
684 717
        std::vector<Value> ray_values(row_num + 1);
685 718
        int ray_length = glp_eval_tab_col(lp, index, &ray_indexes.front(),
686 719
                                          &ray_values.front());
687 720

	
688 721
        for (int i = 1; i <= ray_length; ++i) {
689 722
          if (ray_indexes[i] > row_num) {
690 723
            _primal_ray[ray_indexes[i] - row_num] = ray_values[i];
691 724
          }
692 725
        }
693 726

	
694 727
        if (negate) {
695 728
          for (int i = 1; i <= col_num; ++i) {
696 729
            _primal_ray[i] = - _primal_ray[i];
697 730
          }
698 731
        }
699 732
      } else {
700 733
        for (int i = 1; i <= col_num; ++i) {
... ...
@@ -726,233 +759,248 @@
726 759
          idx = glp_get_col_bind(lp, index - row_num);
727 760
          if (glp_get_col_prim(lp, index - row_num) >
728 761
              glp_get_col_ub(lp, index - row_num)) {
729 762
            negate = true;
730 763
          }
731 764
        } else {
732 765
          idx = glp_get_row_bind(lp, index);
733 766
          if (glp_get_row_prim(lp, index) > glp_get_row_ub(lp, index)) {
734 767
            negate = true;
735 768
          }
736 769
        }
737 770

	
738 771
        _dual_ray[idx] = negate ?  - 1.0 : 1.0;
739 772

	
740 773
        glp_btran(lp, &_dual_ray.front());
741 774
      } else {
742 775
        double eps = 1e-7;
743 776
        // The dual ray is found in primal simplex first phase
744 777
        // We assume that the glpk minimizes the slack to get feasible solution
745 778
        for (int i = 1; i <= row_num; ++i) {
746 779
          int index = glp_get_bhead(lp, i);
747 780
          if (index <= row_num) {
748 781
            double res = glp_get_row_prim(lp, index);
749 782
            if (res > glp_get_row_ub(lp, index) + eps) {
750 783
              _dual_ray[i] = -1;
751 784
            } else if (res < glp_get_row_lb(lp, index) - eps) {
752 785
              _dual_ray[i] = 1;
753 786
            } else {
754 787
              _dual_ray[i] = 0;
755 788
            }
756 789
            _dual_ray[i] *= glp_get_rii(lp, index);
757 790
          } else {
758 791
            double res = glp_get_col_prim(lp, index - row_num);
759 792
            if (res > glp_get_col_ub(lp, index - row_num) + eps) {
760 793
              _dual_ray[i] = -1;
761 794
            } else if (res < glp_get_col_lb(lp, index - row_num) - eps) {
762 795
              _dual_ray[i] = 1;
763 796
            } else {
764 797
              _dual_ray[i] = 0;
765 798
            }
766 799
            _dual_ray[i] /= glp_get_sjj(lp, index - row_num);
767 800
          }
768 801
        }
769 802

	
770 803
        glp_btran(lp, &_dual_ray.front());
771 804

	
772 805
        for (int i = 1; i <= row_num; ++i) {
773 806
          _dual_ray[i] /= glp_get_rii(lp, i);
774 807
        }
775 808
      }
776 809
    }
777 810
    return _dual_ray[i];
778 811
  }
779 812

	
780 813
  GlpkLp::ProblemType GlpkLp::_getPrimalType() const {
781 814
    if (glp_get_status(lp) == GLP_OPT)
782 815
      return OPTIMAL;
783 816
    switch (glp_get_prim_stat(lp)) {
784 817
    case GLP_UNDEF:
785 818
      return UNDEFINED;
786 819
    case GLP_FEAS:
787 820
    case GLP_INFEAS:
788 821
      if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
789 822
        return UNBOUNDED;
790 823
      } else {
791 824
        return UNDEFINED;
792 825
      }
793 826
    case GLP_NOFEAS:
794 827
      return INFEASIBLE;
795 828
    default:
796 829
      LEMON_ASSERT(false, "Wrong primal type");
797 830
      return  GlpkLp::ProblemType();
798 831
    }
799 832
  }
800 833

	
801 834
  GlpkLp::ProblemType GlpkLp::_getDualType() const {
802 835
    if (glp_get_status(lp) == GLP_OPT)
803 836
      return OPTIMAL;
804 837
    switch (glp_get_dual_stat(lp)) {
805 838
    case GLP_UNDEF:
806 839
      return UNDEFINED;
807 840
    case GLP_FEAS:
808 841
    case GLP_INFEAS:
809 842
      if (glp_get_prim_stat(lp) == GLP_NOFEAS) {
810 843
        return UNBOUNDED;
811 844
      } else {
812 845
        return UNDEFINED;
813 846
      }
814 847
    case GLP_NOFEAS:
815 848
      return INFEASIBLE;
816 849
    default:
817 850
      LEMON_ASSERT(false, "Wrong primal type");
818 851
      return  GlpkLp::ProblemType();
819 852
    }
820 853
  }
821 854

	
822
  void GlpkLp::presolver(bool b) {
823
    lpx_set_int_parm(lp, LPX_K_PRESOL, b ? 1 : 0);
855
  void GlpkLp::presolver(bool presolve) {
856
    _presolve = presolve;
824 857
  }
825 858

	
826 859
  void GlpkLp::messageLevel(MessageLevel m) {
827 860
    _message_level = m;
828 861
  }
829 862

	
830 863
  // GlpkMip members
831 864

	
832 865
  GlpkMip::GlpkMip()
833 866
    : LpBase(), MipSolver(), GlpkBase() {
834 867
    messageLevel(MESSAGE_NO_OUTPUT);
835 868
  }
836 869

	
837 870
  GlpkMip::GlpkMip(const GlpkMip& other)
838 871
    : LpBase(), MipSolver(), GlpkBase(other) {
839 872
    messageLevel(MESSAGE_NO_OUTPUT);
840 873
  }
841 874

	
842 875
  void GlpkMip::_setColType(int i, GlpkMip::ColTypes col_type) {
843 876
    switch (col_type) {
844 877
    case INTEGER:
845 878
      glp_set_col_kind(lp, i, GLP_IV);
846 879
      break;
847 880
    case REAL:
848 881
      glp_set_col_kind(lp, i, GLP_CV);
849 882
      break;
850 883
    }
851 884
  }
852 885

	
853 886
  GlpkMip::ColTypes GlpkMip::_getColType(int i) const {
854 887
    switch (glp_get_col_kind(lp, i)) {
855 888
    case GLP_IV:
856 889
    case GLP_BV:
857 890
      return INTEGER;
858 891
    default:
859 892
      return REAL;
860 893
    }
861 894

	
862 895
  }
863 896

	
864 897
  GlpkMip::SolveExitStatus GlpkMip::_solve() {
865 898
    glp_smcp smcp;
866 899
    glp_init_smcp(&smcp);
867 900

	
868 901
    switch (_message_level) {
869 902
    case MESSAGE_NO_OUTPUT:
870 903
      smcp.msg_lev = GLP_MSG_OFF;
871 904
      break;
872 905
    case MESSAGE_ERROR_MESSAGE:
873 906
      smcp.msg_lev = GLP_MSG_ERR;
874 907
      break;
875 908
    case MESSAGE_NORMAL_OUTPUT:
876 909
      smcp.msg_lev = GLP_MSG_ON;
877 910
      break;
878 911
    case MESSAGE_FULL_OUTPUT:
879 912
      smcp.msg_lev = GLP_MSG_ALL;
880 913
      break;
881 914
    }
882 915
    smcp.meth = GLP_DUAL;
883 916

	
884
    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
917
    // If the basis is not valid we get an error return value.
918
    // In this case we can try to create a new basis.
919
    switch (glp_simplex(lp, &smcp)) {
920
    case 0:
921
      break;
922
    case GLP_EBADB:
923
    case GLP_ESING:
924
    case GLP_ECOND:
925
      lpx_set_int_parm(lp, LPX_K_MSGLEV, smcp.msg_lev);
926
      glp_adv_basis(lp, 0);
927
      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
928
      break;
929
    default:
930
      return UNSOLVED;
931
    }
932

	
885 933
    if (glp_get_status(lp) != GLP_OPT) return SOLVED;
886 934

	
887 935
    glp_iocp iocp;
888 936
    glp_init_iocp(&iocp);
889 937

	
890 938
    switch (_message_level) {
891 939
    case MESSAGE_NO_OUTPUT:
892 940
      iocp.msg_lev = GLP_MSG_OFF;
893 941
      break;
894 942
    case MESSAGE_ERROR_MESSAGE:
895 943
      iocp.msg_lev = GLP_MSG_ERR;
896 944
      break;
897 945
    case MESSAGE_NORMAL_OUTPUT:
898 946
      iocp.msg_lev = GLP_MSG_ON;
899 947
      break;
900 948
    case MESSAGE_FULL_OUTPUT:
901 949
      iocp.msg_lev = GLP_MSG_ALL;
902 950
      break;
903 951
    }
904 952

	
905 953
    if (glp_intopt(lp, &iocp) != 0) return UNSOLVED;
906 954
    return SOLVED;
907 955
  }
908 956

	
909 957

	
910 958
  GlpkMip::ProblemType GlpkMip::_getType() const {
911 959
    switch (glp_get_status(lp)) {
912 960
    case GLP_OPT:
913 961
      switch (glp_mip_status(lp)) {
914 962
      case GLP_UNDEF:
915 963
        return UNDEFINED;
916 964
      case GLP_NOFEAS:
917 965
        return INFEASIBLE;
918 966
      case GLP_FEAS:
919 967
        return FEASIBLE;
920 968
      case GLP_OPT:
921 969
        return OPTIMAL;
922 970
      default:
923 971
        LEMON_ASSERT(false, "Wrong problem type.");
924 972
        return GlpkMip::ProblemType();
925 973
      }
926 974
    case GLP_NOFEAS:
927 975
      return INFEASIBLE;
928 976
    case GLP_INFEAS:
929 977
    case GLP_FEAS:
930 978
      if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
931 979
        return UNBOUNDED;
932 980
      } else {
933 981
        return UNDEFINED;
934 982
      }
935 983
    default:
936 984
      LEMON_ASSERT(false, "Wrong problem type.");
937 985
      return GlpkMip::ProblemType();
938 986
    }
939 987
  }
940 988

	
941 989
  GlpkMip::Value GlpkMip::_getSol(int i) const {
942 990
    return glp_mip_col_val(lp, i);
943 991
  }
944 992

	
945 993
  GlpkMip::Value GlpkMip::_getSolValue() const {
946 994
    return glp_mip_obj_val(lp);
947 995
  }
948 996

	
949 997
  GlpkMip* GlpkMip::newSolver() const { return new GlpkMip; }
950 998
  GlpkMip* GlpkMip::cloneSolver() const {return new GlpkMip(*this); }
951 999

	
952 1000
  const char* GlpkMip::_solverName() const { return "GlpkMip"; }
953 1001

	
954 1002
  void GlpkMip::messageLevel(MessageLevel m) {
955 1003
    _message_level = m;
956 1004
  }
957 1005

	
958 1006
} //END OF NAMESPACE LEMON
Ignore white space 6 line context
... ...
@@ -85,187 +85,193 @@
85 85

	
86 86
    virtual void _setRowLowerBound(int i, Value value);
87 87
    virtual Value _getRowLowerBound(int i) const;
88 88

	
89 89
    virtual void _setRowUpperBound(int i, Value value);
90 90
    virtual Value _getRowUpperBound(int i) const;
91 91

	
92 92
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
93 93
    virtual void _getObjCoeffs(InsertIterator b) const;
94 94

	
95 95
    virtual void _setObjCoeff(int i, Value obj_coef);
96 96
    virtual Value _getObjCoeff(int i) const;
97 97

	
98 98
    virtual void _setSense(Sense);
99 99
    virtual Sense _getSense() const;
100 100

	
101 101
    virtual void _clear();
102 102

	
103 103
  private:
104 104

	
105 105
    static void freeEnv();
106 106

	
107 107
    struct FreeEnvHelper {
108 108
      ~FreeEnvHelper() {
109 109
        freeEnv();
110 110
      }
111 111
    };
112 112
    
113 113
    static FreeEnvHelper freeEnvHelper;
114 114
    
115 115
  public:
116 116

	
117 117
    ///Pointer to the underlying GLPK data structure.
118 118
    LPX *lpx() {return lp;}
119 119
    ///Const pointer to the underlying GLPK data structure.
120 120
    const LPX *lpx() const {return lp;}
121 121

	
122 122
    ///Returns the constraint identifier understood by GLPK.
123 123
    int lpxRow(Row r) const { return rows(id(r)); }
124 124

	
125 125
    ///Returns the variable identifier understood by GLPK.
126 126
    int lpxCol(Col c) const { return cols(id(c)); }
127 127

	
128 128
  };
129 129

	
130 130
  /// \brief Interface for the GLPK LP solver
131 131
  ///
132 132
  /// This class implements an interface for the GLPK LP solver.
133 133
  ///\ingroup lp_group
134 134
  class GlpkLp : public LpSolver, public GlpkBase {
135 135
  public:
136 136

	
137 137
    ///\e
138 138
    GlpkLp();
139 139
    ///\e
140 140
    GlpkLp(const GlpkLp&);
141 141

	
142 142
    ///\e
143 143
    virtual GlpkLp* cloneSolver() const;
144 144
    ///\e
145 145
    virtual GlpkLp* newSolver() const;
146 146

	
147 147
  private:
148 148

	
149 149
    mutable std::vector<double> _primal_ray;
150 150
    mutable std::vector<double> _dual_ray;
151 151

	
152 152
    void _clear_temporals();
153 153

	
154 154
  protected:
155 155

	
156 156
    virtual const char* _solverName() const;
157 157

	
158 158
    virtual SolveExitStatus _solve();
159 159
    virtual Value _getPrimal(int i) const;
160 160
    virtual Value _getDual(int i) const;
161 161

	
162 162
    virtual Value _getPrimalValue() const;
163 163

	
164 164
    virtual VarStatus _getColStatus(int i) const;
165 165
    virtual VarStatus _getRowStatus(int i) const;
166 166

	
167 167
    virtual Value _getPrimalRay(int i) const;
168 168
    virtual Value _getDualRay(int i) const;
169 169

	
170 170
    virtual ProblemType _getPrimalType() const;
171 171
    virtual ProblemType _getDualType() const;
172 172

	
173 173
  public:
174 174

	
175 175
    ///Solve with primal simplex
176 176
    SolveExitStatus solvePrimal();
177 177

	
178 178
    ///Solve with dual simplex
179 179
    SolveExitStatus solveDual();
180 180

	
181
  private:
182

	
183
    bool _presolve;
184

	
185
  public:
186

	
181 187
    ///Turns on or off the presolver
182 188

	
183 189
    ///Turns on (\c b is \c true) or off (\c b is \c false) the presolver
184 190
    ///
185 191
    ///The presolver is off by default.
186
    void presolver(bool b);
192
    void presolver(bool presolve);
187 193

	
188 194
    ///Enum for \c messageLevel() parameter
189 195
    enum MessageLevel {
190 196
      /// no output (default value)
191 197
      MESSAGE_NO_OUTPUT = 0,
192 198
      /// error messages only
193 199
      MESSAGE_ERROR_MESSAGE = 1,
194 200
      /// normal output
195 201
      MESSAGE_NORMAL_OUTPUT = 2,
196 202
      /// full output (includes informational messages)
197 203
      MESSAGE_FULL_OUTPUT = 3
198 204
    };
199 205

	
200 206
  private:
201 207

	
202 208
    MessageLevel _message_level;
203 209

	
204 210
  public:
205 211

	
206 212
    ///Set the verbosity of the messages
207 213

	
208 214
    ///Set the verbosity of the messages
209 215
    ///
210 216
    ///\param m is the level of the messages output by the solver routines.
211 217
    void messageLevel(MessageLevel m);
212 218
  };
213 219

	
214 220
  /// \brief Interface for the GLPK MIP solver
215 221
  ///
216 222
  /// This class implements an interface for the GLPK MIP solver.
217 223
  ///\ingroup lp_group
218 224
  class GlpkMip : public MipSolver, public GlpkBase {
219 225
  public:
220 226

	
221 227
    ///\e
222 228
    GlpkMip();
223 229
    ///\e
224 230
    GlpkMip(const GlpkMip&);
225 231

	
226 232
    virtual GlpkMip* cloneSolver() const;
227 233
    virtual GlpkMip* newSolver() const;
228 234

	
229 235
  protected:
230 236

	
231 237
    virtual const char* _solverName() const;
232 238

	
233 239
    virtual ColTypes _getColType(int col) const;
234 240
    virtual void _setColType(int col, ColTypes col_type);
235 241

	
236 242
    virtual SolveExitStatus _solve();
237 243
    virtual ProblemType _getType() const;
238 244
    virtual Value _getSol(int i) const;
239 245
    virtual Value _getSolValue() const;
240 246

	
241 247
    ///Enum for \c messageLevel() parameter
242 248
    enum MessageLevel {
243 249
      /// no output (default value)
244 250
      MESSAGE_NO_OUTPUT = 0,
245 251
      /// error messages only
246 252
      MESSAGE_ERROR_MESSAGE = 1,
247 253
      /// normal output
248 254
      MESSAGE_NORMAL_OUTPUT = 2,
249 255
      /// full output (includes informational messages)
250 256
      MESSAGE_FULL_OUTPUT = 3
251 257
    };
252 258

	
253 259
  private:
254 260

	
255 261
    MessageLevel _message_level;
256 262

	
257 263
  public:
258 264

	
259 265
    ///Set the verbosity of the messages
260 266

	
261 267
    ///Set the verbosity of the messages
262 268
    ///
263 269
    ///\param m is the level of the messages output by the solver routines.
264 270
    void messageLevel(MessageLevel m);
265 271
  };
266 272

	
267 273

	
268 274
} //END OF NAMESPACE LEMON
269 275

	
270 276
#endif //LEMON_GLPK_H
271 277

	
0 comments (0 inline)