Пример #1
0
/** depending on the LP's solution status, calls reduced cost or Farkas pricing method of variable pricer */
SCIP_RETCODE SCIPpricerExec(
   SCIP_PRICER*          pricer,             /**< variable pricer */
   SCIP_SET*             set,                /**< global SCIP settings */
   SCIP_PROB*            prob,               /**< transformed problem */
   SCIP_LP*              lp,                 /**< LP data */
   SCIP_PRICESTORE*      pricestore,         /**< pricing storage */
   SCIP_Real*            lowerbound,         /**< local lower bound computed by the pricer */
   SCIP_RESULT*          result              /**< result of the pricing process */
   )
{
   assert(pricer != NULL);
   assert(lowerbound != NULL);
   assert(result != NULL);

   /* set lowerbound and result pointer */
   *lowerbound = - SCIPsetInfinity(set);
   *result = SCIP_SUCCESS;

   /* check if pricer should be delayed */
   if( pricer->delay && SCIPpricestoreGetNVars(pricestore) > 0 )
      return SCIP_OKAY;

   if( SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_INFEASIBLE )
   {
      SCIP_CALL( SCIPpricerFarkas(pricer, set, prob) );
   }
   else
   {
      *result = SCIP_DIDNOTRUN;
      SCIP_CALL( SCIPpricerRedcost(pricer, set, prob, lowerbound, result) );
   }

   return SCIP_OKAY;
}
Пример #2
0
Файл: stat.c Проект: hhexiy/scip
/** reset primal-dual integral */
void SCIPstatResetPrimalDualIntegral(
   SCIP_STAT*            stat,               /**< problem statistics data */
   SCIP_SET*             set,                /**< global SCIP settings */
   SCIP_Bool             partialreset        /**< should time and integral value be kept? (in combination with no statistical
                                              *   reset, integrals are added for each problem to be solved) */
   )
{
   assert(stat != NULL);

   stat->previousgap = 100.0;
   stat->lastprimalbound = SCIP_UNKNOWN;
   stat->lastdualbound = SCIP_UNKNOWN;
   stat->lastlowerbound = -SCIPsetInfinity(set);
   stat->lastupperbound = SCIPsetInfinity(set);

   /* partial resets keep the integral value and previous evaluation time */
   if( !partialreset )
   {
      stat->previntegralevaltime = 0.0;
      stat->primaldualintegral = 0.0;
   }
}
Пример #3
0
/** adds cut stored as LP row to separation storage and captures it;
 *  if the cut should be forced to be used, an infinite score has to be used
 */
