From beaa1258cc8bc65eb6fffcb465c19778a461d9f9 Mon Sep 17 00:00:00 2001 From: Stefan Vigerske Date: Fri, 6 Dec 2024 13:00:04 +0100 Subject: [PATCH 1/3] include struct_prob.h in header only if OPT=opt - should be needed for inlining macros only (only if NDEBUG) --- src/scip/prob.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/scip/prob.h b/src/scip/prob.h index 9cb159b10d..25372dd930 100644 --- a/src/scip/prob.h +++ b/src/scip/prob.h @@ -52,7 +52,9 @@ #include "scip/type_conflictstore.h" #include "scip/type_message.h" +#ifdef NDEBUG #include "scip/struct_prob.h" +#endif #ifdef __cplusplus extern "C" { From 435454c654617938058e34eac3d78633b295a120 Mon Sep 17 00:00:00 2001 From: Stefan Vigerske Date: Fri, 6 Dec 2024 18:03:02 +0100 Subject: [PATCH 2/3] use prob.h functions everywhere, add additional getter functions - do not rely SCIP_Prob struct being available --- src/scip/branch.c | 4 +-- src/scip/pricer.c | 8 +++--- src/scip/primal.c | 10 +++---- src/scip/prob.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++- src/scip/prob.h | 43 ++++++++++++++++++++++++++++ src/scip/reader.c | 30 +++++++++---------- src/scip/reopt.c | 4 +-- src/scip/tree.c | 12 ++++---- 8 files changed, 149 insertions(+), 35 deletions(-) diff --git a/src/scip/branch.c b/src/scip/branch.c index f376b4fff7..4a05728b44 100644 --- a/src/scip/branch.c +++ b/src/scip/branch.c @@ -807,9 +807,9 @@ SCIP_RETCODE SCIPbranchcandGetPseudoCands( /* pseudo branching candidates are non-fixed binary, integer, and implicit integer variables */ npcs = 0; - for( v = 0; v < prob->nbinvars + prob->nintvars + prob->nimplvars; ++v ) + for( v = 0; v < SCIPprobGetNBinVars(prob) + SCIPprobGetNIntVars(prob) + SCIPprobGetNImplVars(prob); ++v ) { - var = prob->vars[v]; + var = SCIPprobGetVars(prob)[v]; assert(var != NULL); assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN); assert(SCIPvarGetType(var) == SCIP_VARTYPE_BINARY diff --git a/src/scip/pricer.c b/src/scip/pricer.c index 6fa78bafec..b7211bbe00 100644 --- a/src/scip/pricer.c +++ b/src/scip/pricer.c @@ -413,7 +413,7 @@ SCIP_RETCODE SCIPpricerRedcost( SCIPsetDebugMsg(set, "executing reduced cost pricing of variable pricer <%s>\n", pricer->name); - oldnvars = prob->nvars; + oldnvars = SCIPprobGetNVars(prob); /* start timing */ SCIPclockStart(pricer->pricerclock, set); @@ -426,7 +426,7 @@ SCIP_RETCODE SCIPpricerRedcost( /* evaluate result */ pricer->ncalls++; - pricer->nvarsfound += prob->nvars - oldnvars; + pricer->nvarsfound += SCIPprobGetNVars(prob) - oldnvars; return SCIP_OKAY; } @@ -452,7 +452,7 @@ SCIP_RETCODE SCIPpricerFarkas( SCIPsetDebugMsg(set, "executing Farkas pricing of variable pricer <%s>\n", pricer->name); - oldnvars = prob->nvars; + oldnvars = SCIPprobGetNVars(prob); /* start timing */ SCIPclockStart(pricer->pricerclock, set); @@ -465,7 +465,7 @@ SCIP_RETCODE SCIPpricerFarkas( /* evaluate result */ pricer->ncalls++; - pricer->nvarsfound += prob->nvars - oldnvars; + pricer->nvarsfound += SCIPprobGetNVars(prob) - oldnvars; return SCIP_OKAY; } diff --git a/src/scip/primal.c b/src/scip/primal.c index efc9c4641c..04a23fca66 100644 --- a/src/scip/primal.c +++ b/src/scip/primal.c @@ -665,7 +665,7 @@ SCIP_RETCODE primalAddSol( /* make sure that the primal bound is at least the lower bound */ if( ! SCIPsetIsInfinity(set, obj) && ! SCIPsetIsInfinity(set, -SCIPgetLowerbound(set->scip)) && SCIPsetIsFeasGT(set, SCIPgetLowerbound(set->scip), obj) ) { - if( origprob->objsense == SCIP_OBJSENSE_MINIMIZE ) + if( SCIPprobGetObjsense(origprob) == SCIP_OBJSENSE_MINIMIZE ) { SCIPmessagePrintWarning(messagehdlr, "Dual bound %g is larger than the objective of the primal solution %g. The solution might not be optimal.\n", SCIPprobExternObjval(transprob, origprob, set, SCIPgetLowerbound(set->scip)), SCIPprobExternObjval(transprob, origprob, set, obj)); @@ -1834,10 +1834,10 @@ SCIP_RETCODE SCIPprimalTransformSol( assert(solvalssize == 0 || solvals != NULL); assert(solvalssize == 0 || solvalset != NULL); - origvars = origprob->vars; - norigvars = origprob->nvars; - transvars = transprob->vars; - ntransvars = transprob->nvars; + origvars = SCIPprobGetVars(origprob); + norigvars = SCIPprobGetNVars(origprob); + transvars = SCIPprobGetVars(transprob); + ntransvars = SCIPprobGetNVars(transprob); assert(solvalssize == 0 || solvalssize >= ntransvars); SCIPsetDebugMsg(set, "try to transfer original solution %p with objective %g into the transformed problem space\n", diff --git a/src/scip/prob.c b/src/scip/prob.c index 2330a5c8c9..5983da9ed6 100644 --- a/src/scip/prob.c +++ b/src/scip/prob.c @@ -2298,9 +2298,17 @@ void SCIPprobPrintStatistics( #undef SCIPprobGetNIntVars #undef SCIPprobGetNImplVars #undef SCIPprobGetNContVars -#undef SCIPprobGetNConss #undef SCIPprobGetVars +#undef SCIPprobGetNFixedVars +#undef SCIPprobGetFixedVars +#undef SCIPprobGetStartNVars +#undef SCIPprobGetNConss +#undef SCIPprobGetConss +#undef SCIPprobGetMaxNConss +#undef SCIPprobGetStartNConss +#undef SCIPprobGetObjsense #undef SCIPprobGetObjoffset +#undef SCIPprobGetObjscale #undef SCIPisConsCompressedEnabled #undef SCIPprobEnableConsCompression @@ -2443,6 +2451,33 @@ SCIP_VAR** SCIPprobGetVars( return prob->vars; } +/** gets number of fixed variables */ +int SCIPprobGetNFixedVars( + SCIP_PROB* prob /**< problem data */ + ) +{ + assert(prob != NULL); + return prob->nfixedvars; +} + +/** gets fixed variables */ +SCIP_VAR** SCIPprobGetFixedVars( + SCIP_PROB* prob /**< problem data */ + ) +{ + assert(prob != NULL); + return prob->fixedvars; +} + +/** gets number of variables existing when problem solving started */ +int SCIPprobGetStartNVars( + SCIP_PROB* prob /**< problem data */ + ) +{ + assert(prob != NULL); + return prob->startnvars; +} + /** gets number of problem constraints */ int SCIPprobGetNConss( SCIP_PROB* prob /**< problem data */ @@ -2452,6 +2487,42 @@ int SCIPprobGetNConss( return prob->nconss; } +/** gets problem constraints */ +SCIP_CONS** SCIPprobGetConss( + SCIP_PROB* prob /**< problem data */ + ) +{ + assert(prob != NULL); + return prob->conss; +} + +/** gets maximum number of constraints existing at the same time */ +int SCIPprobGetMaxNConss( + SCIP_PROB* prob /**< problem data */ + ) +{ + assert(prob != NULL); + return prob->maxnconss; +} + +/** gets number of constraints existing when problem solving started */ +int SCIPprobGetStartNConss( + SCIP_PROB* prob /**< problem data */ + ) +{ + assert(prob != NULL); + return prob->startnconss; +} + +/** gets the objective sense*/ +SCIP_OBJSENSE SCIPprobGetObjsense( + SCIP_PROB* prob /**< problem data */ + ) +{ + assert(prob != NULL); + return prob->objsense; +} + /** gets the objective offset */ SCIP_Real SCIPprobGetObjoffset( SCIP_PROB* prob /**< problem data */ diff --git a/src/scip/prob.h b/src/scip/prob.h index 25372dd930..f861874e52 100644 --- a/src/scip/prob.h +++ b/src/scip/prob.h @@ -51,6 +51,7 @@ #include "scip/type_cons.h" #include "scip/type_conflictstore.h" #include "scip/type_message.h" +#include "scip/type_misc.h" #ifdef NDEBUG #include "scip/struct_prob.h" @@ -607,11 +608,46 @@ SCIP_VAR** SCIPprobGetVars( SCIP_PROB* prob /**< problem data */ ); +/** gets number of fixed variables */ +int SCIPprobGetNFixedVars( + SCIP_PROB* prob /**< problem data */ + ); + +/** gets fixed variables */ +SCIP_VAR** SCIPprobGetFixedVars( + SCIP_PROB* prob /**< problem data */ + ); + +/** gets number of variables existing when problem solving started */ +int SCIPprobGetStartNVars( + SCIP_PROB* prob /**< problem data */ + ); + /** gets number of problem constraints */ int SCIPprobGetNConss( SCIP_PROB* prob /**< problem data */ ); +/** gets problem constraints */ +SCIP_CONS** SCIPprobGetConss( + SCIP_PROB* prob /**< problem data */ + ); + +/** gets maximum number of constraints existing at the same time */ +int SCIPprobGetMaxNConss( + SCIP_PROB* prob /**< problem data */ + ); + +/** gets number of constraints existing when problem solving started */ +int SCIPprobGetStartNConss( + SCIP_PROB* prob /**< problem data */ + ); + +/** gets the objective sense */ +SCIP_OBJSENSE SCIPprobGetObjsense( + SCIP_PROB* prob /**< problem data */ + ); + /** gets the objective offset */ SCIP_Real SCIPprobGetObjoffset( SCIP_PROB* prob /**< problem data */ @@ -654,7 +690,14 @@ void SCIPprobEnableConsCompression( #define SCIPprobGetNImplVars(prob) ((prob)->nimplvars) #define SCIPprobGetNContVars(prob) ((prob)->ncontvars) #define SCIPprobGetVars(prob) ((prob)->vars) +#define SCIPprobGetNFixedVars(prob) ((prob)->nfixedvars) +#define SCIPprobGetFixedVars(prob) ((prob)->fixedvars) +#define SCIPprobGetStartNVars(prob) ((prob)->startnvars) #define SCIPprobGetNConss(prob) ((prob)->nconss) +#define SCIPprobGetConss(prob) ((prob)->conss) +#define SCIPprobGetMaxNConss(prob) ((prob)->maxnconss) +#define SCIPprobGetStartNConss(prob) ((prob)->startnconss) +#define SCIPprobGetObjsense(prob) ((prob)->objsense) #define SCIPprobGetObjoffset(prob) ((prob)->objoffset) #define SCIPprobGetObjscale(prob) ((prob)->objscale) #define SCIPprobIsConsCompressionEnabled(prob) ((prob)->conscompression) diff --git a/src/scip/reader.c b/src/scip/reader.c index 4b7e820b3e..7a166fd415 100644 --- a/src/scip/reader.c +++ b/src/scip/reader.c @@ -303,13 +303,13 @@ SCIP_RETCODE SCIPreaderWrite( int nvars; int i; - vars = prob->vars; - nvars = prob->nvars; - fixedvars = prob->fixedvars; - nfixedvars = prob->nfixedvars; + vars = SCIPprobGetVars(prob); + nvars = SCIPprobGetNVars(prob); + fixedvars = SCIPprobGetFixedVars(prob); + nfixedvars = SCIPprobGetNFixedVars(prob); /* case of the transformed problem, we want to write currently valid problem */ - if( prob->transformed ) + if( SCIPprobIsTransformed(prob) ) { SCIP_CONSHDLR** conshdlrs; int nconshdlrs; @@ -365,8 +365,8 @@ SCIP_RETCODE SCIPreaderWrite( } else { - conss = prob->conss; - nconss = prob->nconss; + conss = SCIPprobGetConss(prob); + nconss = SCIPprobGetNConss(prob); } if( genericnames ) @@ -426,16 +426,16 @@ SCIP_RETCODE SCIPreaderWrite( } /* adapt objective scale for transformed problem (for the original no change is necessary) */ - objscale = prob->objscale; - if( prob->transformed && prob->objsense == SCIP_OBJSENSE_MAXIMIZE ) + objscale = SCIPprobGetObjscale(prob); + if( SCIPprobIsTransformed(prob) && SCIPprobGetObjsense(prob) == SCIP_OBJSENSE_MAXIMIZE ) objscale *= -1.0; /* call reader to write problem */ - retcode = reader->readerwrite(set->scip, reader, file, prob->name, prob->probdata, prob->transformed, - prob->objsense, objscale, prob->objoffset, - vars, nvars, prob->nbinvars, prob->nintvars, prob->nimplvars, prob->ncontvars, - fixedvars, nfixedvars, prob->startnvars, - conss, nconss, prob->maxnconss, prob->startnconss, genericnames, result); + retcode = reader->readerwrite(set->scip, reader, file, SCIPprobGetName(prob), SCIPprobGetData(prob), SCIPprobIsTransformed(prob), + SCIPprobGetObjsense(prob), objscale, SCIPprobGetObjoffset(prob), + vars, nvars, SCIPprobGetNBinVars(prob), SCIPprobGetNIntVars(prob), SCIPprobGetNImplVars(prob), SCIPprobGetNContVars(prob), + fixedvars, nfixedvars, SCIPprobGetStartNVars(prob), + conss, nconss, SCIPprobGetMaxNConss(prob), SCIPprobGetStartNConss(prob), genericnames, result); /* reset variable and constraint names to original names */ if( genericnames ) @@ -467,7 +467,7 @@ SCIP_RETCODE SCIPreaderWrite( SCIPsetFreeBufferArray(set, &varnames); } - if( prob->transformed ) + if( SCIPprobIsTransformed(prob) ) { /* free memory */ SCIPsetFreeBufferArray(set, &conss); diff --git a/src/scip/reopt.c b/src/scip/reopt.c index 67d156662d..af90b68e45 100644 --- a/src/scip/reopt.c +++ b/src/scip/reopt.c @@ -8194,8 +8194,8 @@ SCIP_RETCODE SCIPreoptSaveActiveConss( assert(reopt->nactiveconss == 0); assert(reopt->nmaxactiveconss == 0); - conss = transprob->conss; - nconss = transprob->nconss; + conss = SCIPprobGetConss(transprob); + nconss = SCIPprobGetNConss(transprob); SCIPsetDebugMsg(set, "save %d active conss\n", nconss); diff --git a/src/scip/tree.c b/src/scip/tree.c index 27d66f2f3f..b9e5e3af98 100644 --- a/src/scip/tree.c +++ b/src/scip/tree.c @@ -3891,9 +3891,9 @@ SCIP_RETCODE focusnodeCleanupVars( } /* mark variables as deleted */ - for( i = 0; i < transprob->nvars; i++ ) + for( i = 0; i < SCIPprobGetNVars(transprob); i++ ) { - var = transprob->vars[i]; + var = SCIPprobGetVars(transprob)[i]; assert(var != NULL); /* check whether variable is deletable */ @@ -7115,8 +7115,8 @@ SCIP_RETCODE SCIPtreeStoreRelaxSol( assert(transprob != NULL); assert(SCIPrelaxationIsSolValid(relaxation)); - nvars = transprob->nvars; - vars = transprob->vars; + nvars = SCIPprobGetNVars(transprob); + vars = SCIPprobGetVars(transprob); /* check if memory still needs to be allocated or resized */ if( tree->probdiverelaxsol == NULL ) @@ -7158,8 +7158,8 @@ SCIP_RETCODE SCIPtreeRestoreRelaxSol( assert(tree->probdiverelaxstored); assert(tree->probdiverelaxsol != NULL); - nvars = transprob->nvars; - vars = transprob->vars; + nvars = SCIPprobGetNVars(transprob); + vars = SCIPprobGetVars(transprob); assert( nvars <= tree->nprobdiverelaxsol ); /* iterate over all variables to restore the relaxation solution */ From 0346a912ab5da496666322038121cf98c1c6cba2 Mon Sep 17 00:00:00 2001 From: Stefan Vigerske Date: Sat, 14 Dec 2024 18:55:46 +0100 Subject: [PATCH 3/3] include constraint name in warning on empty QCMATRIX, ref #3805 --- src/scip/reader_mps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scip/reader_mps.c b/src/scip/reader_mps.c index 0c0b1114a0..fb26356482 100644 --- a/src/scip/reader_mps.c +++ b/src/scip/reader_mps.c @@ -2319,7 +2319,7 @@ SCIP_RETCODE readQCMatrix( } else { - SCIPwarningMessage(scip, "QCMATRIX section has no entries.\n"); + SCIPwarningMessage(scip, "QCMATRIX section for constraint <%s> has no entries.\n", SCIPconsGetName(lincons)); } TERMINATE: