Exemplo n.º 1
0
/** checks the consistency of the origbranch constraints in the problem */
void GCGconsOrigbranchCheckConsistency(
   SCIP*                 scip                /**< SCIP data structure */
   )
{
#ifdef CHECKCONSISTENCY

   SCIP_CONSHDLR*     conshdlr;

#ifndef NDEBUG
   SCIP_CONS** conss;
   int nconss;
   int i;
   SCIP_CONSDATA* consdata;
#endif

   assert(scip != NULL);
   conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
   if( conshdlr == NULL )
   {
      SCIPerrorMessage("origbranch constraint handler not found\n");
      return;
   }
#ifndef NDEBUG
   conss = SCIPconshdlrGetConss(conshdlr);
   nconss = SCIPconshdlrGetNConss(conshdlr);

   for( i = 0; i < nconss; i++ )
   {
      consdata = SCIPconsGetData(conss[i]);
      assert(consdata != NULL);
      assert(consdata->node != NULL);
      assert((consdata->parentcons == NULL) == (SCIPnodeGetDepth(consdata->node) == 0));
      assert(consdata->parentcons == NULL || SCIPconsGetData(consdata->parentcons)->child1cons == conss[i]
         || SCIPconsGetData(consdata->parentcons)->child2cons == conss[i]
         || ( SCIPinProbing(scip) && SCIPconsGetData(consdata->parentcons)->probingtmpcons == conss[i]));
      assert(consdata->child1cons == NULL || SCIPconsGetData(consdata->child1cons)->parentcons == conss[i]);
      assert(consdata->child2cons == NULL || SCIPconsGetData(consdata->child2cons)->parentcons == conss[i]);
      assert(consdata->probingtmpcons == NULL || SCIPinProbing(scip));
      assert(consdata->probingtmpcons == NULL || SCIPconsGetData(consdata->probingtmpcons)->parentcons == conss[i]);
      assert(consdata->mastercons == NULL ||
         GCGconsMasterbranchGetOrigcons(consdata->mastercons) == conss[i]);
   }
#endif
#endif
}
Exemplo n.º 2
0
/** execution method of propagator */
static
SCIP_DECL_PROPEXEC(propExecDualfix)
{  /*lint --e{715}*/
   int nfixedvars;
   SCIP_Bool cutoff;
   SCIP_Bool unbounded;

   assert(prop != NULL);
   assert(strcmp(SCIPpropGetName(prop), PROP_NAME) == 0);
   assert(result != NULL);

   *result = SCIP_DIDNOTRUN;

   /** @warning Don't run in probing or in repropagation since this can lead to wrong conclusion
    *
    *  do not run if propagation w.r.t. current objective is not allowed
    */
   if( SCIPinProbing(scip) || SCIPinRepropagation(scip) || !SCIPallowDualReds(scip) )
      return SCIP_OKAY;

   cutoff = FALSE;
   unbounded = FALSE;
   nfixedvars = 0;

   SCIP_CALL( performDualfix(scip, &nfixedvars, &unbounded, &cutoff) );

   /* evaluate propagation result */
   if( cutoff )
      *result = SCIP_CUTOFF;
   else if( unbounded )
      *result = SCIP_UNBOUNDED;
   else if( nfixedvars > 0 )
      *result = SCIP_REDUCEDDOM;
   else
      *result = SCIP_DIDNOTFIND;

   return SCIP_OKAY;
}
Exemplo n.º 3
0
/** perform randomized rounding of the given solution. Domain propagation is optionally applied after every rounding
 *  step
 */
