/home/coin/SVN-release/OS-2.4.0/Couenne/src/problem/testIntFix.cpp

Go to the documentation of this file.
00001 /* $Id: testIntFix.cpp 490 2011-01-14 16:07:12Z pbelotti $
00002  *
00003  * Name:    testIntFix.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: select rounding for integer variable based on tightening
00006  *
00007  * (C) Carnegie-Mellon University, 2008-09.
00008  * This file is licensed under the Eclipse Public License (EPL)
00009  */
00010 
00011 #include "CoinHelperFunctions.hpp"
00012 #include "CouenneProblem.hpp"
00013 #include "CouenneProblemElem.hpp"
00014 
00015 using namespace Couenne;
00016 
00017 // test if fixing a variable yields an infeasible (or dually
00018 // infeasible) problem
00019 int CouenneProblem::testIntFix (int index, 
00020                                 CouNumber xFrac, 
00021                                 enum fixType *fixed,
00022                                 CouNumber *xInt,
00023                                 CouNumber *dualL, CouNumber *dualR,
00024                                 CouNumber *olb,   CouNumber *oub,
00025                                 bool patient) const {
00026   int 
00027     ncols  = nVars (), 
00028     retval = 0,
00029     objind = Obj (0) -> Body () -> Index ();
00030 
00031   // create fictitious change structure -- all initialized at UNCHANGED by constructor
00032   t_chg_bounds *f_chg = new t_chg_bounds [ncols];
00033 
00034   double
00035     *llb = new double [ncols], *lub = new double [ncols],  // new bounds when rounding down
00036     *rlb = new double [ncols], *rub = new double [ncols];  //                          up
00037 
00038   // try rounding down ///////////////////////////////////////////////////////////////////////
00039 
00040   Lb (index) = Ub (index) = floor (xFrac); 
00041 
00042   // useless
00043   /*for (int j = 0; j<ncols; j++) {
00044     f_chg [j].setLower (t_chg_bounds::UNCHANGED); 
00045     f_chg [j].setUpper (t_chg_bounds::UNCHANGED);
00046     }*/
00047 
00048   f_chg [index].setLower (t_chg_bounds::CHANGED); 
00049   f_chg [index].setUpper (t_chg_bounds::CHANGED);
00050 
00051   bool feasLeft = btCore (f_chg); // true if feasible with fake bound
00052 
00053   dualL [index] = Lb (objind);
00054 
00055   // save new bounds 
00056   CoinCopyN (Lb (), ncols, llb);
00057   CoinCopyN (Ub (), ncols, lub);
00058 
00059   // restore initial situation
00060   CoinCopyN (olb, ncols, Lb ());
00061   CoinCopyN (oub, ncols, Ub ());
00062 
00063   // try rounding up ///////////////////////////////////////////////////////////////////////
00064 
00065   Lb (index) = Ub (index) = ceil (xFrac); 
00066 
00067   for (int j = 0; j<ncols; j++) {
00068     f_chg [j].setLower (t_chg_bounds::UNCHANGED); 
00069     f_chg [j].setUpper (t_chg_bounds::UNCHANGED);
00070   }
00071 
00072   f_chg [index].setLower (t_chg_bounds::CHANGED); 
00073   f_chg [index].setUpper (t_chg_bounds::CHANGED);
00074 
00075   bool feasRight = btCore (f_chg); // true if feasible with fake bound
00076 
00077   dualR [index] = Lb (objind);
00078 
00079   // save new bounds
00080   CoinCopyN (Lb (), ncols, rlb);
00081   CoinCopyN (Ub (), ncols, rub);
00082 
00083   // restore initial situation
00084   CoinCopyN (olb, ncols, Lb ());
00085   CoinCopyN (oub, ncols, Ub ());
00086 
00088 
00089   // Three cases:
00090   //
00091   // 1) if at least one is infeasible, set x_i to other
00092   //
00093   // 2) if both are infeasible, apply normal aggressive BT:
00094   //    2a) if both infeasible, node is infeasible
00095   //    2b) if both feasible, store index in free++ variables
00096   //    2c) if only one feasible, set rounded +/- 2
00097   //    ...
00098   //    2z) or probably simpler if return -1 to avoid calling Ipopt
00099   //
00100   // 3) if both feasible, choose one based on dual bound
00101 
00102   if (!feasLeft)
00103 
00104     if (!feasRight) {
00105 
00106       jnlst_ -> Printf (Ipopt::J_MOREVECTOR, J_NLPHEURISTIC, 
00107                         "test on %d -> Infeasible.\n ", index);
00108       retval = -1; // case 2
00109 
00110     } else {
00111 
00112       // ceil is feasible, floor is not.
00113       jnlst_ -> Printf (Ipopt::J_MOREVECTOR, J_NLPHEURISTIC, 
00114                         "test on %d -> Right feasible, fix to %g.\n", index, ceil (xFrac));
00115 
00116       fixed [index] = FIXED;
00117       Lb (index) = Ub (index) = olb [index] = oub [index] = xInt [index] = ceil (xFrac); 
00118       //printf ("0 fixed %d [%g,%g,%g]\n", i, Lb (i), Ub (i), xInt [i]);
00119       retval++;
00120       //printf ("+++ 1 %d\n", i);
00121 
00122       // tighten bounds using r[lu]b
00123       for (int j=0; j<ncols; j++) if (index != j) {
00124 
00125         olb [j] = Lb (j) = CoinMax (Lb (j), rlb [j]);
00126         oub [j] = Ub (j) = CoinMin (Ub (j), rub [j]);
00127 
00128         if (Lb (j) > Ub (j) + COUENNE_EPS)
00129           retval = -1;
00130       }
00131     }
00132   else if (!feasRight) {
00133 
00134     // floor is feasible, ceil is not.
00135     jnlst_ -> Printf (Ipopt::J_MOREVECTOR, J_NLPHEURISTIC, 
00136                       "test on %d -> Left feasible, fix to %g.\n", index, floor (xFrac));
00137 
00138     fixed [index] = FIXED;
00139     Lb (index) = Ub (index) = olb [index] = oub [index] = xInt [index] = floor (xFrac); 
00140     //printf ("1 fixed %d [%g,%g,%g]\n", i, Lb (i), Ub (i), xInt [i]);
00141     retval++;
00142     //printf ("+++ 2 %d\n", i);
00143 
00144     // tighten bounds using l[lu]b
00145     for (int j=0; j<ncols; j++) if (index != j) {
00146 
00147       olb [j] = Lb (j) = CoinMax (Lb (j), llb [j]);
00148       oub [j] = Ub (j) = CoinMin (Ub (j), lub [j]);
00149 
00150       if (Lb (j) > Ub (j) + COUENNE_EPS) {
00151         retval = -1;
00152         break;
00153       }
00154     }
00155   } else { // case 3: tighten to smallest interval containing both [llb,lub] and [rlb,rub]
00156 
00157     // tighten bounds using l[lu]b
00158     for (int j=0; j<ncols; j++) {
00159 
00160       olb [j] = Lb (j) = CoinMax (Lb (j), CoinMin (llb [j], rlb [j]));
00161       oub [j] = Ub (j) = CoinMin (Ub (j), CoinMax (lub [j], rub [j]));
00162 
00163       if (Lb (j) > Ub (j) + COUENNE_EPS) {
00164         retval = -1;
00165         break;
00166       }
00167     }
00168 
00169     if ((retval >= 0) && !patient) { // too much time spent here, just fix it based on dual bound
00170 
00171       fixed [index] = FIXED;
00172 
00173       Lb (index) = Ub (index) = olb [index] = oub [index] = xInt [index] = 
00174         ((dualL [index] < dualR [index] - COUENNE_EPS) ? floor (xFrac) :
00175          (dualL [index] > dualR [index] + COUENNE_EPS) ? ceil  (xFrac) :
00176          ((CoinDrand48 () < 0.5) ? floor (xFrac) : ceil (xFrac)));
00177       
00178       jnlst_ -> Printf (Ipopt::J_MOREVECTOR, J_NLPHEURISTIC, 
00179                         "test on %d -> Both feasible, lost patience, fixed to %g.\n", 
00180                         index, xInt [index]);
00181 
00182       //printf ("1 fixed %d [%g,%g,%g]\n", i, Lb (i), Ub (i), xInt [i]);
00183       retval++;
00184       //printf ("+++ 2 %d\n", i);
00185     } else if (retval >= 0) jnlst_ -> Printf (Ipopt::J_MOREVECTOR, J_NLPHEURISTIC, 
00186                                               "test on %d -> Both feasible, skip this turn.\n", index);
00187   }
00188 
00189   delete [] f_chg;
00190 
00191   delete [] llb; delete [] lub;
00192   delete [] rlb; delete [] rub;
00193 
00194   return retval;
00195 }

Generated on Thu Sep 22 03:05:59 2011 by  doxygen 1.4.7