/** 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; }
/** adds problem variables with negative reduced costs to pricing storage */ SCIP_RETCODE SCIPpricestoreAddProbVars( SCIP_PRICESTORE* pricestore, /**< pricing storage */ BMS_BLKMEM* blkmem, /**< block memory buffers */ SCIP_SET* set, /**< global SCIP settings */ SCIP_STAT* stat, /**< dynamic problem statistics */ SCIP_PROB* prob, /**< transformed problem after presolve */ 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; SCIP_COL* col; SCIP_Bool root; SCIP_Bool added; int v; int abortpricevars; int maxpricevars; int nfoundvars; assert(pricestore != NULL); assert(set != NULL); assert(stat != NULL); assert(prob != NULL); assert(lp != NULL); assert(lp->solved); assert(tree != NULL); assert(SCIPtreeHasCurrentNodeLP(tree)); assert(prob->nvars >= SCIPlpGetNCols(lp)); /* if all problem variables of status COLUMN are already in the LP, nothing has to be done */ if( prob->ncolvars == SCIPlpGetNCols(lp) ) return SCIP_OKAY; root = (SCIPtreeGetCurrentDepth(tree) == 0); maxpricevars = SCIPsetGetPriceMaxvars(set, root); assert(maxpricevars >= 1); abortpricevars = (int)(set->price_abortfac * maxpricevars); assert(abortpricevars >= maxpricevars); /**@todo test pricing: is abortpricevars a good idea? -> like strong branching, lookahead, ... */ pricestore->nprobpricings++; /* start timing */ SCIPclockStart(pricestore->probpricingtime, set); /* price already existing problem variables */ nfoundvars = 0; for( v = 0; v < prob->nvars && nfoundvars < abortpricevars; ++v ) { var = prob->vars[v]; if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN ) { col = SCIPvarGetCol(var); assert(col != NULL); assert(col->var == var); assert(col->len >= 0); assert(col->lppos >= -1); assert(col->lpipos >= -1); assert(SCIPcolIsInLP(col) == (col->lpipos >= 0)); if( !SCIPcolIsInLP(col) ) { SCIPdebugMessage("price column variable <%s> in bounds [%g,%g]\n", SCIPvarGetName(var), SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)); /* add variable to pricing storage, if zero is not best bound w.r.t. objective function */ SCIP_CALL( addBoundViolated(pricestore, blkmem, set, stat, tree, lp, branchcand, eventqueue, var, &added) ); if( added ) { pricestore->nprobvarsfound++; nfoundvars++; } else if( SCIPcolGetNNonz(col) > 0 ) { SCIP_Real feasibility; /* a column not in LP that doesn't have zero in its bounds was added by bound checking above */ assert(!SCIPsetIsPositive(set, SCIPvarGetLbLocal(col->var))); assert(!SCIPsetIsNegative(set, SCIPvarGetUbLocal(col->var))); if( SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_INFEASIBLE ) { /* The LP was proven infeasible, so we have an infeasibility proof by the dual Farkas multipliers y. * The valid inequality y^T A x >= y^T b is violated by all x, especially by the (for this * inequality most feasible solution) x' defined by * x'_i = ub_i, if y^T A_i > 0 * x'_i = lb_i, if y^T A_i <= 0. * Pricing in this case means to add variables i with positive Farkas value, i.e. y^T A_i x'_i > 0 */ feasibility = -SCIPcolGetFarkasValue(col, stat, lp); SCIPdebugMessage(" <%s> Farkas feasibility: %e\n", SCIPvarGetName(col->var), feasibility); } else { /* The dual LP is feasible, and we have a feasible dual solution. Pricing in this case means to * add variables with negative feasibility, that is * - positive reduced costs for variables with negative lower bound * - negative reduced costs for variables with positive upper bound */ feasibility = SCIPcolGetFeasibility(col, set, stat, lp); SCIPdebugMessage(" <%s> reduced cost feasibility: %e\n", SCIPvarGetName(col->var), feasibility); } /* the score is -feasibility / (#nonzeros in column + 1) to prefer short columns * we must add variables with negative feasibility, but in order to not get a too large lower bound * due to missing columns, we better also add variables, that have a very small feasibility */ if( !SCIPsetIsPositive(set, feasibility) ) { SCIP_CALL( SCIPpricestoreAddVar(pricestore, blkmem, set, eventqueue, lp, var, -feasibility / (col->len+1), root) ); pricestore->nprobvarsfound++; nfoundvars++; } } } } } /* stop timing */ SCIPclockStop(pricestore->probpricingtime, set); return SCIP_OKAY; }