示例#1
0
/** adds given problem variable to pricing storage, if zero is not best bound w.r.t. objective function */
static
SCIP_RETCODE addBoundViolated(
   SCIP_PRICESTORE*      pricestore,         /**< pricing storage */
   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
   SCIP_SET*             set,                /**< global SCIP settings */
   SCIP_STAT*            stat,               /**< dynamic problem statistics */
   SCIP_TREE*            tree,               /**< branch and bound tree */
   SCIP_LP*              lp,                 /**< LP data */
   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
   SCIP_VAR*             var,                /**< problem variable */
   SCIP_Bool*            added               /**< pointer to store whether variable was added to pricing storage */
   )
{
   assert(tree != NULL);
   assert(added != NULL);

   *added = FALSE;

   /* add variable, if zero is not feasible within the bounds */
   if( SCIPsetIsPositive(set, SCIPvarGetLbLocal(var)) || SCIPsetIsNegative(set, SCIPvarGetUbLocal(var)) )
   {
      SCIPdebugMessage(" -> zero violates bounds of <%s> [%g,%g]\n",
         SCIPvarGetName(var), SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var));
      SCIP_CALL( SCIPpricestoreAddBdviolvar(pricestore, blkmem, set, stat, lp, branchcand, eventqueue, var) );
      *added = TRUE;
   }
   else
   {
      SCIP_Real bestbound;

      /* add variable, if zero is not best bound w.r.t. objective function */
      bestbound = SCIPvarGetBestBoundLocal(var);
      if( !SCIPsetIsZero(set, bestbound) )
      {
         SCIPdebugMessage(" -> best bound of <%s> [%g,%g] is not zero but %g\n",
            SCIPvarGetName(var), SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), bestbound);
         SCIP_CALL( SCIPpricestoreAddVar(pricestore, blkmem, set, eventqueue, lp, var, 
               -SCIPvarGetObj(var) * bestbound, (SCIPtreeGetCurrentDepth(tree) == 0)) );
         *added = TRUE;
      }
   }

   return SCIP_OKAY;
}
示例#2
0
文件: stat.c 项目: hhexiy/scip
/** update the primal-dual integral statistic. method accepts + and - SCIPsetInfinity() as values for
 *  upper and lower bound, respectively
 */