static
SCIP_RETCODE sepastoreAddCut(
   SCIP_SEPASTORE*       sepastore,          /**< separation storage */
   BMS_BLKMEM*           blkmem,             /**< block memory */
   SCIP_SET*             set,                /**< global SCIP settings */
   SCIP_STAT*            stat,               /**< problem statistics data */
   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
   SCIP_EVENTFILTER*     eventfilter,        /**< event filter for global events */
   SCIP_LP*              lp,                 /**< LP data */
   SCIP_SOL*             sol,                /**< primal solution that was separated, or NULL for LP solution */
   SCIP_ROW*             cut,                /**< separated cut */
   SCIP_Bool             forcecut,           /**< should the cut be forced to enter the LP? */
   SCIP_Bool             root                /**< are we at the root node? */
   )
{
   SCIP_Real cutefficacy;
   SCIP_Real cutobjparallelism;
   SCIP_Real cutscore;
   int pos;

   assert(sepastore != NULL);
   assert(sepastore->nforcedcuts <= sepastore->ncuts);
   assert(set != NULL);
   assert(cut != NULL);
   assert(sol != NULL || !SCIProwIsInLP(cut));
   assert(!SCIPsetIsInfinity(set, -SCIProwGetLhs(cut)) || !SCIPsetIsInfinity(set, SCIProwGetRhs(cut)));
   assert(eventqueue != NULL);
   assert(eventfilter != NULL);

   /* in the root node, every local cut is a global cut, and global cuts are nicer in many ways...*/
   if( root && SCIProwIsLocal(cut) )
   {
      SCIPdebugMessage("change local flag of cut <%s> to FALSE due to addition in root node\n", SCIProwGetName(cut));

      SCIP_CALL( SCIProwChgLocal(cut, FALSE) );

      assert(!SCIProwIsLocal(cut));
   }

   /* check cut for redundancy
    * in each separation round, make sure that at least one (even redundant) cut enters the LP to avoid cycling
    */
   if( !forcecut && sepastore->ncuts > 0 && sepastoreIsCutRedundant(sepastore, set, stat, cut) )
      return SCIP_OKAY;

   /* if only one cut is currently present in the cut store, it could be redundant; in this case, it can now be removed
    * again, because now a non redundant cut enters the store
    */
   if( sepastore->ncuts == 1 && sepastoreIsCutRedundant(sepastore, set, stat, sepastore->cuts[0]) )
   {
      /* check, if the row deletions from separation storage events are tracked
       * if so, issue ROWDELETEDSEPA event
       */
      if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDSEPA) != 0 )
      {
         SCIP_EVENT* event;

         SCIP_CALL( SCIPeventCreateRowDeletedSepa(&event, blkmem, sepastore->cuts[0]) );
         SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
      }
      
      SCIP_CALL( SCIProwRelease(&sepastore->cuts[0], blkmem, set, lp) );
      sepastore->ncuts = 0;
      sepastore->nforcedcuts = 0;
   }

   /* a cut is forced to enter the LP if
    *  - we construct the initial LP, or
    *  - it has infinite score factor, or
    *  - it is a bound change
    * if it is a non-forced cut and no cuts should be added, abort
    */
   forcecut = forcecut || sepastore->initiallp || sepastore->forcecuts
      || (!SCIProwIsModifiable(cut) && SCIProwGetNNonz(cut) == 1);
   if( !forcecut && SCIPsetGetSepaMaxcuts(set, root) == 0 )
      return SCIP_OKAY;

   /* get enough memory to store the cut */
   SCIP_CALL( sepastoreEnsureCutsMem(sepastore, set, sepastore->ncuts+1) );
   assert(sepastore->ncuts < sepastore->cutssize);

   if( forcecut )
   {
      cutefficacy = SCIPsetInfinity(set);
      cutscore = SCIPsetInfinity(set);
      cutobjparallelism = 1.0;
   }
   else
   {
      /* initialize values to invalid (will be initialized during cut filtering) */
      cutefficacy = SCIP_INVALID;
      cutscore = SCIP_INVALID;

      /* initialize parallelism to objective (constant throughout filtering) */
      if( set->sepa_objparalfac > 0.0 )
         cutobjparallelism = SCIProwGetObjParallelism(cut, set, lp);
      else
         cutobjparallelism = 0.0; /* no need to calculate it */
   }

   SCIPdebugMessage("adding cut <%s> to separation storage of size %d (forcecut=%u, len=%d)\n",
      SCIProwGetName(cut), sepastore->ncuts, forcecut, SCIProwGetNNonz(cut));
   /*SCIPdebug(SCIProwPrint(cut, NULL));*/

   /* capture the cut */
   SCIProwCapture(cut);

   /* add cut to arrays */
   if( forcecut )
   {
      /* make room at the beginning of the array for forced cut */
      pos = sepastore->nforcedcuts;
      sepastore->cuts[sepastore->ncuts] = sepastore->cuts[pos];
      sepastore->efficacies[sepastore->ncuts] = sepastore->efficacies[pos];
      sepastore->objparallelisms[sepastore->ncuts] = sepastore->objparallelisms[pos];
      sepastore->orthogonalities[sepastore->ncuts] = sepastore->orthogonalities[pos];
      sepastore->scores[sepastore->ncuts] = sepastore->scores[pos];
      sepastore->nforcedcuts++;
   }
   else
      pos = sepastore->ncuts;

   sepastore->cuts[pos] = cut;
   sepastore->efficacies[pos] = cutefficacy;
   sepastore->objparallelisms[pos] = cutobjparallelism;
   sepastore->orthogonalities[pos] = 1.0;
   sepastore->scores[pos] = cutscore;
   sepastore->ncuts++;

   /* check, if the row addition to separation storage events are tracked
    * if so, issue ROWADDEDSEPA event
    */
   if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWADDEDSEPA) != 0 )
   {
      SCIP_EVENT* event;

      SCIP_CALL( SCIPeventCreateRowAddedSepa(&event, blkmem, cut) );
      SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
   }

   return SCIP_OKAY;
}