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 24 line context
... ...
@@ -524,29 +524,31 @@
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

	
... ...
@@ -565,52 +567,83 @@
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 {
... ...
@@ -810,26 +843,26 @@
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
  }
... ...
@@ -872,25 +905,40 @@
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;
Ignore white space 24 line context
... ...
@@ -169,30 +169,36 @@
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
    };
0 comments (0 inline)