/** problem writing method of reader */ static SCIP_DECL_READERWRITE(readerWriteCip) { /*lint --e{715}*/ int i; SCIPinfoMessage(scip, file, "STATISTICS\n"); SCIPinfoMessage(scip, file, " Problem name : %s\n", name); SCIPinfoMessage(scip, file, " Variables : %d (%d binary, %d integer, %d implicit integer, %d continuous)\n", nvars, nbinvars, nintvars, nimplvars, ncontvars); SCIPinfoMessage(scip, file, " Constraints : %d initial, %d maximal\n", startnconss, maxnconss); SCIPinfoMessage(scip, file, "OBJECTIVE\n"); SCIPinfoMessage(scip, file, " Sense : %s\n", objsense == SCIP_OBJSENSE_MINIMIZE ? "minimize" : "maximize"); if( !SCIPisZero(scip, objoffset) ) SCIPinfoMessage(scip, file, " Offset : %+.15g\n", objoffset); if( !SCIPisEQ(scip, objscale, 1.0) ) SCIPinfoMessage(scip, file, " Scale : %.15g\n", objscale); if( nvars > 0 ) { SCIPinfoMessage(scip, file, "VARIABLES\n"); for( i = 0; i < nvars; ++i ) { SCIP_CALL( SCIPprintVar(scip, vars[i], file) ); } } if( nfixedvars > 0 ) { SCIPinfoMessage(scip, file, "FIXED\n"); for( i = 0; i < nfixedvars; ++i ) { SCIP_CALL( SCIPprintVar(scip, fixedvars[i], file) ); } } if( nconss > 0 ) { SCIPinfoMessage(scip, file, "CONSTRAINTS\n"); for( i = 0; i < nconss; ++i ) { /* in case the transformed is written only constraint are posted which are enabled in the current node */ assert(!transformed || SCIPconsIsEnabled(conss[i])); SCIP_CALL( SCIPprintCons(scip, conss[i], file) ); SCIPinfoMessage(scip, file, ";\n"); } } *result = SCIP_SUCCESS; SCIPinfoMessage(scip, file, "END\n"); return SCIP_OKAY; }
/** creates variable */ SCIP_RETCODE SCIPcreateVarBinpacking( SCIP* scip, /**< SCIP data structure */ SCIP_VAR** var, /**< pointer to variable object */ const char* name, /**< name of variable, or NULL for automatic name creation */ SCIP_Real obj, /**< objective function value */ SCIP_Bool initial, /**< should var's column be present in the initial root LP? */ SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */ SCIP_VARDATA* vardata /**< user data for this specific variable */ ) { assert(scip != NULL); assert(var != NULL); /* create a basic variable object */ SCIP_CALL( SCIPcreateVarBasic(scip, var, name, 0.0, 1.0, obj, SCIP_VARTYPE_BINARY) ); assert(*var != NULL); /* set callback functions */ SCIPvarSetData(*var, vardata); SCIPvarSetDeltransData(*var, vardataDelTrans); /* set initial and removable flag */ SCIP_CALL( SCIPvarSetInitial(*var, initial) ); SCIP_CALL( SCIPvarSetRemovable(*var, removable) ); SCIPvarMarkDeletable(*var); SCIPdebug( SCIPprintVar(scip, *var, NULL) ); return SCIP_OKAY; }
static SCIP_Bool consdataCheck( SCIP* scip, /**< SCIP data structure */ SCIP_PROBDATA* probdata, /**< problem data */ SCIP_CONSDATA* consdata /**< constraint data */ ) { SCIP_VAR** vars; int nvars; SCIP_VARDATA* vardata; SCIP_VAR* var; int* consids; int nconsids; SCIP_Bool existid1; SCIP_Bool existid2; CONSTYPE type; int pos; int v; vars = SCIPprobdataGetVars(probdata); nvars = SCIPprobdataGetNVars(probdata); for( v = 0; v < nvars; ++v ) { var = vars[v]; /* if variables is locally fixed to zero continue */ if( SCIPvarGetLbLocal(var) < 0.5 ) continue; /* check if the packing which corresponds to the variable is feasible for this constraint */ vardata = SCIPvarGetData(var); nconsids = SCIPvardataGetNConsids(vardata); consids = SCIPvardataGetConsids(vardata); existid1 = SCIPsortedvecFindInt(consids, consdata->itemid1, nconsids, &pos); existid2 = SCIPsortedvecFindInt(consids, consdata->itemid2, nconsids, &pos); type = consdata->type; if( (type == SAME && existid1 != existid2) || (type == DIFFER && existid1 && existid2) ) { SCIPdebug( SCIPvardataPrint(scip, vardata, NULL) ); SCIPdebug( consdataPrint(scip, consdata, NULL) ); SCIPdebug( SCIPprintVar(scip, var, NULL) ); return FALSE; } } return TRUE; }
/** read variable */ static SCIP_RETCODE getVariable( SCIP* scip, /**< SCIP data structure */ CIPINPUT* cipinput, /**< CIP parsing data */ SCIP_Bool initial, /**< should var's column be present in the initial root LP? */ SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */ SCIP_Real objscale /**< objective scale */ ) { SCIP_Bool success; SCIP_VAR* var; char* buf; char* endptr; buf = cipinput->strbuf; if( strncmp(buf, "FIXED", 5) == 0 ) cipinput->section = CIP_FIXEDVARS; else if( strncmp(buf, "CONSTRAINTS", 4) == 0 ) cipinput->section = CIP_CONSTRAINTS; else if( strncmp(buf, "END", 3) == 0 ) cipinput->section = CIP_END; if( cipinput->section != CIP_VARS ) return SCIP_OKAY; SCIPdebugMessage("parse variable\n"); /* parse the variable */ SCIP_CALL( SCIPparseVar(scip, &var, buf, initial, removable, NULL, NULL, NULL, NULL, NULL, &endptr, &success) ); if( !success ) { SCIPerrorMessage("syntax error in variable information (line: %d):\n%s\n", cipinput->linenumber, cipinput->strbuf); cipinput->haserror = TRUE; return SCIP_OKAY; } if( objscale != 1.0 ) { SCIP_CALL( SCIPchgVarObj(scip, var, SCIPvarGetObj(var) * objscale) ); } SCIP_CALL( SCIPaddVar(scip, var) ); SCIPdebug( SCIP_CALL( SCIPprintVar(scip, var, NULL) ) ); SCIP_CALL( SCIPreleaseVar(scip, &var) ); return SCIP_OKAY; }
/** creates variable */ SCIP_RETCODE SCIPcreateVarBinpacking( SCIP* scip, /**< SCIP data structure */ SCIP_VAR** var, /**< pointer to variable object */ const char* name, /**< name of variable, or NULL for automatic name creation */ SCIP_Real obj, /**< objective function value */ SCIP_Bool initial, /**< should var's column be present in the initial root LP? */ SCIP_Bool removable, /**< is var's column removable from the LP (due to aging or cleanup)? */ SCIP_VARDATA* vardata /**< user data for this specific variable */ ) { SCIP_CALL( SCIPcreateVar(scip, var, name, 0.0, 1.0, obj, SCIP_VARTYPE_BINARY, initial, removable, vardataDelOrig, vardataTrans, vardataDelTrans, vardataCopy, vardata) ); SCIPvarMarkDeletable(*var); SCIPdebug(SCIPprintVar(scip, *var, NULL) ); return SCIP_OKAY; }
/** problem writing method of reader */ static SCIP_DECL_READERWRITE(readerWriteCip) { /*lint --e{715}*/ SCIP_HASHTABLE* varhash = NULL; SCIP_READERDATA* readerdata; int i; assert(reader != NULL); assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0); SCIPinfoMessage(scip, file, "STATISTICS\n"); SCIPinfoMessage(scip, file, " Problem name : %s\n", name); SCIPinfoMessage(scip, file, " Variables : %d (%d binary, %d integer, %d implicit integer, %d continuous)\n", nvars, nbinvars, nintvars, nimplvars, ncontvars); SCIPinfoMessage(scip, file, " Constraints : %d initial, %d maximal\n", startnconss, maxnconss); SCIPinfoMessage(scip, file, "OBJECTIVE\n"); SCIPinfoMessage(scip, file, " Sense : %s\n", objsense == SCIP_OBJSENSE_MINIMIZE ? "minimize" : "maximize"); if( !SCIPisZero(scip, objoffset) ) SCIPinfoMessage(scip, file, " Offset : %+.15g\n", objoffset); if( !SCIPisEQ(scip, objscale, 1.0) ) SCIPinfoMessage(scip, file, " Scale : %.15g\n", objscale); if ( nfixedvars > 0 ) { /* set up hash table for variables that have been written property (used for writing out fixed vars in the right order) */ SCIP_CALL( SCIPhashtableCreate(&varhash, SCIPblkmem(scip), SCIPcalcHashtableSize(10 * (nvars + nfixedvars)), hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) ); } if ( nvars + nfixedvars > 0 ) { SCIPinfoMessage(scip, file, "VARIABLES\n"); } if( nvars > 0 ) { for( i = 0; i < nvars; ++i ) { SCIP_VAR* var; var = vars[i]; assert( var != NULL ); SCIP_CALL( SCIPprintVar(scip, var, file) ); if ( varhash != NULL ) { /* add free variable to hashtable */ if ( ! SCIPhashtableExists(varhash, (void*) var) ) { SCIP_CALL( SCIPhashtableInsert(varhash, (void*) var) ); } } } } readerdata = SCIPreaderGetData(reader); assert(readerdata != NULL); if( readerdata->writefixedvars && nfixedvars > 0 ) { int nwritten = 0; SCIPinfoMessage(scip, file, "FIXED\n"); /* loop through variables until each has been written after the variables that it depends on have been written; this * requires several runs over the variables, but the depth (= number of loops) is usually small. */ while ( nwritten < nfixedvars ) { SCIPdebugMessage("written %d of %d fixed variables.\n", nwritten, nfixedvars); for (i = 0; i < nfixedvars; ++i) { SCIP_VAR* var; SCIP_VAR* tmpvar; var = fixedvars[i]; assert( var != NULL ); /* skip variables already written */ if ( SCIPhashtableExists(varhash, (void*) var) ) continue; switch ( SCIPvarGetStatus(var) ) { case SCIP_VARSTATUS_FIXED: /* fixed variables can simply be output and added to the hashtable */ SCIP_CALL( SCIPprintVar(scip, var, file) ); assert( ! SCIPhashtableExists(varhash, (void*) var) ); SCIP_CALL( SCIPhashtableInsert(varhash, (void*) var) ); ++nwritten; break; case SCIP_VARSTATUS_NEGATED: tmpvar = SCIPvarGetNegationVar(var); assert( tmpvar != NULL ); assert( var == SCIPvarGetNegatedVar(tmpvar) ); /* if the negated variable has been written, we can write the current variable */ if ( SCIPhashtableExists(varhash, (void*) tmpvar) ) { SCIP_CALL( SCIPprintVar(scip, var, file) ); assert( ! SCIPhashtableExists(varhash, (void*) var) ); SCIP_CALL( SCIPhashtableInsert(varhash, (void*) var) ); ++nwritten; } break; case SCIP_VARSTATUS_AGGREGATED: tmpvar = SCIPvarGetAggrVar(var); assert( tmpvar != NULL ); /* if the aggregating variable has been written, we can write the current variable */ if ( SCIPhashtableExists(varhash, (void*) tmpvar) ) { SCIP_CALL( SCIPprintVar(scip, var, file) ); assert( ! SCIPhashtableExists(varhash, (void*) var) ); SCIP_CALL( SCIPhashtableInsert(varhash, (void*) var) ); ++nwritten; } break; case SCIP_VARSTATUS_MULTAGGR: { SCIP_VAR** aggrvars; int naggrvars; int j; /* get the active representation */ SCIP_CALL( SCIPflattenVarAggregationGraph(scip, var) ); naggrvars = SCIPvarGetMultaggrNVars(var); aggrvars = SCIPvarGetMultaggrVars(var); assert(aggrvars != NULL || naggrvars == 0); for (j = 0; j < naggrvars; ++j) { if( !SCIPhashtableExists(varhash, (void*) aggrvars[j]) ) /*lint !e613*/ break; } /* if all multi-aggregating variables have been written, we can write the current variable */ if ( j >= naggrvars ) { SCIP_CALL( SCIPprintVar(scip, var, file) ); assert( ! SCIPhashtableExists(varhash, (void*) var) ); SCIP_CALL( SCIPhashtableInsert(varhash, (void*) var) ); ++nwritten; } break; } case SCIP_VARSTATUS_ORIGINAL: case SCIP_VARSTATUS_LOOSE: case SCIP_VARSTATUS_COLUMN: SCIPerrorMessage("Only fixed variables are allowed to be present in fixedvars list.\n"); SCIPABORT(); return SCIP_ERROR; /*lint !e527*/ } } } } if( nconss > 0 ) { SCIPinfoMessage(scip, file, "CONSTRAINTS\n"); for( i = 0; i < nconss; ++i ) { SCIP_CALL( SCIPprintCons(scip, conss[i], file) ); SCIPinfoMessage(scip, file, ";\n"); } } SCIPinfoMessage(scip, file, "END\n"); *result = SCIP_SUCCESS; if( nfixedvars > 0 ) SCIPhashtableFree(&varhash); else assert(varhash == NULL); return SCIP_OKAY; }
/** read fixed variable */ static SCIP_RETCODE getFixedVariable( SCIP* scip, /**< SCIP data structure */ CIPINPUT* cipinput /**< CIP parsing data */ ) { SCIP_Bool success; SCIP_VAR* var; char* buf; char* endptr; char name[SCIP_MAXSTRLEN]; buf = cipinput->strbuf; if( strncmp(buf, "CONSTRAINTS", 11) == 0 ) cipinput->section = CIP_CONSTRAINTS; else if( strncmp(buf, "END", 3) == 0 ) cipinput->section = CIP_END; if( cipinput->section != CIP_FIXEDVARS ) return SCIP_OKAY; SCIPdebugMessage("parse fixed variable\n"); /* parse the variable */ SCIP_CALL( SCIPparseVar(scip, &var, buf, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL, &endptr, &success) ); if( !success ) { SCIPerrorMessage("syntax error in variable information (line: %d):\n%s\n", cipinput->linenumber, cipinput->strbuf); cipinput->haserror = TRUE; return SCIP_OKAY; } /* skip intermediate stuff */ buf = endptr; while ( *buf != '\0' && (*buf == ' ' || *buf == ',') ) ++buf; /* check whether variable is fixed */ if ( strncmp(buf, "fixed:", 6) == 0 ) { SCIP_CALL( SCIPaddVar(scip, var) ); SCIPdebug( SCIP_CALL( SCIPprintVar(scip, var, NULL) ) ); } else if ( strncmp(buf, "negated:", 8) == 0 ) { SCIP_CONS* lincons; SCIP_VAR* negvar; SCIP_Real vals[2]; SCIP_VAR* vars[2]; buf += 8; /* we can just parse the next variable (ignoring all other information in between) */ SCIP_CALL( SCIPparseVarName(scip, buf, &negvar, &endptr) ); if ( negvar == NULL ) { SCIPerrorMessage("could not parse negated variable (line: %d):\n%s\n", cipinput->linenumber, cipinput->strbuf); cipinput->haserror = TRUE; return SCIP_OKAY; } assert(SCIPvarIsBinary(var)); assert(SCIPvarIsBinary(negvar)); SCIP_CALL( SCIPaddVar(scip, var) ); SCIPdebugMessage("creating negated variable <%s> (of <%s>) ...\n", SCIPvarGetName(var), SCIPvarGetName(negvar) ); SCIPdebug( SCIP_CALL( SCIPprintVar(scip, var, NULL) ) ); /* add linear constraint for negation */ (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "neg_%s", SCIPvarGetName(var) ); vars[0] = var; vars[1] = negvar; vals[0] = 1.0; vals[1] = 1.0; SCIPdebugMessage("coupling constraint:\n"); SCIP_CALL( SCIPcreateConsLinear(scip, &lincons, name, 2, vars, vals, 1.0, 1.0, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE) ); SCIPdebugPrintCons(scip, lincons, NULL); SCIP_CALL( SCIPaddCons(scip, lincons) ); SCIP_CALL( SCIPreleaseCons(scip, &lincons) ); } else if ( strncmp(buf, "aggregated:", 11) == 0 ) { /* handle (multi-)aggregated variables */ SCIP_CONS* lincons; SCIP_Real* vals; SCIP_VAR** vars; SCIP_Real rhs = 0.0; const char* str; int nvarssize = 20; int requsize; int nvars; buf += 11; SCIPdebugMessage("parsing aggregated variable <%s> ...\n", SCIPvarGetName(var)); /* first parse constant */ if ( ! SCIPstrToRealValue(buf, &rhs, &endptr) ) { SCIPerrorMessage("expected constant when aggregated variable information (line: %d):\n%s\n", cipinput->linenumber, buf); cipinput->haserror = TRUE; return SCIP_OKAY; } /* check whether constant is 0.0 */ str = endptr; while ( *str != '\0' && isspace(*str) ) ++str; /* if next char is '<' we found a variable -> constant is 0 */ if ( *str != '<' ) { SCIPdebugMessage("constant: %f\n", rhs); buf = endptr; } else { /* otherwise keep buf */ rhs = 0.0; } /* initialize buffers for storing the variables and values */ SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvarssize) ); SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvarssize) ); vars[0] = var; vals[0] = -1.0; --nvarssize; /* parse linear sum to get variables and coefficients */ SCIP_CALL( SCIPparseVarsLinearsum(scip, buf, &(vars[1]), &(vals[1]), &nvars, nvarssize, &requsize, &endptr, &success) ); if ( success && requsize > nvarssize ) { /* realloc buffers and try again */ nvarssize = requsize; SCIP_CALL( SCIPreallocBufferArray(scip, &vars, nvarssize + 1) ); SCIP_CALL( SCIPreallocBufferArray(scip, &vals, nvarssize + 1) ); SCIP_CALL( SCIPparseVarsLinearsum(scip, buf, &(vars[1]), &(vals[1]), &nvars, nvarssize, &requsize, &endptr, &success) ); assert( ! success || requsize <= nvarssize); /* if successful, then should have had enough space now */ } if( success ) { /* add aggregated variable */ SCIP_CALL( SCIPaddVar(scip, var) ); /* special handling of variables that seem to be slack variables of indicator constraints */ str = SCIPvarGetName(var); if ( strncmp(str, "indslack", 8) == 0 ) { (void) strcpy(name, "indlin"); (void) strncat(name, str+8, SCIP_MAXSTRLEN-7); } else if ( strncmp(str, "t_indslack", 10) == 0 ) { (void) strcpy(name, "indlin"); (void) strncat(name, str+10, SCIP_MAXSTRLEN-7); } else (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s", SCIPvarGetName(var) ); /* add linear constraint for (multi-)aggregation */ SCIPdebugMessage("coupling constraint:\n"); SCIP_CALL( SCIPcreateConsLinear(scip, &lincons, name, nvars + 1, vars, vals, -rhs, -rhs, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE) ); SCIPdebugPrintCons(scip, lincons, NULL); SCIP_CALL( SCIPaddCons(scip, lincons) ); SCIP_CALL( SCIPreleaseCons(scip, &lincons) ); } else { SCIPwarningMessage(scip, "Could not read (multi-)aggregated variable <%s>: dependent variables unkown - consider changing the order (line: %d):\n%s\n", SCIPvarGetName(var), cipinput->linenumber, buf); } SCIPfreeBufferArray(scip, &vals); SCIPfreeBufferArray(scip, &vars); } else { SCIPerrorMessage("unknown section when parsing variables (line: %d):\n%s\n", cipinput->linenumber, buf); cipinput->haserror = TRUE; return SCIP_OKAY; } SCIP_CALL( SCIPreleaseVar(scip, &var) ); return SCIP_OKAY; }
/** reduced cost pricing method of variable pricer for feasible LPs */ static SCIP_DECL_PRICERREDCOST(pricerRedcostBinpacking) { /*lint --e{715}*/ SCIP* subscip; SCIP_PRICERDATA* pricerdata; SCIP_CONS** conss; SCIP_VAR** vars; int* ids; SCIP_Bool addvar; SCIP_SOL** sols; int nsols; int s; int nitems; SCIP_Longint capacity; SCIP_Real timelimit; SCIP_Real memorylimit; assert(scip != NULL); assert(pricer != NULL); (*result) = SCIP_DIDNOTRUN; /* get the pricer data */ pricerdata = SCIPpricerGetData(pricer); assert(pricerdata != NULL); capacity = pricerdata->capacity; conss = pricerdata->conss; ids = pricerdata->ids; nitems = pricerdata->nitems; /* get the remaining time and memory limit */ SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) ); if( !SCIPisInfinity(scip, timelimit) ) timelimit -= SCIPgetSolvingTime(scip); SCIP_CALL( SCIPgetRealParam(scip, "limits/memory", &memorylimit) ); if( !SCIPisInfinity(scip, memorylimit) ) memorylimit -= SCIPgetMemUsed(scip)/1048576.0; /* initialize SCIP */ SCIP_CALL( SCIPcreate(&subscip) ); SCIP_CALL( SCIPincludeDefaultPlugins(subscip) ); /* create problem in sub SCIP */ SCIP_CALL( SCIPcreateProbBasic(subscip, "pricing") ); SCIP_CALL( SCIPsetObjsense(subscip, SCIP_OBJSENSE_MAXIMIZE) ); /* do not abort subproblem on CTRL-C */ SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) ); /* disable output to console */ SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) ); /* set time and memory limit */ SCIP_CALL( SCIPsetRealParam(subscip, "limits/time", timelimit) ); SCIP_CALL( SCIPsetRealParam(subscip, "limits/memory", memorylimit) ); SCIP_CALL( SCIPallocMemoryArray(subscip, &vars, nitems) ); /* initialization local pricing problem */ SCIP_CALL( initPricing(scip, pricerdata, subscip, vars) ); SCIPdebugMessage("solve pricer problem\n"); /* solve sub SCIP */ SCIP_CALL( SCIPsolve(subscip) ); sols = SCIPgetSols(subscip); nsols = SCIPgetNSols(subscip); addvar = FALSE; /* loop over all solutions and create the corresponding column to master if the reduced cost are negative for master, * that is the objective value i greater than 1.0 */ for( s = 0; s < nsols; ++s ) { SCIP_Bool feasible; SCIP_SOL* sol; /* the soultion should be sorted w.r.t. the objective function value */ assert(s == 0 || SCIPisFeasGE(subscip, SCIPgetSolOrigObj(subscip, sols[s-1]), SCIPgetSolOrigObj(subscip, sols[s]))); sol = sols[s]; assert(sol != NULL); /* check if solution is feasible in original sub SCIP */ SCIP_CALL( SCIPcheckSolOrig(subscip, sol, &feasible, FALSE, FALSE ) ); if( !feasible ) { SCIPwarningMessage(scip, "solution in pricing problem (capacity <%d>) is infeasible\n", capacity); continue; } /* check if the solution has a value greater than 1.0 */ if( SCIPisFeasGT(subscip, SCIPgetSolOrigObj(subscip, sol), 1.0) ) { SCIP_VAR* var; SCIP_VARDATA* vardata; int* consids; char strtmp[SCIP_MAXSTRLEN]; char name[SCIP_MAXSTRLEN]; int nconss; int o; int v; SCIPdebug( SCIP_CALL( SCIPprintSol(subscip, sol, NULL, FALSE) ) ); nconss = 0; (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "items"); SCIP_CALL( SCIPallocBufferArray(scip, &consids, nitems) ); /* check which variables are fixed -> which item belongs to this packing */ for( o = 0, v = 0; o < nitems; ++o ) { if( !SCIPconsIsEnabled(conss[o]) ) continue; assert(SCIPgetNFixedonesSetppc(scip, conss[o]) == 0); if( SCIPgetSolVal(subscip, sol, vars[v]) > 0.5 ) { (void) SCIPsnprintf(strtmp, SCIP_MAXSTRLEN, "_%d", ids[o]); strcat(name, strtmp); consids[nconss] = o; nconss++; } else assert( SCIPisFeasEQ(subscip, SCIPgetSolVal(subscip, sol, vars[v]), 0.0) ); v++; } SCIP_CALL( SCIPvardataCreateBinpacking(scip, &vardata, consids, nconss) ); /* create variable for a new column with objective function coefficient 0.0 */ SCIP_CALL( SCIPcreateVarBinpacking(scip, &var, name, 1.0, FALSE, TRUE, vardata) ); /* add the new variable to the pricer store */ SCIP_CALL( SCIPaddPricedVar(scip, var, 1.0) ); addvar = TRUE; /* change the upper bound of the binary variable to lazy since the upper bound is already enforced due to * the objective function the set covering constraint; The reason for doing is that, is to avoid the bound * of x <= 1 in the LP relaxation since this bound constraint would produce a dual variable which might have * a positive reduced cost */ SCIP_CALL( SCIPchgVarUbLazy(scip, var, 1.0) ); /* check which variable are fixed -> which orders belong to this packing */ for( v = 0; v < nconss; ++v ) { assert(SCIPconsIsEnabled(conss[consids[v]])); SCIP_CALL( SCIPaddCoefSetppc(scip, conss[consids[v]], var) ); } SCIPdebug(SCIPprintVar(scip, var, NULL) ); SCIP_CALL( SCIPreleaseVar(scip, &var) ); SCIPfreeBufferArray(scip, &consids); } else break; } /* free pricer MIP */ SCIPfreeMemoryArray(subscip, &vars); if( addvar || SCIPgetStatus(subscip) == SCIP_STATUS_OPTIMAL ) (*result) = SCIP_SUCCESS; /* free sub SCIP */ SCIP_CALL( SCIPfree(&subscip) ); return SCIP_OKAY; }