static
SCIP_RETCODE performRandRounding(
   SCIP*                 scip,               /**< SCIP main data structure */
   SCIP_HEURDATA*        heurdata,           /**< heuristic data */
   SCIP_SOL*             sol,                /**< solution to round */
   SCIP_VAR**            cands,              /**< candidate variables */
   int                   ncands,             /**< number of candidates */
   SCIP_Bool             propagate,          /**< should the rounding be propagated? */
   SCIP_RESULT*          result              /**< pointer to store the result of the heuristic call */
   )
{
   int c;
   SCIP_Bool stored;
   SCIP_VAR** permutedcands;
   SCIP_Bool cutoff;

   assert(heurdata != NULL);

   /* start probing tree before rounding begins */
   if( propagate )
   {
      SCIP_CALL( SCIPstartProbing(scip) );
      SCIPenableVarHistory(scip);
   }

   /* copy and permute the candidate array */
   SCIP_CALL( SCIPduplicateBufferArray(scip, &permutedcands, cands, ncands) );

   assert(permutedcands != NULL);

   SCIPpermuteArray((void **)permutedcands, 0, ncands, &heurdata->randseed);
   cutoff = FALSE;

   /* loop over candidates and perform randomized rounding and optionally probing. */
   for (c = 0; c < ncands && !cutoff; ++c)
   {
      SCIP_VAR* var;
      SCIP_Real oldsolval;
      SCIP_Real newsolval;
      SCIP_Bool mayrounddown;
      SCIP_Bool mayroundup;
      SCIP_Longint ndomreds;
      SCIP_Real lb;
      SCIP_Real ub;
      SCIP_Real ceilval;
      SCIP_Real floorval;

      /* get next variable from permuted candidate array */
      var = permutedcands[c];
      oldsolval = SCIPgetSolVal(scip, sol, var);
      lb = SCIPvarGetLbLocal(var);
      ub = SCIPvarGetUbLocal(var);

      assert( ! SCIPisFeasIntegral(scip, oldsolval) );
      assert( SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN );

      mayrounddown = SCIPvarMayRoundDown(var);
      mayroundup = SCIPvarMayRoundUp(var);
      ceilval = SCIPfeasCeil(scip, oldsolval);
      floorval = SCIPfeasFloor(scip, oldsolval);

      SCIPdebugMessage("rand rounding heuristic: var <%s>, val=%g, rounddown=%u, roundup=%u\n",
         SCIPvarGetName(var), oldsolval, mayrounddown, mayroundup);

      /* abort if rounded ceil and floor value lie outside the variable domain. Otherwise, check if
       * bounds allow only one rounding direction, anyway */
      if( lb > ceilval + 0.5 || ub < floorval - 0.5 )
      {
         cutoff = TRUE;
         break;
      }
      else if( SCIPisFeasEQ(scip, lb, ceilval) )
      {
         /* only rounding up possible */
         assert(SCIPisFeasGE(scip, ub, ceilval));
         newsolval = ceilval;
      }
      else if( SCIPisFeasEQ(scip, ub, floorval) )
      {
         /* only rounding down possible */
         assert(SCIPisFeasLE(scip,lb, floorval));
         newsolval = floorval;
      }
      else if( !heurdata->usesimplerounding || !(mayroundup || mayrounddown) )
      {
         /* the standard randomized rounding */
         SCIP_Real randnumber;

         randnumber = SCIPgetRandomReal(0.0, 1.0, &heurdata->randseed);
         if( randnumber <= oldsolval - floorval )
            newsolval = ceilval;
         else
            newsolval = floorval;
      }
      /* choose rounding direction, if possible, or use the only direction guaranteed to be feasible */
      else if( mayrounddown && mayroundup )
      {
         /* we can round in both directions: round in objective function direction */
         if ( SCIPvarGetObj(var) >= 0.0 )
            newsolval = floorval;
         else
            newsolval = ceilval;
      }
      else if( mayrounddown )
         newsolval = floorval;
      else
      {
         assert(mayroundup);
         newsolval = ceilval;
      }

      assert(SCIPisFeasLE(scip, lb, newsolval));
      assert(SCIPisFeasGE(scip, ub, newsolval));

      /* if propagation is enabled, fix the candidate variable to its rounded value and propagate the solution */
      if( propagate )
      {
         SCIP_Bool lbadjust;
         SCIP_Bool ubadjust;

         lbadjust = SCIPisGT(scip, newsolval, lb);
         ubadjust = SCIPisLT(scip, newsolval, ub);

         assert( lbadjust || ubadjust || SCIPisFeasEQ(scip, lb, ub));

         /* enter a new probing node if the variable was not already fixed before */
         if( lbadjust || ubadjust )
         {
            SCIP_RETCODE retcode;

            if( SCIPisStopped(scip) )
               break;

            retcode = SCIPnewProbingNode(scip);
            if( retcode == SCIP_MAXDEPTHLEVEL )
               break;

            SCIP_CALL( retcode );

            /* tighten the bounds to fix the variable for the probing node */
            if( lbadjust )
            {
               SCIP_CALL( SCIPchgVarLbProbing(scip, var, newsolval) );
            }
            if( ubadjust )
            {
               SCIP_CALL( SCIPchgVarUbProbing(scip, var, newsolval) );
            }

            /* call propagation routines for the reduced problem */
            SCIP_CALL( SCIPpropagateProbing(scip, heurdata->maxproprounds, &cutoff, &ndomreds) );
         }
      }
      /* store new solution value */
      SCIP_CALL( SCIPsetSolVal(scip, sol, var, newsolval) );
   }

   /* if no cutoff was detected, the solution is a candidate to be checked for feasibility */
   if( !cutoff && ! SCIPisStopped(scip) )
   {
      if( SCIPallColsInLP(scip) )
      {
         /* check solution for feasibility, and add it to solution store if possible
          * neither integrality nor feasibility of LP rows has to be checked, because all fractional
          * variables were already moved in feasible direction to the next integer
          */
         SCIP_CALL( SCIPtrySol(scip, sol, FALSE, FALSE, FALSE, TRUE, &stored) );
      }
      else
      {
         /* if there are variables which are not present in the LP, e.g., for
          * column generation, we need to check their bounds
          */
         SCIP_CALL( SCIPtrySol(scip, sol, FALSE, TRUE, FALSE, TRUE, &stored) );
      }

      if( stored )
      {
#ifdef SCIP_DEBUG
         SCIPdebugMessage("found feasible rounded solution:\n");
         SCIP_CALL( SCIPprintSol(scip, sol, NULL, FALSE) );
#endif
         *result = SCIP_FOUNDSOL;
      }
   }

   assert( !propagate || SCIPinProbing(scip) );

   /* exit probing mode and free locally allocated memory */
   if( propagate )
   {
      SCIP_CALL( SCIPendProbing(scip) );
   }

   SCIPfreeBufferArray(scip, &permutedcands);

   return SCIP_OKAY;
}
Exemplo n.º 4
0
/** execution method of presolver */
static
SCIP_DECL_PRESOLEXEC(presolExecDualagg)
{  /*lint --e{715}*/
   SCIPMILPMATRIX* matrix;
   SCIP_Bool initialized;
   SCIP_Bool complete;

   assert(result != NULL);
   *result = SCIP_DIDNOTRUN;

   if( (SCIPgetStage(scip) != SCIP_STAGE_PRESOLVING) || SCIPinProbing(scip) || SCIPisNLPEnabled(scip) )
      return SCIP_OKAY;

   if( SCIPisStopped(scip) || SCIPgetNActivePricers(scip) > 0 )
      return SCIP_OKAY;

   if( SCIPgetNBinVars(scip) == 0 )
      return SCIP_OKAY;

   if( !SCIPallowDualReds(scip) )
      return SCIP_OKAY;

   *result = SCIP_DIDNOTFIND;

   matrix = NULL;
   SCIP_CALL( SCIPmatrixCreate(scip, &matrix, &initialized, &complete) );

   /* we only work on pure MIPs currently */
   if( initialized && complete )
   {
      AGGRTYPE* aggtypes;
      SCIP_VAR** binvars;
      int nvaragg;
      int ncols;

      ncols = SCIPmatrixGetNColumns(matrix);
      nvaragg = 0;

      SCIP_CALL( SCIPallocBufferArray(scip, &aggtypes, ncols) );
      BMSclearMemoryArray(aggtypes, ncols);

      SCIP_CALL( SCIPallocBufferArray(scip, &binvars, ncols) );
      SCIPdebug( BMSclearMemoryArray(binvars, ncols) );

      /* search for aggregations */
      SCIP_CALL( findUplockAggregations(scip, matrix, &nvaragg, aggtypes, binvars) );
      SCIP_CALL( findDownlockAggregations(scip, matrix, &nvaragg, aggtypes, binvars) );

      /* apply aggregations, if we found any */
      if( nvaragg > 0 )
      {
         int v;

         for( v = 0; v < ncols; v++ )
         {
            if( aggtypes[v] != NOAGG )
            {
               SCIP_Bool infeasible;
               SCIP_Bool redundant;
               SCIP_Bool aggregated;
               SCIP_Real ub;
               SCIP_Real lb;

               ub = SCIPmatrixGetColUb(matrix, v);
               lb = SCIPmatrixGetColLb(matrix, v);

               /* aggregate variable */
               assert(binvars[v] != NULL);
               if( aggtypes[v] == BIN0UBOUND )
               {
                  SCIP_CALL( SCIPaggregateVars(scip, SCIPmatrixGetVar(matrix, v), binvars[v], 1.0, ub-lb,
                        ub, &infeasible, &redundant, &aggregated) );
               }
               else
               {
                  assert(aggtypes[v] == BIN0LBOUND);
                  SCIP_CALL( SCIPaggregateVars(scip, SCIPmatrixGetVar(matrix, v), binvars[v], 1.0, lb-ub,
                        lb, &infeasible, &redundant, &aggregated) );
               }

               /* infeasible aggregation */
               if( infeasible )
               {
                  SCIPdebugMessage(" -> infeasible aggregation\n");
                  *result = SCIP_CUTOFF;
                  return SCIP_OKAY;
               }

               if( aggregated )
                  (*naggrvars)++;
            }
         }

         /* set result pointer */
         if( (*naggrvars) > 0 )
            *result = SCIP_SUCCESS;
      }

      SCIPfreeBufferArray(scip, &binvars);
      SCIPfreeBufferArray(scip, &aggtypes);
   }

   SCIPmatrixFree(scip, &matrix);

   return SCIP_OKAY;
}
Exemplo n.º 5
0
/** creates and captures a origbranch constraint */
SCIP_RETCODE GCGcreateConsOrigbranch(
   SCIP*                 scip,               /**< SCIP data structure */
   SCIP_CONS**           cons,               /**< pointer to hold the created constraint */
   const char*           name,               /**< name of constraint */
   SCIP_NODE*            node,               /**< the node to which this origbranch constraint belongs */
   SCIP_CONS*            parentcons,         /**< origbranch constraint associated with the father node */
   SCIP_BRANCHRULE*      branchrule,         /**< the branching rule that created the b&b node the constraint belongs to */
   GCG_BRANCHDATA*       branchdata          /**< branching data storing information about the branching restrictions at the
                                              *   corresponding node */
   )
{
   SCIP_CONSHDLR* conshdlr;
   SCIP_CONSDATA* consdata;

   assert(scip != NULL);
   assert((parentcons == NULL) == (node == NULL));

   /* find the origbranch constraint handler */
   conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
   if( conshdlr == NULL )
   {
      SCIPerrorMessage("origbranch constraint handler not found\n");
      return SCIP_PLUGINNOTFOUND;
   }

   /* create constraint data */
   SCIP_CALL( SCIPallocBlockMemory(scip, &consdata) );

   /* initialize the fields in the constraint data */
   consdata->parentcons = parentcons;
   consdata->node = node;
   consdata->child1cons = NULL;
   consdata->child2cons = NULL;
   consdata->probingtmpcons = NULL;
   consdata->mastercons = NULL;
   consdata->branchrule = branchrule;
   consdata->branchdata = branchdata;
   consdata->npropbounds = 0;
   consdata->maxpropbounds = 0;
   consdata->propvars = NULL;
   consdata->propboundtypes = NULL;
   consdata->propbounds = NULL;

   SCIPdebugMessage("Creating branch orig constraint: <%s>.\n", name);

   /* create constraint */
   SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, FALSE, FALSE, FALSE, FALSE, FALSE,
         TRUE, FALSE, FALSE, FALSE, TRUE) );

   /* store the pointer to the new constraint in the origbranch constraint of the parent node */
   if( parentcons != NULL )
   {
      SCIP_CONSDATA* parentdata;

      parentdata = SCIPconsGetData(parentcons);
      assert(parentdata != NULL);

      if( parentdata->child1cons == NULL )
      {
         parentdata->child1cons = *cons;
      }
      else
      {
         assert(parentdata->child2cons == NULL || SCIPinProbing(scip));

         /* store the second child in case we are in probing and have to overwrite it */
         if( SCIPinProbing(scip) )
         {
            assert(parentdata->probingtmpcons == NULL);
            parentdata->probingtmpcons = parentdata->child2cons;
         }

         parentdata->child2cons = *cons;
      }
   }

   return SCIP_OKAY;
}
Exemplo n.º 6
0
/** frees specific constraint data */
static
SCIP_DECL_CONSDELETE(consDeleteOrigbranch)
{  /*lint --e{715}*/
   SCIP_CONSDATA* parentdata;

   assert(scip != NULL);
   assert(conshdlr != NULL);
   assert(cons != NULL);
   assert(consdata != NULL);
   assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
   assert(*consdata != NULL);

   SCIPdebugMessage("Deleting branch orig constraint: <%s>.\n", SCIPconsGetName(cons));

   /* set the origcons pointer of the corresponding mastercons to NULL */
   if( (*consdata)->mastercons != NULL )
      GCGconsMasterbranchSetOrigcons((*consdata)->mastercons, NULL);

   /* set the pointer in the parent constraint to NULL */
   if( (*consdata)->parentcons != NULL )
   {
      parentdata = SCIPconsGetData((*consdata)->parentcons);
      if( parentdata->child1cons == cons )
         parentdata->child1cons = NULL;
      else if( parentdata->probingtmpcons == cons )
      {
         assert(SCIPinProbing(scip));
         parentdata->probingtmpcons = NULL;
      }
      else
      {
         assert(parentdata->child2cons == cons);
         parentdata->child2cons = NULL;
         if( SCIPinProbing(scip) )
         {
            parentdata->child2cons = parentdata->probingtmpcons;
            parentdata->probingtmpcons = NULL;
         }
      }
   }
   /* no child nodes may exist */
   assert((*consdata)->child1cons == NULL);
   assert((*consdata)->child2cons == NULL);

   /* delete branchdata, if no mastercons is linked, which would still need the branchdata
    * otherwise, the mastercons deletes the branchdata when it is deleted itself */
   if( (*consdata)->mastercons == NULL && (*consdata)->branchdata != NULL )
   {
      SCIP_CALL( GCGrelaxBranchDataDelete(scip, (*consdata)->branchrule, &(*consdata)->branchdata) );
   }

   /* free propagation domain changes arrays */
   if( (*consdata)->maxpropbounds > 0 )
   {
      SCIPfreeMemoryArray(scip, &((*consdata)->propvars));
      SCIPfreeMemoryArray(scip, &((*consdata)->propboundtypes));
      SCIPfreeMemoryArray(scip, &((*consdata)->propbounds));
   }

   /* free constraint data */
   SCIPfreeBlockMemory(scip, consdata);

   return SCIP_OKAY;
}
/** process a variable from the queue of changed variables */
static
SCIP_RETCODE varProcessBoundChanges(
   SCIP*                 scip,               /**< SCIP data structure */
   SCIP_HEURDATA*        heurdata,           /**< heuristic data */
   SCIP_VAR*             var                 /**< the variable whose bound changes need to be processed */
   )
{
   SCIP_ROW** colrows;
   SCIP_COL* varcol;
   SCIP_Real* colvals;
   SCIP_Real oldmean;
   SCIP_Real newmean;
   SCIP_Real oldvariance;
   SCIP_Real newvariance;
   SCIP_Real oldlb;
   SCIP_Real newlb;
   SCIP_Real oldub;
   SCIP_Real newub;
   SCIP_VARTYPE vartype;
   int ncolrows;
   int r;
   int varindex;

   /* ensure that this is a probing bound change */
   assert(SCIPinProbing(scip));

   assert(var != NULL);
   varcol = SCIPvarGetCol(var);
   assert(varcol != NULL);
   colrows = SCIPcolGetRows(varcol);
   colvals = SCIPcolGetVals(varcol);
   ncolrows = SCIPcolGetNNonz(varcol);

   varindex = SCIPvarGetProbindex(var);

   oldlb = heurdata->currentlbs[varindex];
   oldub = heurdata->currentubs[varindex];

   /* skip update if the variable has never been subject of previously calculated row activities */
   assert((oldlb == SCIP_INVALID) == (oldub == SCIP_INVALID)); /*lint !e777 doesn't like comparing floats for equality */
   if( oldlb == SCIP_INVALID ) /*lint !e777 */
      return SCIP_OKAY;

   newlb = SCIPvarGetLbLocal(var);
   newub = SCIPvarGetUbLocal(var);

   /* skip update if the bound change events have cancelled out */
   if( SCIPisFeasEQ(scip, oldlb, newlb) && SCIPisFeasEQ(scip, oldub, newub) )
      return SCIP_OKAY;

   /* calculate old and new variable distribution mean and variance */
   oldvariance = 0.0;
   newvariance = 0.0;
   oldmean = 0.0;
   newmean = 0.0;
   vartype = SCIPvarGetType(var);
   SCIPvarCalcDistributionParameters(scip, oldlb, oldub, vartype, &oldmean, &oldvariance);
   SCIPvarCalcDistributionParameters(scip, newlb, newub, vartype, &newmean, &newvariance);

   /* loop over all rows of this variable and update activity distribution */
   for( r = 0; r < ncolrows; ++r )
   {
      int rowpos;

      assert(colrows[r] != NULL);
      rowpos = SCIProwGetIndex(colrows[r]);
      assert(rowpos >= 0);

      SCIP_CALL( heurdataEnsureArraySize(scip, heurdata, rowpos) );

      /* only consider rows for which activity distribution was already calculated */
      if( heurdata->rowmeans[rowpos] != SCIP_INVALID ) /*lint !e777 doesn't like comparing floats for equality */
      {
         SCIP_Real coeff;
         SCIP_Real coeffsquared;
         assert(heurdata->rowvariances[rowpos] != SCIP_INVALID
               && SCIPisFeasGE(scip, heurdata->rowvariances[rowpos], 0.0)); /*lint !e777 */

         coeff = colvals[r];
         coeffsquared = SQUARED(coeff);

         /* update variable contribution to row activity distribution */
         heurdata->rowmeans[rowpos] += coeff * (newmean - oldmean);
         heurdata->rowvariances[rowpos] += coeffsquared * (newvariance - oldvariance);
         heurdata->rowvariances[rowpos] = MAX(0.0, heurdata->rowvariances[rowpos]);

         /* account for changes of the infinite contributions to row activities */
         if( coeff > 0.0 )
         {
            /* if the coefficient is positive, upper bounds affect activity up */
            if( SCIPisInfinity(scip, newub) && !SCIPisInfinity(scip, oldub) )
               ++heurdata->rowinfinitiesup[rowpos];
            else if( !SCIPisInfinity(scip, newub) && SCIPisInfinity(scip, oldub) )
               --heurdata->rowinfinitiesup[rowpos];

            if( SCIPisInfinity(scip, newlb) && !SCIPisInfinity(scip, oldlb) )
               ++heurdata->rowinfinitiesdown[rowpos];
            else if( !SCIPisInfinity(scip, newlb) && SCIPisInfinity(scip, oldlb) )
               --heurdata->rowinfinitiesdown[rowpos];
         }
         else if( coeff < 0.0 )
         {
            if( SCIPisInfinity(scip, newub) && !SCIPisInfinity(scip, oldub) )
               ++heurdata->rowinfinitiesdown[rowpos];
            else if( !SCIPisInfinity(scip, newub) && SCIPisInfinity(scip, oldub) )
               --heurdata->rowinfinitiesdown[rowpos];

            if( SCIPisInfinity(scip, newlb) && !SCIPisInfinity(scip, oldlb) )
               ++heurdata->rowinfinitiesup[rowpos];
            else if( !SCIPisInfinity(scip, newlb) && SCIPisInfinity(scip, oldlb) )
               --heurdata->rowinfinitiesup[rowpos];
         }
         assert(heurdata->rowinfinitiesdown[rowpos] >= 0);
         assert(heurdata->rowinfinitiesup[rowpos] >= 0);
      }
   }

   /* store the new local bounds in the data */
   heurdataUpdateCurrentBounds(scip, heurdata, var);

   return SCIP_OKAY;
}