/home/coin/SVN-release/OS-2.4.1/Couenne/src/branch/CouenneThreeWayBranchObj.cpp

Go to the documentation of this file.
00001 /* $Id: CouenneThreeWayBranchObj.cpp 694 2011-06-18 20:13:17Z stefan $
00002  *
00003  * Name:    CouenneThreeWayBranchObj.cpp
00004  * Authors: Pietro Belotti, Carnegie Mellon University
00005  * Purpose: Branching object for auxiliary variables
00006  *
00007  * (C) Carnegie-Mellon University, 2006-10.
00008  * This file is licensed under the Eclipse Public License (EPL)
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                                                     //bool isint
00027                                                     ): 
00028   brVar_   (brVar),
00029   lcrop_   (lcrop),
00030   rcrop_   (rcrop),
00031   jnlst_   (jnlst) {
00032 
00033   numberBranches_ = 3;
00034 
00035   // if none of these three, set to 0 and do code below
00036   firstBranch_ = (way == THREE_LEFT)   ? 0 : 
00037                  (way == THREE_CENTER) ? 1 : 
00038                  (way == THREE_RIGHT)  ? 2 : 0; 
00039   
00040   if (way == THREE_RAND) { // pick first branch randomly
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   //       -1 if "<= a"  node
00056   // way =  0 if "[a,b]" node
00057   //        1 if ">= b"  node
00058 
00059   int way = 0;
00060 
00061   switch (branchIndex_) {
00062     // if first offspring, let firstBranch_ decide who's first
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   // set lower or upper bound (round if this variable is integer)
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) { // from {0,1,2} to {-1,0,1}
00083 
00084   case -1: solver -> setColUpper (index, integer ? floor (lcrop_) : lcrop_); break; // left
00085   case  0: solver -> setColLower (index, integer ? ceil  (lcrop_) : lcrop_);
00086            solver -> setColUpper (index, integer ? floor (rcrop_) : rcrop_); break; // central
00087   case  1: solver -> setColLower (index, integer ? ceil  (rcrop_) : rcrop_); break; // right
00088   default: jnlst_->Printf(J_WARNING, J_BRANCHING, "Couenne: branching on nonsense way %d\n", way);
00089   }
00090 
00091   // TODO: apply bound tightening 
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; // left
00097     case  0: jnlst_->Printf(J_DETAILED, J_BRANCHING, 
00098                             "#3# Branch: %g <= x%d <= %g\n", lcrop_, index, rcrop_); break; // center
00099     case  1: jnlst_->Printf(J_DETAILED, J_BRANCHING, 
00100                             "#3# Branch: x%d >= %g\n",               index, rcrop_); break; // right
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.; // estimated change in objective function
00108 }

Generated on Thu Nov 10 03:05:42 2011 by  doxygen 1.4.7