void SCIPstatUpdatePrimalDualIntegral(
   SCIP_STAT*            stat,               /**< problem statistics data */
   SCIP_SET*             set,                /**< global SCIP settings */
   SCIP_PROB*            transprob,          /**< transformed problem */
   SCIP_PROB*            origprob,           /**< original problem */
   SCIP_Real             upperbound,         /**< current upper bound in transformed problem, or infinity */
   SCIP_Real             lowerbound          /**< current lower bound in transformed space, or -infinity */
   )
{
   SCIP_Real currentgap;
   SCIP_Real solvingtime;
   SCIP_Real primalbound;
   SCIP_Real dualbound;

   assert(stat != NULL);
   assert(set != NULL);

   solvingtime = SCIPclockGetTime(stat->solvingtime);
   assert(solvingtime >= stat->previntegralevaltime);

   if( !SCIPsetIsInfinity(set, upperbound) ) /*lint !e777*/
   {
      /* get value in original space for gap calculation */
      primalbound = SCIPprobExternObjval(transprob, origprob, set, upperbound);

      if( SCIPsetIsZero(set, primalbound) )
         primalbound = 0.0;
   }
   else
   {
      /* no new upper bound: use stored values from last update */
      upperbound = stat->lastupperbound;
      primalbound = stat->lastprimalbound;
      assert(SCIPsetIsZero(set, primalbound) == (primalbound == 0.0)); /*lint !e777*/
   }

   if( !SCIPsetIsInfinity(set, -lowerbound) ) /*lint !e777*/
   {
      /* get value in original space for gap calculation */
      dualbound = SCIPprobExternObjval(transprob, origprob, set, lowerbound);

      if( SCIPsetIsZero(set, dualbound) )
         dualbound = 0.0;
   }
   else
   {
      /* no new lower bound: use stored values from last update */
      lowerbound = stat->lastlowerbound;
      dualbound = stat->lastdualbound;
      assert(SCIPsetIsZero(set, dualbound) == (dualbound == 0.0)); /*lint !e777*/
   }

   /* computation of the gap, special cases are handled first */
   if( primalbound == SCIP_UNKNOWN || dualbound == SCIP_UNKNOWN ) /*lint !e777*/
      currentgap = 100.0;
   /* the gap is 0.0 if bounds coincide */
   else if( SCIPsetIsGE(set, lowerbound, upperbound) || SCIPsetIsEQ(set, primalbound, dualbound) )
      currentgap = 0.0;
   /* the gap is 100.0 if bounds have different signs */
   else if( primalbound * dualbound <= 0.0 ) /*lint !e777*/
      currentgap = 100.0;
   else if( !SCIPsetIsInfinity(set, REALABS(primalbound)) && !SCIPsetIsInfinity(set, REALABS(dualbound)) )
   {
      SCIP_Real absprim = REALABS(primalbound);
      SCIP_Real absdual = REALABS(dualbound);

      /* The gap in the definition of the primal-dual integral differs from the default SCIP gap function.
       * Here, the MAX(primalbound, dualbound) is taken for gap quotient in order to ensure a gap <= 100.
       */
      currentgap = 100.0 * REALABS(primalbound - dualbound) / MAX(absprim, absdual);
      assert(SCIPsetIsLE(set, currentgap, 100.0));
   }
   else
      currentgap = 100.0;

   /* if primal and dual bound have opposite signs, the gap always evaluates to 100.0% */
   assert(currentgap == 0.0 || currentgap == 100.0 || SCIPsetIsGE(set, primalbound * dualbound, 0.0));
   assert(SCIPsetIsGE(set, stat->previousgap, currentgap) || (set->stage == SCIP_STAGE_EXITPRESOLVE
         && SCIPsetIsFeasGE(set, stat->previousgap, currentgap)));

   /* update the integral based on previous information */
   stat->primaldualintegral += (solvingtime - stat->previntegralevaltime) * stat->previousgap;

   /* update all relevant information for next evaluation */
   stat->previousgap = currentgap;
   stat->previntegralevaltime = solvingtime;
   stat->lastprimalbound = primalbound;
   stat->lastdualbound = dualbound;
   stat->lastlowerbound = lowerbound;
   stat->lastupperbound = upperbound;
}
示例#3
0
/** applies a cut that is a bound change directly as bound change instead of adding it as row to the LP */
static
SCIP_RETCODE sepastoreApplyBdchg(
   SCIP_SEPASTORE*       sepastore,          /**< separation storage */
   BMS_BLKMEM*           blkmem,             /**< block memory */
   SCIP_SET*             set,                /**< global SCIP settings */
   SCIP_STAT*            stat,               /**< problem statistics */
   SCIP_TREE*            tree,               /**< branch and bound tree */
   SCIP_LP*              lp,                 /**< LP data */
   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
   SCIP_ROW*             cut,                /**< cut with a single variable */
   SCIP_Bool*            cutoff              /**< pointer to store whether an empty domain was created */
   )
{
   SCIP_COL** cols;
   SCIP_Real* vals;
   SCIP_VAR* var;
   SCIP_Real lhs;
   SCIP_Real rhs;

   assert(sepastore != NULL);
   assert(!SCIProwIsModifiable(cut));
   assert(SCIProwGetNNonz(cut) == 1);
   assert(cutoff != NULL);

   *cutoff = FALSE;

   /* get the single variable and its coefficient of the cut */
   cols = SCIProwGetCols(cut);
   assert(cols != NULL);
   var = SCIPcolGetVar(cols[0]);
   vals = SCIProwGetVals(cut);
   assert(vals != NULL);
   assert(!SCIPsetIsZero(set, vals[0]));

   /* if the coefficient is nearly zero, we better ignore this cut for numerical reasons */
   if( SCIPsetIsFeasZero(set, vals[0]) )
      return SCIP_OKAY;

   /* get the left hand side of the cut and convert it to a bound */
   lhs = SCIProwGetLhs(cut);
   if( !SCIPsetIsInfinity(set, -lhs) )
   {
      lhs -= SCIProwGetConstant(cut);
      if( vals[0] > 0.0 )
      {
         /* coefficient is positive -> lhs corresponds to lower bound */
         SCIP_CALL( sepastoreApplyLb(sepastore, blkmem, set, stat, tree, lp, branchcand, eventqueue,
               var, lhs/vals[0], cutoff) );
      }
      else
      {
         /* coefficient is negative -> lhs corresponds to upper bound */
         SCIP_CALL( sepastoreApplyUb(sepastore, blkmem, set, stat, tree, lp, branchcand, eventqueue,
               var, lhs/vals[0], cutoff) );
      }
   }

   /* get the right hand side of the cut and convert it to a bound */
   rhs = SCIProwGetRhs(cut);
   if( !SCIPsetIsInfinity(set, rhs) )
   {
      rhs -= SCIProwGetConstant(cut);
      if( vals[0] > 0.0 )
      {
         /* coefficient is positive -> rhs corresponds to upper bound */
         SCIP_CALL( sepastoreApplyUb(sepastore, blkmem, set, stat, tree, lp, branchcand, eventqueue,
               var, rhs/vals[0], cutoff) );
      }
      else
      {
         /* coefficient is negative -> rhs corresponds to lower bound */
         SCIP_CALL( sepastoreApplyLb(sepastore, blkmem, set, stat, tree, lp, branchcand, eventqueue,
               var, rhs/vals[0], cutoff) );
      }
   }

   /* count the bound change as applied cut */
   if( !sepastore->initiallp )
      sepastore->ncutsapplied++;

   return SCIP_OKAY;
}