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