/** copy method for constraint handler plugins (called when SCIP copies plugins) */
static
SCIP_DECL_PRESOLCOPY(presolCopyInttobinary)
{  /*lint --e{715}*/
   assert(scip != NULL);
   assert(presol != NULL);
   assert(strcmp(SCIPpresolGetName(presol), PRESOL_NAME) == 0);

   /* call inclusion method of presolver */
   SCIP_CALL( SCIPincludePresolInttobinary(scip) );
 
   return SCIP_OKAY;
}
Esempio n. 2
0
/** copies the given presolver to a new scip */
SCIP_RETCODE SCIPpresolCopyInclude(
   SCIP_PRESOL*          presol,             /**< presolver */
   SCIP_SET*             set                 /**< SCIP_SET of SCIP to copy to */
   )
{
   assert(presol != NULL);
   assert(set != NULL);
   assert(set->scip != NULL);

   if( presol->presolcopy != NULL )
   {
      SCIPdebugMessage("including presolver %s in subscip %p\n", SCIPpresolGetName(presol), (void*)set->scip);
      SCIP_CALL( presol->presolcopy(set->scip, presol) );
   }
   return SCIP_OKAY;
}
/** execution method of presolver */
static
SCIP_DECL_PRESOLEXEC(presolExecDualfix)
{  /*lint --e{715}*/
   SCIP_VAR** vars;
   SCIP_Real bound;
   SCIP_Real roundbound;
   SCIP_Real obj;
   SCIP_Bool infeasible;
   SCIP_Bool fixed;
   int nvars;
   int v;

   assert(presol != NULL);
   assert(strcmp(SCIPpresolGetName(presol), PRESOL_NAME) == 0);
   assert(result != NULL);

   *result = SCIP_DIDNOTFIND;

   /* get active problem variables */
   vars = SCIPgetVars(scip);
   nvars = SCIPgetNVars(scip);

   /* look for fixable variables
    * loop backwards, since a variable fixing can change the current and the subsequent slots in the vars array
    */
   for( v = nvars - 1; v >= 0; --v )
   {
      /* don't perform dual presolving operations on deleted variables */
      if( SCIPvarIsDeleted(vars[v]) )
         continue;

      obj = SCIPvarGetObj(vars[v]);

      /* if the objective coefficient of the variable is 0 and it may be rounded both
       * up and down, then fix it to the closest feasible value to 0 */
      if( SCIPisZero(scip, obj) && SCIPvarMayRoundDown(vars[v]) && SCIPvarMayRoundUp(vars[v]) )
      {
         bound = SCIPvarGetLbGlobal(vars[v]);
         if( SCIPisLT(scip, bound, 0.0) )
         {
            if( SCIPisLE(scip, 0.0, SCIPvarGetUbGlobal(vars[v])) )
               bound = 0.0;
            else
            {
               /* try to take an integer value, only for polishing */
               roundbound = SCIPfloor(scip, SCIPvarGetUbGlobal(vars[v]));
               
               if( roundbound < bound )
                  bound = SCIPvarGetUbGlobal(vars[v]);
               else
                  bound = roundbound;
            }
         }
         else
         {
            /* try to take an integer value, only for polishing */
            roundbound = SCIPceil(scip, bound);

            if( roundbound < SCIPvarGetUbGlobal(vars[v]) )
               bound = roundbound;
         }
         SCIPdebugMessage("variable <%s> with objective 0 fixed to %g\n",
            SCIPvarGetName(vars[v]), bound);
      }
      else
      {
         /* if it is always possible to round variable in direction of objective value,
          * fix it to its proper bound
          */
         if( SCIPvarMayRoundDown(vars[v]) && !SCIPisNegative(scip, obj) )
         {
            bound = SCIPvarGetLbGlobal(vars[v]);
            if( SCIPisZero(scip, obj) && SCIPvarGetNLocksUp(vars[v]) == 1 && SCIPisInfinity(scip, -bound) )
            {
               /* variable can be set to -infinity, and it is only contained in one constraint:
                * we hope that the corresponding constraint handler is clever enough to set/aggregate the variable
                * to something more useful than -infinity and do nothing here
                */
               continue;
            }
            SCIPdebugMessage("variable <%s> with objective %g and %d uplocks fixed to lower bound %g\n",
               SCIPvarGetName(vars[v]), SCIPvarGetObj(vars[v]), SCIPvarGetNLocksUp(vars[v]), bound);
         }
         else if( SCIPvarMayRoundUp(vars[v]) && !SCIPisPositive(scip, obj) )
         {
            bound = SCIPvarGetUbGlobal(vars[v]);
            if( SCIPisZero(scip, obj) && SCIPvarGetNLocksDown(vars[v]) == 1 && SCIPisInfinity(scip, bound) )
            {
               /* variable can be set to +infinity, and it is only contained in one constraint:
                * we hope that the corresponding constraint handler is clever enough to set/aggregate the variable
                * to something more useful than +infinity and do nothing here
                */
               continue;
            }
            SCIPdebugMessage("variable <%s> with objective %g and %d downlocks fixed to upper bound %g\n",
               SCIPvarGetName(vars[v]), SCIPvarGetObj(vars[v]), SCIPvarGetNLocksDown(vars[v]), bound);
         }
         else
            continue;
      }

      /* apply the fixing */
      if( SCIPisInfinity(scip, REALABS(bound)) && !SCIPisZero(scip, obj) )
      {
         SCIPdebugMessage(" -> unbounded fixing\n");
         SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL,
            "problem infeasible or unbounded: variable <%s> with objective %.15g can be made infinitely %s\n",
            SCIPvarGetName(vars[v]), SCIPvarGetObj(vars[v]), bound < 0.0 ? "small" : "large");
         *result = SCIP_UNBOUNDED;
         return SCIP_OKAY;
      }
      SCIP_CALL( SCIPfixVar(scip, vars[v], bound, &infeasible, &fixed) );
      if( infeasible )
      {
         SCIPdebugMessage(" -> infeasible fixing\n");
         *result = SCIP_CUTOFF;
         return SCIP_OKAY;
      }
      assert(fixed);
      (*nfixedvars)++;
      *result = SCIP_SUCCESS;
   }

   return SCIP_OKAY;
}
Esempio n. 4
0
/** presolving execution method */
static
SCIP_DECL_PRESOLEXEC(presolExecBoundshift)
{  /*lint --e{715}*/
   SCIP_PRESOLDATA* presoldata;
   SCIP_VAR** scipvars;
   SCIP_VAR** vars;
   int nbinvars;
   int nvars;
   int v;

   assert(scip != NULL);
   assert(presol != NULL);
   assert(strcmp(SCIPpresolGetName(presol), PRESOL_NAME) == 0);
   assert(result != NULL);

   *result = SCIP_DIDNOTRUN;

   /* get presolver data */
   presoldata = SCIPpresolGetData(presol);
   assert(presoldata != NULL);
   
   /* get the problem variables */
   scipvars = SCIPgetVars(scip);
   nbinvars = SCIPgetNBinVars(scip);
   nvars = SCIPgetNVars(scip) - nbinvars;

   if( nvars == 0 )
      return SCIP_OKAY;
   
   if( SCIPdoNotAggr(scip) )
      return SCIP_OKAY;

   *result = SCIP_DIDNOTFIND;

   /* copy the integer variables into an own array, since adding new integer variables affects the left-most slots in
    * the array and thereby interferes with our search loop
    */
   SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, &scipvars[nbinvars], nvars) );
   
   /* scan the integer, implicit, and continuous variables for possible conversion */
   for( v = nvars - 1; v >= 0; --v )
   {
      SCIP_VAR* var = vars[v];
      SCIP_Real lb;
      SCIP_Real ub;

      assert(SCIPvarGetType(var) != SCIP_VARTYPE_BINARY);

      /* get current variable's bounds */
      lb = SCIPvarGetLbGlobal(var);
      ub = SCIPvarGetUbGlobal(var);

      assert( SCIPisLE(scip, lb, ub) );
      if( SCIPisEQ(scip, lb, ub) )
         continue;
      if( presoldata->integer && !SCIPisIntegral(scip, ub - lb) ) 
         continue;

      /* check if bounds are shiftable */
      if( !SCIPisEQ(scip, lb, 0.0) &&                           /* lower bound != 0.0 */
         SCIPisLT(scip, ub, SCIPinfinity(scip)) &&              /* upper bound != infinity */
         SCIPisGT(scip, lb, -SCIPinfinity(scip)) &&             /* lower bound != -infinity */
#if 0
         SCIPisLT(scip, ub - lb, SCIPinfinity(scip)) &&         /* interval length less than SCIPinfinity(scip) */
#endif
         SCIPisLT(scip, ub - lb, (SCIP_Real) presoldata->maxshift) )        /* less than max shifting */
      {
         SCIP_VAR* newvar;
         char newvarname[SCIP_MAXSTRLEN];
         SCIP_Bool infeasible;
         SCIP_Bool redundant;
         SCIP_Bool aggregated;

         SCIPdebugMessage("convert range <%s>[%g,%g] to [%g,%g]\n", SCIPvarGetName(var), lb, ub, 0.0, (ub - lb) );

         /* create new variable */
         (void) SCIPsnprintf(newvarname, SCIP_MAXSTRLEN, "%s_shift", SCIPvarGetName(var));
         SCIP_CALL( SCIPcreateVar(scip, &newvar, newvarname, 0.0, (ub - lb), 0.0, SCIPvarGetType(var),
               SCIPvarIsInitial(var), SCIPvarIsRemovable(var), NULL, NULL, NULL, NULL, NULL) );
         SCIP_CALL( SCIPaddVar(scip, newvar) );

         /* aggregate old variable with new variable */
         if( presoldata->flipping )
         {
            if( REALABS(ub) < REALABS(lb) )
            {
               SCIP_CALL( SCIPaggregateVars(scip, var, newvar, 1.0, 1.0, ub, &infeasible, &redundant, &aggregated) );
            }
            else
            {
               SCIP_CALL( SCIPaggregateVars(scip, var, newvar, 1.0, -1.0, lb, &infeasible, &redundant, &aggregated) );
            }
         }
         else
         {
            SCIP_CALL( SCIPaggregateVars(scip, var, newvar, 1.0, -1.0, lb, &infeasible, &redundant, &aggregated) );
         }

         assert(!infeasible);
         assert(redundant);
         assert(aggregated);
         SCIPdebugMessage("var <%s> with bounds [%f,%f] has obj %f\n",
            SCIPvarGetName(newvar),SCIPvarGetLbGlobal(newvar),SCIPvarGetUbGlobal(newvar),SCIPvarGetObj(newvar));

         /* release variable */
         SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
         
         /* take care of statistic */
         (*naggrvars)++;
         *result = SCIP_SUCCESS;
      }
   }

   /* free temporary memory */
   SCIPfreeBufferArray(scip, &vars);
   
   return SCIP_OKAY;
}