Example #1
0
	int CPXPUBLIC CPX_CutCallback(CPXCENVptr xenv, void *cbdata,
			int wherefrom, void *cbhandle, int *useraction_p) {
//		cout << "Entering CPX Callback\n" << flush;
		CPXLPptr nodelp;
		CPXgetcallbacknodelp(xenv, cbdata, wherefrom, &nodelp);

		CoinCallbacks* ccc = (CoinCallbacks*)cbhandle;
		
		int length = CPXgetnumcols(xenv,nodelp) - 1; //hey, don't ask me! some VERY WIERD PHENOMENON... crap
		double objVal;
		double* solution = new double[length];
		CPXgetcallbacknodeobjval(xenv, cbdata, wherefrom, &objVal);
		CPXgetcallbacknodex(xenv, cbdata, wherefrom, solution, 0, length-1);

		OsiCuts* cuts = new OsiCuts();		
		CoinCallbacks::CutReturn ret = ccc->cutCallback(objVal, solution, cuts);
		
		if(ret == CoinCallbacks::CR_AddCuts) {
			for(int i = cuts->sizeRowCuts(); i-->0;) {
				const OsiRowCut& c = cuts->rowCut(i);				
				const CoinPackedVector& vec = c.row();

				if(c.globallyValid())
					/* Old Cplex-Versions did NOT have the last parameter (now set to "false").
					 * If you compile agains an older CPLEX version, simple *REMOVE*
					 *   ", false"
					 * from the calls to CPXcutscallbackadd
					 */
					CPXcutcallbackadd(xenv, cbdata, wherefrom,
						vec.getNumElements(), c.rhs(), c.sense(), vec.getIndices(), vec.getElements(), false);  //default to non-purgable cuts
				else
					CPXcutcallbackaddlocal(xenv, cbdata, wherefrom,
						vec.getNumElements(), c.rhs(), c.sense(), vec.getIndices(), vec.getElements());
				cuts->eraseRowCut(i);
			}
			if(cuts->sizeColCuts() > 0) {
				cerr << "ColCuts currently not supported...\n";
				OGDF_THROW_PARAM(LibraryNotSupportedException, lnscFunctionNotImplemented);
			}
		}
		
		*useraction_p = ( ret == CoinCallbacks::CR_Error) ? CPX_CALLBACK_FAIL :
		                ( ret == CoinCallbacks::CR_AddCuts ) ? CPX_CALLBACK_SET : 
		                CPX_CALLBACK_DEFAULT;
		delete cuts;
		delete[] solution;
//		cout << "Leaving CPX Callback\n" << flush;
		return 0; // success
	}
