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

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

Generated on Mon Aug 3 03:02:21 2009 by  doxygen 1.4.7