I’m pretty new to the world of OR and SCIP and I’m having some trouble understanding the Subscip idea in SCIP or the example I’m referring to. I have a complex 2D cutting stock problem and I’m trying to use and understand the Branch And Price Bin Packing example on the SCIP website (https://scipopt.org/scip/doc/html/BINPACKING_MAIN.php).
I have modified some of the code to better suit my own problem. I’m aware that this won’t really work for now, I’m missing a fitting branch and price and so on, but I would have guessed that I would at least get a valid knapsack solution in the pricing problem. I assumed that the defined subproblem was an empty problem that did not use any solutions from the original master problem. Here is the initPricing function:
SCIP_RETCODE initPricing(...)
{
SCIP_CONS** conss;
SCIP_Longint* vals;
SCIP_CONS* cons;
SCIP_VAR* var;
int* demands;
SCIP_Longint* widths;
SCIP_Longint* heights;
SCIP_Longint binWidth;
SCIP_Longint binHeight;
SCIP_Real dual;
SCIP_CALL( SCIPallocBufferArray(subscip, &vals, nitems) );
for( c = 0; c < nitems; ++c )
{
cons = conss[c];
if( !SCIPconsIsEnabled(cons) )
continue;
dual = SCIPgetDualsolLinear(scip, cons);
SCIP_CALL( SCIPcreateVarBasic(subscip, &var, NULL, 0.0, demands[c], dual, SCIP_VARTYPE_INTEGER) );
SCIP_CALL( SCIPaddVar(subscip, var) );
vals[nvars] = widths[c] * heights[c];
vars[nvars] = var;
nvars++;
SCIP_CALL( SCIPreleaseVar(subscip, &var) );
}
SCIP_CALL( SCIPcreateConsBasicKnapsack(subscip, &cons, "capacity", nvars, vars, vals, binWidth * binHeight) );
SCIP_CALL( SCIPaddCons(subscip, cons) );
SCIP_CALL( SCIPreleaseCons(subscip, &cons) );
SCIPfreeBufferArray(subscip, &vals);
// TODO add branching decision constraints ...
return SCIP_OKAY;
And here is a part of my doPricing function:
SCIP_RETCODE doPricing(...)
{
SCIP* subscip;
SCIP_PRICERDATA* pricerdata;
SCIP_CONS** conss;
SCIP_VAR** vars;
int* ids;
...
SCIP_CALL( SCIPcreate(&subscip) );
SCIP_CALL( SCIPincludeDefaultPlugins(subscip) );
SCIP_CALL( SCIPcreateProbBasic(subscip, "pricing") );
SCIP_CALL( SCIPsetObjsense(subscip, SCIP_OBJSENSE_MAXIMIZE) );
/* allocate in orginal scip, since otherwise the buffer counts in subscip are not correct */
SCIP_CALL( SCIPallocBufferArray(scip, &vars, nitems) );
/* initialization local pricing problem */
SCIP_CALL( initPricing(scip, pricerdata, isfarkas, subscip, vars));
//SCIP_CALL( SCIPsetIntParam(subscip, "presolving/maxrounds", 0) );
SCIP_CALL( SCIPsolve(subscip) );
}
When I call SCIP_CALL( SCIPsolve(subscip) ); the first solution is always the solution of my master problem instead of a valid solution of the knapsack. If I keep presolve enabled, that’s the only solution I get, next to 0. The transformed model doesn’t contain my knapsack capacity constraint and all variables are fixed to the solution of the master. So I assume that presolve uses the master solution to perform some kind of warmstart and for the solution to become valid it removes my constraint ? When presolve is disabled their is a third valid solution, which than is a valid new column for my problem.
I assume that I am basically missing something here. Perhaps someone could give me a hint. If more code is needed, I’m happy to provide it, but I didn’t want to blow up the question.