示例#1
0
/** applies an upper bound change */
static
SCIP_RETCODE sepastoreApplyUb(
   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_VAR*             var,                /**< problem variable */
   SCIP_Real             bound,              /**< new upper bound of variable */
   SCIP_Bool*            cutoff              /**< pointer to store TRUE, if an infeasibility has been detected */
   )
{
   assert(sepastore != NULL);
   assert(cutoff != NULL);

   if( SCIPsetIsLT(set, bound, SCIPvarGetUbLocal(var)) )
   {
      SCIPdebugMessage(" -> applying bound change: <%s>: [%g,%g] -> [%g,%g]\n",
         SCIPvarGetName(var), SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), SCIPvarGetLbLocal(var), bound);

      if( SCIPsetIsFeasGE(set, bound, SCIPvarGetLbLocal(var)) )
      {
         SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(tree), blkmem, set, stat, tree, lp, branchcand, eventqueue,
               var, bound, SCIP_BOUNDTYPE_UPPER, FALSE) );
      }
      else
         *cutoff = TRUE;

      if( !sepastore->initiallp )
         sepastore->ncutsapplied++;
   }

   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
/** returns whether the solution is contained in node's subproblem */
static
SCIP_RETCODE isSolutionInNode(
   BMS_BLKMEM*           blkmem,             /**< block memory */
   SCIP_SET*             set,                /**< global SCIP settings */
   SCIP_NODE*            node,               /**< local node where this bound change was applied */
   SCIP_Bool*            solcontained        /**< pointer to store whether the solution is contained in node's subproblem */
   )
{
   SCIP_Bool* boolptr;

   assert(set != NULL);
   assert(blkmem != NULL);
   assert(node != NULL);
   assert(solcontained != NULL);

   /* check if we are in the original problem and not in a sub MIP */
   if( !isSolutionInMip(set) )
   {
      *solcontained = FALSE;
      return SCIP_OKAY;
   }

   /* generate the hashmap */
   if( solinnode == NULL )
   {
      SCIP_CALL( SCIPhashmapCreate(&solinnode, blkmem, SCIPcalcHashtableSize(SCIP_HASHSIZE_DEBUG)) );
   }

   /* check, whether we know already whether the solution is contained in the given node */
   boolptr = (SCIP_Bool*)SCIPhashmapGetImage(solinnode, (void*)node);
   if( boolptr != NULL )
   {
      if( boolptr != &falseptr && boolptr != &trueptr )
      {
         SCIPerrorMessage("wrong value in node hashmap\n");
         SCIPABORT();
      }
      *solcontained = *boolptr;
      return SCIP_OKAY;
   }

   /* if the solution is not contained in the parent of the node, it cannot be contained in the current node */
   *solcontained = TRUE;
   if( node->parent != NULL )
   {
      SCIP_CALL( isSolutionInNode(blkmem, set, node->parent, solcontained) );
   }

   if( *solcontained )
   {
      /* check whether the bound changes at the current node remove the debugging solution from the subproblem */
      if( node->domchg != NULL )
      {
         SCIP_DOMCHGBOUND* domchgbound;
         SCIP_BOUNDCHG* boundchgs;
         int i;

         domchgbound = &node->domchg->domchgbound;
         boundchgs = domchgbound->boundchgs;
         for( i = 0; i < (int)domchgbound->nboundchgs && *solcontained; ++i )
         {
            SCIP_Real varsol;

            if( SCIPboundchgIsRedundant(&boundchgs[i]) )
               continue;

            /* get solution value of variable */
            SCIP_CALL( getSolutionValue(set, boundchgs[i].var, &varsol) );

            if( varsol != SCIP_UNKNOWN ) /*lint !e777*/
            {
               /* compare the bound change with the solution value */
               if( SCIPboundchgGetBoundtype(&boundchgs[i]) == SCIP_BOUNDTYPE_LOWER )
                  *solcontained = SCIPsetIsFeasGE(set, varsol, boundchgs[i].newbound);
               else
                  *solcontained = SCIPsetIsFeasLE(set, varsol, boundchgs[i].newbound);
               if( !(*solcontained) && SCIPboundchgGetBoundchgtype(&boundchgs[i]) != SCIP_BOUNDCHGTYPE_BRANCHING )
               {
                  SCIPerrorMessage("debugging solution was cut off in local node %p at depth %d by inference <%s>[%.15g] %s %.15g\n",
                     node, SCIPnodeGetDepth(node), SCIPvarGetName(boundchgs[i].var), varsol,
                     SCIPboundchgGetBoundtype(&boundchgs[i]) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", boundchgs[i].newbound);
                  SCIPABORT();
               }
            }
            else if( SCIPboundchgGetBoundchgtype(&boundchgs[i]) == SCIP_BOUNDCHGTYPE_BRANCHING )
            {
               /* we branched on a variable were we don't know the solution: no debugging can be applied in this subtree */
               *solcontained = FALSE;
            }
         }
      }
   }

   /* remember the status of the current node */
   SCIP_CALL( SCIPhashmapSetImage(solinnode, (void*)node, *solcontained ? (void*)(&trueptr) : (void*)(&falseptr)) );

   return SCIP_OKAY;
}