Example #2
0
static int CPXPUBLIC 
usersetbranch (CPXCENVptr   env,
               void         *cbdata,
               int          wherefrom,
               void         *userinfo,
               int          brtype,
               int          sos,
               int          nodecnt,
               int          bdcnt,
               const int    *nodebeg,
               const int    *idx,
               const char   *lu,
               const double *bd,
               const double *nodeest,
               int          *useraction_p)
{
   int status = 0;
   
   int      isfeas;
   int      i, j, k, l;
   int      besti = -1;
   int      bestj = -1;
   int      bestk = -1;
   int      cols;
   int      sossize, numsos;
   double   maxfrac = 0.0;
   double   xj_frac;
   double   objval;
   double   epint;
   double   *x = NULL;

   int      bdsz;
   int      *varind = NULL;
   char     *varlu  = NULL;
   double   *varbd  = NULL;
   int      seqnum;

   CPXCLPptr lp;

   /* Initialize useraction to indicate no user action taken */

   *useraction_p = CPX_CALLBACK_DEFAULT;

   /* If CPLEX is choosing an ordinary branch, take it */

   if ( sos < 0 )  goto TERMINATE;

   /* Get pointer to the problem */

   status = CPXgetcallbacklp (env, cbdata, wherefrom, &lp);
   if ( status ) {
      fprintf (stdout, "Can't get LP pointer.\n");
      goto TERMINATE;
   }

   cols = CPXgetnumcols (env, lp);
   if ( cols <= 0 ) {
      fprintf (stdout, "Can't number of columns.\n");
      status = CPXERR_CALLBACK;
      goto TERMINATE;
   }

   /* Get solution values and objective coefficients */

   x = (double *) malloc (cols * sizeof (double));
   if ( x == NULL ) {
      fprintf (stdout, "Out of memory.");
      goto TERMINATE;
   }

   status = CPXgetcallbacknodex (env, cbdata, wherefrom, x, 0,
                                 cols-1);
   if ( status ) {
      fprintf (stdout, "Can't get node solution.");
      goto TERMINATE;
   }

   status = CPXgetcallbacknodeobjval (env, cbdata, wherefrom,
                                      &objval);
   if ( status ) {
      fprintf (stdout, "Can't get node objective value.");
      goto TERMINATE;
   }

   status = CPXgetcallbacksosinfo (env, cbdata, wherefrom, 0, 0,
                                   CPX_CALLBACK_INFO_SOS_NUM,
                                   &numsos);
   if ( status )  goto TERMINATE;

   /* Branch on the set that has the variable closest to 1 */

   status = CPXgetdblparam (env, CPXPARAM_MIP_Tolerances_Integrality, &epint);

   for (i = 0; i < numsos; i++) {

      /* Check if the set is feasible */ 

      status = CPXgetcallbacksosinfo (env, cbdata, wherefrom, i, 0,
                                   CPX_CALLBACK_INFO_SOS_IS_FEASIBLE,
                                   &isfeas);
      if ( status )  goto TERMINATE;

      /* Find variable with largest fraction in each infeasible
         set.  Select a set with largest largest fraction for
         branching */

      if ( !isfeas ) {
         status = CPXgetcallbacksosinfo (env, cbdata, wherefrom, i,
                                         0,
                                         CPX_CALLBACK_INFO_SOS_SIZE,
                                         &sossize);
         if ( status )  goto TERMINATE;

         for (k = 0; k < sossize; k++) {
            status = CPXgetcallbacksosinfo (env, cbdata, wherefrom,
                                  i, k,
                                  CPX_CALLBACK_INFO_SOS_MEMBER_INDEX,
                                  &j);
            if ( status )  goto TERMINATE;

            xj_frac = x[j] - floor (x[j] + epint);
            if ( xj_frac > maxfrac ) {
               bestj = j;
               bestk = k;
               besti = i;
               maxfrac = xj_frac;
           }
         }
      }
   }

   if ( bestj < 0 ) {
      status = CPX_CALLBACK_DEFAULT;
      goto TERMINATE;
   } 

   /* Now set up node descriptions */

   /* Check that arrays are big enough; if not, return, requesting
      more space */

   status = CPXgetcallbacksosinfo (env, cbdata, wherefrom, besti, 0,
                                   CPX_CALLBACK_INFO_SOS_SIZE,
                                   &sossize);
   if ( status )  goto TERMINATE;

   bdsz = sossize + 1;

   varind = (int *) malloc (bdsz*sizeof(int));
   varlu  = (char *) malloc (bdsz*sizeof(char));
   varbd  = (double *) malloc (bdsz*sizeof(double));
   if ( varind == NULL ||
        varlu   == NULL ||
        varbd   == NULL   ) {
      status = CPXERR_NO_MEMORY;
      goto TERMINATE;
   }
   

   /* Create two nodes, one setting all but the selected variable 
      to 0 and the selected variable to 1, the other setting 
      the selected variable to 0 */

   /* First node */

   for (k = 0, l = 0; k < sossize; k++) {
      status = CPXgetcallbacksosinfo (env, cbdata, wherefrom, besti,
                                 k,
                                 CPX_CALLBACK_INFO_SOS_MEMBER_INDEX,
                                 &j);
      if ( status )  goto TERMINATE;
      if ( k != bestk ) {
         varind[l] = j;
         varlu[l]  = 'U';
         varbd[l]  = 0.;
         l++;
      }
      else {
         varind[l] = j;
         varlu[l]  = 'L';
         varbd[l]  = 1.;
         l++;
      }
   }
   status = CPXbranchcallbackbranchbds (env, cbdata, wherefrom,
                                        l, varind, varlu, varbd, objval,
                                        NULL, &seqnum);
   if ( status )  goto TERMINATE;

   /* Second node */

   varind[0] = bestj;
   varlu[0]  = 'U';
   varbd[0]  = 0.;

   status = CPXbranchcallbackbranchbds (env, cbdata, wherefrom,
                                        1, varind, varlu, varbd, objval, 
                                        NULL, &seqnum);
   if ( status )  goto TERMINATE;

   *useraction_p = CPX_CALLBACK_SET;

TERMINATE:

   free_and_null ((char **) &x);
   free_and_null ((char **) &varind);
   free_and_null ((char **) &varlu);
   free_and_null ((char **) &varbd);

   return (status);

} /* END usersetbranch */
Example #3
0
static int CPXPUBLIC
usersetbranch (CPXCENVptr   env,
               void         *cbdata,
               int          wherefrom,
               void         *cbhandle,
               int          brtype,
               int          sos,
               int          nodecnt,
               int          bdcnt,
               const int    *nodebeg,
               const int    *indices,
               const char   *lu,
               const double *bd,
               const double *nodeest,
               int          *useraction_p)   
{
   int status = 0;
 
   int      j, bestj = -1;
   int      cols;
   double   maxobj = -CPX_INFBOUND;
   double   maxinf = -CPX_INFBOUND;
   double   xj_inf;
   double   xj_lo;
   double   objval;
   double   *x   = NULL;
   double   *obj = NULL;
   int      *feas = NULL;
 
   char     varlu[1];
   double   varbd[1];
   int      seqnum1, seqnum2;
 
   CPXCLPptr lp;
 
   /* Initialize useraction to indicate no user action taken */
 
   *useraction_p = CPX_CALLBACK_DEFAULT;
 
   /* If CPLEX is choosing an SOS branch, take it */
 
   if ( sos >= 0 )  return (status);
 
   /* Get pointer to the problem */
 
   status = CPXgetcallbacklp (env, cbdata, wherefrom, &lp);
   if ( status ) {
      fprintf (stdout, "Can't get LP pointer.\n");
      goto TERMINATE;
   }
 
   cols = CPXgetnumcols (env, lp);
   if ( cols <= 0 ) {
      fprintf (stdout, "Can't get number of columns.\n");
      status = CPXERR_CALLBACK;
      goto TERMINATE;
   }
 
   /* Get solution values and objective coefficients */
 
   x    = (double *) malloc (cols * sizeof (double));
   obj  = (double *) malloc (cols * sizeof (double));
   feas = (int *)    malloc (cols * sizeof (int));
   if ( x     == NULL ||
        obj   == NULL ||
        feas  == NULL   ) {
      fprintf (stdout, "Out of memory.");
      status = CPXERR_CALLBACK;
      goto TERMINATE;
   }
 
   status = CPXgetcallbacknodex (env, cbdata, wherefrom, x, 0,
                                 cols-1);
   if ( status ) {
      fprintf (stdout, "Can't get node solution.");
      goto TERMINATE;
   }
 
   status = CPXgetcallbacknodeobjval (env, cbdata, wherefrom,
                                      &objval);
   if ( status ) {
      fprintf (stdout, "Can't get node objective value.");
      goto TERMINATE;
   }
 
   status = CPXgetobj (env, lp, obj, 0, cols-1);
   if ( status ) {
      fprintf (stdout, "Can't get obj.");
      goto TERMINATE;
   }
 
   status = CPXgetcallbacknodeintfeas (env, cbdata, wherefrom, feas,
                                       0, cols-1);
   if ( status ) {
      fprintf (stdout,
               "Can't get variable feasible status for node.");
      goto TERMINATE;
   }
 
   /* Branch on var with largest objective coefficient among those
      with largest infeasibility */
 
   for (j = 0; j < cols; j++) {
      if ( feas[j] == CPX_INTEGER_INFEASIBLE ) {
         xj_inf = x[j] - floor (x[j]);
         if ( xj_inf > 0.5 )  xj_inf = 1.0 - xj_inf;
 
         if ( xj_inf >= maxinf                            &&
              (xj_inf > maxinf || fabs (obj[j]) >= maxobj)  ) {
            bestj  = j;
            maxinf = xj_inf; 
            maxobj = fabs (obj[j]);
         }
      }
   }
 
   /* If there weren't any eligible variables, take default branch */
 
   if ( bestj < 0 ) {
      goto TERMINATE;
   }
 
   /* Now set up node descriptions */
 
   xj_lo = floor (x[bestj]);
 
   /* Up node */
 
   varlu[0] = 'L';
   varbd[0] = xj_lo + 1;
   status = CPXbranchcallbackbranchbds (env, cbdata, wherefrom,
                                        1, &bestj, varlu, varbd, objval,
                                        NULL, &seqnum1);
   if ( status )  goto TERMINATE;
 
   /* Down node */
 
   varlu[0] = 'U';
   varbd[0] = xj_lo;
 
   status = CPXbranchcallbackbranchbds (env, cbdata, wherefrom,
                                        1, &bestj, varlu, varbd, objval,
                                        NULL, &seqnum2);
   if ( status )  goto TERMINATE;
 
   /* Set useraction to indicate a user-specified branch */
 
   *useraction_p = CPX_CALLBACK_SET;
 
TERMINATE:
 
   free_and_null ((char **) &x);
   free_and_null ((char **) &obj);
   free_and_null ((char **) &feas); 
   return (status);
 
} /* END usersetbranch */