/** 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; }
/** 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; }
/** initializes the pricing problem for the given capacity */ static SCIP_RETCODE initPricing( SCIP* scip, /**< SCIP data structure */ SCIP_PRICERDATA* pricerdata, /**< pricer data */ SCIP* subscip, /**< pricing SCIP data structure */ SCIP_VAR** vars /**< variable array for the items */ ) { SCIP_CONS** conss; SCIP_Longint* vals; SCIP_CONS* cons; SCIP_VAR* var; SCIP_Longint* weights; SCIP_Longint capacity; SCIP_Real dual; int nitems; int nvars; int c; assert( SCIPgetStage(subscip) == SCIP_STAGE_PROBLEM ); assert(pricerdata != NULL); nitems = pricerdata->nitems; conss = pricerdata->conss; weights = pricerdata->weights; capacity = pricerdata->capacity; nvars = 0; SCIP_CALL( SCIPallocBufferArray(subscip, &vals, nitems) ); /* create for each order, which is not assigned yet, a variable with objective coefficient */ for( c = 0; c < nitems; ++c ) { cons = conss[c]; /* check if each constraint is setppc constraint */ assert( !strncmp( SCIPconshdlrGetName( SCIPconsGetHdlr(cons) ), "setppc", 6) ); /* constraints which are (locally) disabled/redundant are not of * interest since the corresponding job is assigned to a packing */ if( !SCIPconsIsEnabled(cons) ) continue; if( SCIPgetNFixedonesSetppc(scip, cons) == 1 ) { /* disable constraint locally */ SCIP_CALL( SCIPdelConsLocal(scip, cons) ); continue; } /* dual value in original SCIP */ dual = SCIPgetDualsolSetppc(scip, cons); SCIP_CALL( SCIPcreateVarBasic(subscip, &var, SCIPconsGetName(cons), 0.0, 1.0, dual, SCIP_VARTYPE_BINARY) ); SCIP_CALL( SCIPaddVar(subscip, var) ); vals[nvars] = weights[c]; vars[nvars] = var; nvars++; /* release variable */ SCIP_CALL( SCIPreleaseVar(subscip, &var) ); } /* create capacity constraint */ SCIP_CALL( SCIPcreateConsBasicKnapsack(subscip, &cons, "capacity", nvars, vars, vals, capacity) ); SCIP_CALL( SCIPaddCons(subscip, cons) ); SCIP_CALL( SCIPreleaseCons(subscip, &cons) ); /* add constraint of the branching decisions */ SCIP_CALL( addBranchingDecisionConss(scip, subscip, vars, pricerdata->conshdlr) ); /* avoid to generate columns which are fixed to zero */ SCIP_CALL( addFixedVarsConss(scip, subscip, vars, conss, nitems) ); SCIPfreeBufferArray(subscip, &vals); return SCIP_OKAY; }
/** avoid to generate columns which are fixed to zero; therefore add for each variable which is fixed to zero a * corresponding logicor constraint to forbid this column * * @note variable which are fixed locally to zero should not be generated again by the pricing MIP */ static SCIP_RETCODE addFixedVarsConss( SCIP* scip, /**< SCIP data structure */ SCIP* subscip, /**< pricing SCIP data structure */ SCIP_VAR** vars, /**< variable array of the subscuip */ SCIP_CONS** conss, /**< array of setppc constraint for each item one */ int nitems /**< number of items */ ) { SCIP_VAR** origvars; int norigvars; SCIP_CONS* cons; int* consids; int nconsids; int consid; int nvars; SCIP_VAR** logicorvars; SCIP_VAR* var; SCIP_VARDATA* vardata; SCIP_Bool needed; int nlogicorvars; int v; int c; int o; /* collect all variable which are currently existing */ origvars = SCIPgetVars(scip); norigvars = SCIPgetNVars(scip); /* loop over all these variables and check if they are fixed to zero */ for( v = 0; v < norigvars; ++v ) { assert(SCIPvarGetType(origvars[v]) == SCIP_VARTYPE_BINARY); /* if the upper bound is smaller than 0.5 if follows due to the integrality that the binary variable is fixed to zero */ if( SCIPvarGetUbLocal(origvars[v]) < 0.5 ) { SCIPdebugMessage("variable <%s> glb=[%.15g,%.15g] loc=[%.15g,%.15g] is fixed to zero\n", SCIPvarGetName(origvars[v]), SCIPvarGetLbGlobal(origvars[v]), SCIPvarGetUbGlobal(origvars[v]), SCIPvarGetLbLocal(origvars[v]), SCIPvarGetUbLocal(origvars[v]) ); /* coolect the constraints/items the variable belongs to */ vardata = SCIPvarGetData(origvars[v]); nconsids = SCIPvardataGetNConsids(vardata); consids = SCIPvardataGetConsids(vardata); needed = TRUE; SCIP_CALL( SCIPallocBufferArray(subscip, &logicorvars, nitems) ); nlogicorvars = 0; consid = consids[0]; nvars = 0; /* loop over these items and create a linear (logicor) constraint which forbids this item combination in the * pricing problem; thereby check if this item combination is already forbidden */ for( c = 0, o = 0; o < nitems && needed; ++o ) { assert(o <= consid); cons = conss[o]; if( SCIPconsIsEnabled(cons) ) { assert( SCIPgetNFixedonesSetppc(scip, cons) == 0 ); var = vars[nvars]; nvars++; assert(var != NULL); if( o == consid ) { SCIP_CALL( SCIPgetNegatedVar(subscip, var, &var) ); } logicorvars[nlogicorvars] = var; nlogicorvars++; } else if( o == consid ) needed = FALSE; if( o == consid ) { c++; if ( c == nconsids ) consid = nitems + 100; else { assert(consid < consids[c]); consid = consids[c]; } } } if( needed ) { SCIP_CALL( SCIPcreateConsBasicLogicor(subscip, &cons, SCIPvarGetName(origvars[v]), nlogicorvars, logicorvars) ); SCIP_CALL( SCIPsetConsInitial(subscip, cons, FALSE) ); SCIP_CALL( SCIPaddCons(subscip, cons) ); SCIP_CALL( SCIPreleaseCons(subscip, &cons) ); } SCIPfreeBufferArray(subscip, &logicorvars); } } return SCIP_OKAY; }
/** writes problem to file */ SCIP_RETCODE SCIPwriteCcg( SCIP* scip, /**< SCIP data structure */ FILE* file, /**< output file, or NULL if standard output should be used */ const char* name, /**< problem name */ SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */ SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */ int nvars, /**< number of active variables in the problem */ SCIP_CONS** conss, /**< array with constraints of the problem */ int nconss, /**< number of constraints in the problem */ SCIP_RESULT* result /**< pointer to store the result of the file writing call */ ) { /*lint --e{715}*/ int c; int v; int i; SCIP_CONSHDLR* conshdlr; const char* conshdlrname; SCIP_CONS* cons; SCIP_VAR** consvars; SCIP_Real* consvals; int nconsvars; SparseGraph G; assert( scip != NULL ); assert( nvars >= 0 ); /* initialize graph */ SCIP_CALL( initGraph(scip, &G, (unsigned int) nvars, 10) ); /* check all constraints */ for( c = 0; c < nconss; ++c) { cons = conss[c]; assert( cons != NULL); /* in case the transformed is written only constraint are posted which are enabled in the current node */ assert(!transformed || SCIPconsIsEnabled(cons)); conshdlr = SCIPconsGetHdlr(cons); assert( conshdlr != NULL ); conshdlrname = SCIPconshdlrGetName(conshdlr); assert( transformed == SCIPconsIsTransformed(cons) ); if( strcmp(conshdlrname, "linear") == 0 ) { consvars = SCIPgetVarsLinear(scip, cons); nconsvars = SCIPgetNVarsLinear(scip, cons); assert( consvars != NULL || nconsvars == 0 ); if( nconsvars > 0 ) { SCIP_CALL( handleLinearCons(scip, SCIPgetVarsLinear(scip, cons), SCIPgetValsLinear(scip, cons), SCIPgetNVarsLinear(scip, cons), transformed, &G) ); } } else if( strcmp(conshdlrname, "setppc") == 0 ) { consvars = SCIPgetVarsSetppc(scip, cons); nconsvars = SCIPgetNVarsSetppc(scip, cons); assert( consvars != NULL || nconsvars == 0 ); if( nconsvars > 0 ) { SCIP_CALL( handleLinearCons(scip, consvars, NULL, nconsvars, transformed, &G) ); } } else if( strcmp(conshdlrname, "logicor") == 0 ) { consvars = SCIPgetVarsLogicor(scip, cons); nconsvars = SCIPgetNVarsLogicor(scip, cons); assert( consvars != NULL || nconsvars == 0 ); if( nconsvars > 0 ) { SCIP_CALL( handleLinearCons(scip, SCIPgetVarsLogicor(scip, cons), NULL, SCIPgetNVarsLogicor(scip, cons), transformed, &G) ); } } else if( strcmp(conshdlrname, "knapsack") == 0 ) { SCIP_Longint* w; consvars = SCIPgetVarsKnapsack(scip, cons); nconsvars = SCIPgetNVarsKnapsack(scip, cons); assert( consvars != NULL || nconsvars == 0 ); /* copy Longint array to SCIP_Real array */ w = SCIPgetWeightsKnapsack(scip, cons); SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) ); for( v = 0; v < nconsvars; ++v ) consvals[v] = (SCIP_Real)w[v]; if( nconsvars > 0 ) { SCIP_CALL( handleLinearCons(scip, consvars, consvals, nconsvars, transformed, &G) ); } SCIPfreeBufferArray(scip, &consvals); } else if( strcmp(conshdlrname, "varbound") == 0 ) { SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) ); SCIP_CALL( SCIPallocBufferArray(scip, &consvals, 2) ); consvars[0] = SCIPgetVarVarbound(scip, cons); consvars[1] = SCIPgetVbdvarVarbound(scip, cons); consvals[0] = 1.0; consvals[1] = SCIPgetVbdcoefVarbound(scip, cons); SCIP_CALL( handleLinearCons(scip, consvars, consvals, 2, transformed, &G) ); SCIPfreeBufferArray(scip, &consvars); SCIPfreeBufferArray(scip, &consvals); } else { SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname ); SCIPinfoMessage(scip, file, "\\ "); SCIP_CALL( SCIPprintCons(scip, cons, file) ); SCIPinfoMessage(scip, file, ";\n"); } } /* output graph */ SCIPinfoMessage(scip, file, "c graph generated from %s\n", name); SCIPinfoMessage(scip, file, "p edge %d %d\n", nvars, G.m); for( i = 0; i < nvars; ++i ) { unsigned int k; int a; k = 0; a = G.A[i][k]; while( a >= 0 ) { /* only output edges from lower to higher number */ if( i < a ) { /* note: node numbers start with 1 in the DIMACS format */ SCIPinfoMessage(scip, file, "e %d %d %f\n", i+1, a+1, G.W[i][k]); } a = G.A[i][++k]; assert( k <= G.size[i] ); } assert( k == G.deg[i] ); } freeGraph(scip, &G); *result = SCIP_SUCCESS; return SCIP_OKAY; }
/** writes problem to file */ SCIP_RETCODE SCIPwritePpm( SCIP* scip, /**< SCIP data structure */ FILE* file, /**< output file, or NULL if standard output should be used */ const char* name, /**< problem name */ SCIP_READERDATA* readerdata, /**< information for reader */ SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */ SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */ int nvars, /**< number of active variables in the problem */ SCIP_CONS** conss, /**< array with constraints of the problem */ int nconss, /**< number of constraints in the problem */ SCIP_RESULT* result /**< pointer to store the result of the file writing call */ ) { /*lint --e{715}*/ int c; int v; int i; int linecnt; char linebuffer[PPM_MAX_LINELEN]; SCIP_CONSHDLR* conshdlr; const char* conshdlrname; SCIP_CONS* cons; SCIP_VAR** consvars; SCIP_Real* consvals; int nconsvars; int i_max = 1; SCIP_Real maxcoef = 0; SCIP_Bool printbool = FALSE; assert( scip != NULL ); assert(readerdata != NULL); /* print statistics as comment to file */ if(readerdata->rgb_ascii) SCIPinfoMessage(scip, file, "P6\n"); else SCIPinfoMessage(scip, file, "P3\n"); SCIPinfoMessage(scip, file, "# %s\n", name); SCIPinfoMessage(scip, file, "%d %d\n", nvars, nconss); SCIPinfoMessage(scip, file, "255\n"); clearLine(linebuffer, &linecnt); if(!(readerdata->rgb_relativ)) { i_max = 2; } for(i = 0; i < i_max; ++i) { if(i) { printbool = TRUE; SCIPdebugPrintf("Maximal coefficient = %g\n", maxcoef); } for(c = 0; c < nconss; ++c) { cons = conss[c]; assert( cons != NULL); /* in case the transformed is written only constraint are posted which are enabled in the current node */ assert(!transformed || SCIPconsIsEnabled(cons)); conshdlr = SCIPconsGetHdlr(cons); assert( conshdlr != NULL ); conshdlrname = SCIPconshdlrGetName(conshdlr); assert( transformed == SCIPconsIsTransformed(cons) ); if( strcmp(conshdlrname, "linear") == 0 ) { consvars = SCIPgetVarsLinear(scip, cons); nconsvars = SCIPgetNVarsLinear(scip, cons); assert( consvars != NULL || nconsvars == 0 ); if( nconsvars > 0 ) { SCIP_CALL( printLinearCons(scip, file, readerdata, consvars, SCIPgetValsLinear(scip, cons), nconsvars, nvars, transformed, &maxcoef, printbool) ); } } else if( strcmp(conshdlrname, "setppc") == 0 ) { consvars = SCIPgetVarsSetppc(scip, cons); nconsvars = SCIPgetNVarsSetppc(scip, cons); assert( consvars != NULL || nconsvars == 0 ); if( nconsvars > 0 ) { SCIP_CALL( printLinearCons(scip, file, readerdata, consvars, NULL, nconsvars, nvars, transformed, &maxcoef, printbool) ); } } else if( strcmp(conshdlrname, "logicor") == 0 ) { consvars = SCIPgetVarsLogicor(scip, cons); nconsvars = SCIPgetNVarsLogicor(scip, cons); assert( consvars != NULL || nconsvars == 0 ); if( nconsvars > 0 ) { SCIP_CALL( printLinearCons(scip, file, readerdata, consvars, NULL, nconsvars, nvars, transformed, &maxcoef, printbool) ); } } else if( strcmp(conshdlrname, "knapsack") == 0 ) { SCIP_Longint* weights; consvars = SCIPgetVarsKnapsack(scip, cons); nconsvars = SCIPgetNVarsKnapsack(scip, cons); assert( consvars != NULL || nconsvars == 0 ); /* copy Longint array to SCIP_Real array */ weights = SCIPgetWeightsKnapsack(scip, cons); SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) ); for( v = 0; v < nconsvars; ++v ) consvals[v] = (SCIP_Real)weights[v]; if( nconsvars > 0 ) { SCIP_CALL( printLinearCons(scip, file, readerdata, consvars, consvals, nconsvars, nvars, transformed, &maxcoef, printbool) ); } SCIPfreeBufferArray(scip, &consvals); } else if( strcmp(conshdlrname, "varbound") == 0 ) { SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) ); SCIP_CALL( SCIPallocBufferArray(scip, &consvals, 2) ); consvars[0] = SCIPgetVarVarbound(scip, cons); consvars[1] = SCIPgetVbdvarVarbound(scip, cons); consvals[0] = 1.0; consvals[1] = SCIPgetVbdcoefVarbound(scip, cons); SCIP_CALL( printLinearCons(scip, file, readerdata, consvars, consvals, 2, nvars, transformed, &maxcoef, printbool) ); SCIPfreeBufferArray(scip, &consvars); SCIPfreeBufferArray(scip, &consvals); } else { SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname ); SCIPinfoMessage(scip, file, "\\ "); SCIP_CALL( SCIPprintCons(scip, cons, file) ); SCIPinfoMessage(scip, file, ";\n"); } } } *result = SCIP_SUCCESS; return SCIP_OKAY; }