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 48 line context
... ...
@@ -512,117 +512,150 @@
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:
... ...
@@ -798,50 +831,50 @@
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:
... ...
@@ -860,49 +893,64 @@
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

	
Ignore white space 48 line context
... ...
@@ -157,54 +157,60 @@
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.
0 comments (0 inline)