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

Go to the documentation of this file.
00001 /* $Id: CouenneThreeWayBranchObj.cpp 141 2009-06-03 04:19:19Z pbelotti $ */
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. 
00008  * This file is licensed under the Common Public License (CPL)
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                                                     //bool isint
00025                                                     ): 
00026   brVar_   (brVar),
00027   lcrop_   (lcrop),
00028   rcrop_   (rcrop),
00029   jnlst_   (jnlst) {
00030 
00031   numberBranches_ = 3;
00032 
00033   // if none of these three, set to 0 and do code below
00034   firstBranch_ = (way == THREE_LEFT)   ? 0 : 
00035                  (way == THREE_CENTER) ? 1 : 
00036                  (way == THREE_RIGHT)  ? 2 : 0; 
00037   
00038   if (way == THREE_RAND) { // pick first branch randomly
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   //       -1 if "<= a"  node
00054   // way =  0 if "[a,b]" node
00055   //        1 if ">= b"  node
00056 
00057   int way = 0;
00058 
00059   switch (branchIndex_) {
00060     // if first offspring, let firstBranch_ decide who's first
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   // set lower or upper bound (round if this variable is integer)
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) { // from {0,1,2} to {-1,0,1}
00081 
00082   case -1: solver -> setColUpper (index, integer ? floor (lcrop_) : lcrop_); break; // left
00083   case  0: solver -> setColLower (index, integer ? ceil  (lcrop_) : lcrop_);
00084            solver -> setColUpper (index, integer ? floor (rcrop_) : rcrop_); break; // central
00085   case  1: solver -> setColLower (index, integer ? ceil  (rcrop_) : rcrop_); break; // right
00086   default: jnlst_->Printf(J_WARNING, J_BRANCHING, "Couenne: branching on nonsense way %d\n", way);
00087   }
00088 
00089   // TODO: apply bound tightening 
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; // left
00095     case  0: jnlst_->Printf(J_DETAILED, J_BRANCHING, 
00096                             "#3# Branch: %g <= x%d <= %g\n", lcrop_, index, rcrop_); break; // center
00097     case  1: jnlst_->Printf(J_DETAILED, J_BRANCHING, 
00098                             "#3# Branch: x%d >= %g\n",               index, rcrop_); break; // right
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.; // estimated change in objective function
00106 }

Generated on Thu Oct 8 03:02:56 2009 by  doxygen 1.4.7