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

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

Generated on Thu Aug 5 03:02:57 2010 by  doxygen 1.4.7