00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CoinHelperFunctions.hpp"
00012 #include "CouenneObject.hpp"
00013 #include "CouenneBranchingObject.hpp"
00014 #include "CouenneThreeWayBranchObj.hpp"
00015
00016 using namespace Ipopt;
00017 using namespace Couenne;
00018
00021 CouenneThreeWayBranchObj::CouenneThreeWayBranchObj (JnlstPtr jnlst,
00022 expression *brVar,
00023 CouNumber lcrop,
00024 CouNumber rcrop,
00025 int way
00026
00027 ):
00028 brVar_ (brVar),
00029 lcrop_ (lcrop),
00030 rcrop_ (rcrop),
00031 jnlst_ (jnlst) {
00032
00033 numberBranches_ = 3;
00034
00035
00036 firstBranch_ = (way == THREE_LEFT) ? 0 :
00037 (way == THREE_CENTER) ? 1 :
00038 (way == THREE_RIGHT) ? 2 : 0;
00039
00040 if (way == THREE_RAND) {
00041 CouNumber rnd = 3. * CoinDrand48 ();
00042 firstBranch_ = (rnd < 1.) ? 0 : (rnd < 2.) ? 1: 2;
00043 }
00044 }
00045
00046
00053 double CouenneThreeWayBranchObj::branch (OsiSolverInterface * solver) {
00054
00055
00056
00057
00058
00059 int way = 0;
00060
00061 switch (branchIndex_) {
00062
00063 case 0: way = firstBranch_; break;
00064 case 1: way = (firstBranch_ == 0) ? 1 : 0; break;
00065 case 2: way = (firstBranch_ == 2) ? 1 : 2; break;
00066 default: jnlst_->Printf(J_WARNING, J_BRANCHING,
00067 "Warning, branchIndex_ has a strange value (%d)\n", branchIndex_);
00068 }
00069
00070
00071
00072 int index = brVar_ -> Index ();
00073 bool integer = brVar_ -> isInteger ();
00074
00075 CouNumber
00076 l = solver -> getColLower () [index],
00077 u = solver -> getColUpper () [index];
00078
00079 if (lcrop_ < l) lcrop_ = l;
00080 if (rcrop_ > u) rcrop_ = u;
00081
00082 switch (--way) {
00083
00084 case -1: solver -> setColUpper (index, integer ? floor (lcrop_) : lcrop_); break;
00085 case 0: solver -> setColLower (index, integer ? ceil (lcrop_) : lcrop_);
00086 solver -> setColUpper (index, integer ? floor (rcrop_) : rcrop_); break;
00087 case 1: solver -> setColLower (index, integer ? ceil (rcrop_) : rcrop_); break;
00088 default: jnlst_->Printf(J_WARNING, J_BRANCHING, "Couenne: branching on nonsense way %d\n", way);
00089 }
00090
00091
00092
00093 if (jnlst_->ProduceOutput(J_DETAILED, J_BRANCHING)) {
00094 switch (way) {
00095 case -1: jnlst_->Printf(J_DETAILED, J_BRANCHING,
00096 "#3# Branch: x%d <= %g\n", index, lcrop_); break;
00097 case 0: jnlst_->Printf(J_DETAILED, J_BRANCHING,
00098 "#3# Branch: %g <= x%d <= %g\n", lcrop_, index, rcrop_); break;
00099 case 1: jnlst_->Printf(J_DETAILED, J_BRANCHING,
00100 "#3# Branch: x%d >= %g\n", index, rcrop_); break;
00101 default: jnlst_->Printf(J_DETAILED, J_BRANCHING, "Couenne: branching on nonsense way %d\n", way);
00102 }
00103 }
00104
00105 branchIndex_++;
00106
00107 return 0.;
00108 }