37 #define SEPA_NAME "gauge" 38 #define SEPA_DESC "gauge separator" 39 #define SEPA_PRIORITY 0 41 #define SEPA_MAXBOUNDDIST 1.0 42 #define SEPA_USESSUBSCIP FALSE 43 #define SEPA_DELAY FALSE 45 #define VIOLATIONFAC 100 48 #define DEFAULT_NLPTIMELIMIT 0.0 49 #define DEFAULT_NLPITERLIM 1000 51 #define NLPFEASFAC 1e-1 52 #define NLPVERBOSITY 0 54 #define INTERIOROBJVARLB -100 114 assert(scip !=
NULL);
115 assert(sepadata !=
NULL);
116 assert(nlrows !=
NULL);
124 sepadata->nlrowssize = nnlrows;
126 sepadata->nnlrows = 0;
127 for( i = 0; i < nnlrows; ++i )
132 assert(nlrow !=
NULL);
142 sepadata->convexsides[sepadata->nnlrows] =
RHS;
143 sepadata->nlrows[sepadata->nnlrows] = nlrow;
144 ++(sepadata->nnlrows);
148 sepadata->convexsides[sepadata->nnlrows] =
LHS;
149 sepadata->nlrows[sepadata->nnlrows] = nlrow;
150 ++(sepadata->nnlrows);
184 assert(scip !=
NULL);
185 assert(sepadata !=
NULL);
186 assert(!sepadata->skipsepa);
194 assert(nlpi !=
NULL);
215 assert(nlpioracle !=
NULL);
221 for( i = 0; i < nconss; i++ )
232 if( nconvexnlrows < 2 )
234 SCIPdebugMsg(scip,
"convex relaxation is not interesting, only %d nonlinear convex rows; abort\n", nconvexnlrows);
235 sepadata->skipsepa =
TRUE;
250 if( timelimit <= 1.0 )
253 sepadata->skipsepa =
TRUE;
257 if( sepadata->nlptimelimit > 0.0 )
258 timelimit =
MIN(sepadata->nlptimelimit, timelimit);
261 iterlimit = sepadata->nlpiterlimit > 0 ? sepadata->nlpiterlimit : INT_MAX;
267 SCIPdebugMsg(scip,
"starting interior point computation\n");
269 SCIPdebugMsg(scip,
"finish interior point computation\n");
279 SCIPdebugMsg(scip,
"nlpi took iters %d, time %g searching for an find interior point: solstat %d\n",
293 assert(nlpisol !=
NULL);
294 SCIPdebugMsg(scip,
"NLP solved: sol found has objvalue = %g\n", nlpisol[objvaridx]);
299 SCIPdebugMsg(scip,
"Interior point found!, storing it\n");
301 for( i = 0; i < nvars; i ++ )
313 sepadata->isintsolavailable =
TRUE;
317 SCIPdebugMsg(scip,
"We got a feasible point but not interior (objval: %g)\n", nlpisol[objvaridx]);
318 sepadata->skipsepa =
TRUE;
324 sepadata->skipsepa =
TRUE;
353 assert(scip !=
NULL);
354 assert(nlrows !=
NULL);
355 assert(convexsides !=
NULL);
356 assert(nnlrowsidx > 0);
357 assert(point !=
NULL);
358 assert(position !=
NULL);
361 for( i = 0; i < nnlrowsidx; i++ )
367 nlrow = nlrows[nlrowsidx[i]];
368 convexside = convexsides[nlrowsidx[i]];
373 if( convexside ==
RHS )
395 assert(convexside ==
LHS);
429 assert(scip !=
NULL);
430 assert(startpoint !=
NULL);
431 assert(endpoint !=
NULL);
432 assert(convexcomb !=
NULL);
437 for( i = 0; i < nvars; i++ )
480 assert(scip !=
NULL);
481 assert(nlrows !=
NULL);
482 assert(nlrowsidx !=
NULL);
483 assert(convexsides !=
NULL);
484 assert(intsol !=
NULL);
485 assert(tosepasol !=
NULL);
487 assert(position !=
NULL);
499 SCIPdebugMsg(scip,
"Position: %d, lambda: %g\n", position, (ub + lb)/2.0);
538 assert(scip !=
NULL);
539 assert(exprint !=
NULL);
541 assert(exprtree !=
NULL);
542 assert(grad !=
NULL);
555 for( i = 0; i < nvars; ++i )
585 assert(scip !=
NULL);
586 assert(exprint !=
NULL);
587 assert(nlrow !=
NULL);
627 gradx0 += grad1 * solval1 + grad2 * solval2;
663 if( convexside ==
RHS )
670 assert(convexside ==
LHS);
708 assert(sepa !=
NULL);
711 assert(sepadata !=
NULL);
713 intsol = sepadata->intsol;
714 nlrows = sepadata->nlrows;
715 nlrowsidx = sepadata->nlrowsidx;
716 nnlrowsidx = sepadata->nnlrowsidx;
717 convexsides = sepadata->convexsides;
719 assert(intsol !=
NULL);
720 assert(nlrows !=
NULL);
721 assert(nlrowsidx !=
NULL);
722 assert(nnlrowsidx > 0);
723 assert(convexsides !=
NULL);
736 SCIPdebugMsg(scip,
"segment joining intsol and tosepasol seems to be contained in the exterior of the region, can't separate\n");
742 SCIPdebugMsg(scip,
"line through intsol and tosepasol is tangent to region; can't separate\n");
745 printf(
"Position of intsol is %s\n",
746 position ==
EXTERIOR ?
"exterior" : position ==
INTERIOR ?
"interior":
"boundary");
748 printf(
"Position of tosepasol is %s\n",
749 position ==
EXTERIOR ?
"exterior" : position ==
INTERIOR ?
"interior":
"boundary");
754 printf(
"Position of intsol + 0.00001(tosepasol - inisol) is %s\n",
755 position ==
EXTERIOR ?
"exterior" : position ==
INTERIOR ?
"interior":
"boundary");
760 printf(
"Position of intsol - 0.00001(tosepasol - inisol) is %s\n",
761 position ==
EXTERIOR ?
"exterior" : position ==
INTERIOR ?
"interior":
"boundary");
777 SCIPdebugMsg(scip,
"couldn't find boundary point, don't separate\n");
783 for( i = 0; i < nnlrowsidx; i++ )
791 nlrow = nlrows[nlrowsidx[i]];
792 convexside = convexsides[nlrowsidx[i]];
856 assert(sepadata !=
NULL);
872 assert(sepa !=
NULL);
876 assert(sepadata !=
NULL);
879 if( sepadata->isintsolavailable )
887 sepadata->nnlrows = 0;
888 sepadata->nnlrowsidx = 0;
889 sepadata->nlrowssize = 0;
890 sepadata->isintsolavailable =
FALSE;
892 assert(sepadata->nnlrows == 0);
893 assert(sepadata->nnlrowsidx == 0);
894 assert(sepadata->nlrowssize == 0);
895 assert(sepadata->isintsolavailable ==
FALSE);
897 sepadata->skipsepa =
FALSE;
912 assert(sepa !=
NULL);
916 assert(sepadata !=
NULL);
921 if( sepadata->skipsepa )
923 SCIPdebugMsg(
scip,
"not running because convex relaxation is uninteresting\n");
937 SCIPdebugMsg(
scip,
"Skip gauge separator: no nlpi and SCIP can't solve nonlinear problems without a nlpi\n");
944 if( !sepadata->isintsolavailable )
948 assert(sepadata->skipsepa || sepadata->isintsolavailable);
950 if( sepadata->skipsepa )
957 #ifdef SCIP_DISABLED_CODE 963 if( !sepadata->isintsolavailable && sepadata->computeintsol )
971 sepadata->isintsolavailable =
TRUE;
974 if( !sepadata->isintsolavailable )
980 sepadata->isintsolavailable =
TRUE;
986 sepadata->isintsolavailable =
TRUE;
990 SCIPdebugMsg(
scip,
"We couldn't find an interior point, don't have a feasible nor an NLP solution; skip separator\n");
1000 sepadata->nnlrowsidx = 0;
1001 for( i = 0; i < sepadata->nnlrows; i++ )
1006 nlrow = sepadata->nlrows[i];
1010 if( sepadata->convexsides[i] ==
RHS )
1019 assert(sepadata->convexsides[i] ==
LHS);
1026 sepadata->nlrowsidx[sepadata->nnlrowsidx] = i;
1027 ++(sepadata->nnlrowsidx);
1031 SCIPdebugMsg(
scip,
"there are %d violated nlrows\n", sepadata->nnlrowsidx);
1032 if( sepadata->nnlrowsidx > 0 )
1065 sepaExeclpGauge,
NULL,
1068 assert(sepa !=
NULL);
1076 "iteration limit of NLP solver; 0 for no limit",
1080 "time limit of NLP solver; 0.0 for no limit",
enum SCIP_Result SCIP_RESULT
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
SCIP_ROW ** SCIPgetLPRows(SCIP *scip)
int SCIPgetNNLPNlRows(SCIP *scip)
SCIP_Real SCIPgetSolvingTime(SCIP *scip)
SCIP_RETCODE SCIPnlpiGetStatistics(SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, SCIP_NLPSTATISTICS *statistics)
SCIP_Real SCIPfeastol(SCIP *scip)
#define SCIPallocBlockMemoryArray(scip, ptr, num)
void * SCIPgetNlpiOracleIpopt(SCIP_NLPIPROBLEM *nlpiproblem)
SCIP_Bool SCIPisNLPConstructed(SCIP *scip)
SCIP_RETCODE SCIPnlpStatisticsCreate(SCIP_NLPSTATISTICS **statistics)
SCIP_RETCODE SCIPcacheRowExtensions(SCIP *scip, SCIP_ROW *row)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
methods to interpret (evaluate) an expression tree "fast"
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
int SCIPnlpiOracleGetNVars(SCIP_NLPIORACLE *oracle)
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
SCIP_RETCODE SCIPflushRowExtensions(SCIP *scip, SCIP_ROW *row)
SCIP_RETCODE SCIPcreateNlpiProb(SCIP *scip, SCIP_NLPI *nlpi, SCIP_NLROW **nlrows, int nnlrows, SCIP_NLPIPROBLEM *nlpiprob, SCIP_HASHMAP *var2idx, SCIP_Real *nlscore, SCIP_Real cutoffbound, SCIP_Bool setobj, SCIP_Bool onlyconvex)
SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
SCIP_Real SCIPnlpStatisticsGetTotalTime(SCIP_NLPSTATISTICS *statistics)
internal methods for NLPI solver interfaces
SCIP_RETCODE SCIPnlpiCreateProblem(SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM **problem, const char *name)
const char * SCIProwGetName(SCIP_ROW *row)
methods to store an NLP and request function, gradient, and hessian values
SCIP_Bool SCIPisFeasNegative(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE computeInteriorPoint(SCIP *scip, SCIP_SEPADATA *sepadata)
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
static SCIP_DECL_SEPAFREE(sepaFreeGauge)
SCIP_Real SCIPinfinity(SCIP *scip)
int SCIPsnprintf(char *t, int len, const char *s,...)
const char * SCIPsepaGetName(SCIP_SEPA *sepa)
enum SCIP_Retcode SCIP_RETCODE
SCIP_RETCODE SCIPexprintCompile(SCIP_EXPRINT *exprint, SCIP_EXPRTREE *tree)
SCIP_Real SCIPnlrowGetRhs(SCIP_NLROW *nlrow)
enum ConvexSide CONVEXSIDE
const char * SCIPnlpiGetName(SCIP_NLPI *nlpi)
int SCIPnlrowGetNLinearVars(SCIP_NLROW *nlrow)
#define SCIPfreeBlockMemory(scip, ptr)
#define DEFAULT_NLPITERLIM
SCIP_RETCODE SCIPgetNlRowSolActivity(SCIP *scip, SCIP_NLROW *nlrow, SCIP_SOL *sol, SCIP_Real *activity)
SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
SCIP_EXPRCURV SCIPnlrowGetCurvature(SCIP_NLROW *nlrow)
SCIP_RETCODE SCIPnlpiGetSolution(SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, SCIP_Real **primalvalues, SCIP_Real **consdualvalues, SCIP_Real **varlbdualvalues, SCIP_Real **varubdualvalues)
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
#define SCIPfreeBufferArray(scip, ptr)
#define SCIPallocBlockMemory(scip, ptr)
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
void SCIPnlpStatisticsFree(SCIP_NLPSTATISTICS **statistics)
int SCIPnlpiOracleGetNConstraints(SCIP_NLPIORACLE *oracle)
SCIP_VAR ** SCIPexprtreeGetVars(SCIP_EXPRTREE *tree)
SCIP_NLROW ** SCIPgetNLPNlRows(SCIP *scip)
SCIP_SEPADATA * SCIPsepaGetData(SCIP_SEPA *sepa)
int SCIPnlrowGetNQuadElems(SCIP_NLROW *nlrow)
#define SEPA_MAXBOUNDDIST
static SCIP_RETCODE computeGradient(SCIP *scip, SCIP_EXPRINT *exprint, SCIP_SOL *sol, SCIP_EXPRTREE *exprtree, SCIP_Real *grad)
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
SCIP_RETCODE SCIPnlpiSolve(SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem)
SCIP_RETCODE SCIPnlpiAddVars(SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int nvars, const SCIP_Real *lbs, const SCIP_Real *ubs, const char **varnames)
static SCIP_RETCODE generateCut(SCIP *scip, SCIP_SOL *sol, SCIP_EXPRINT *exprint, SCIP_NLROW *nlrow, CONVEXSIDE convexside, SCIP_ROW *row)
static SCIP_DECL_SEPAEXITSOL(sepaExitsolGauge)
SCIP_Bool SCIPisCutEfficacious(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
SCIP_RETCODE SCIPcreateSolCopy(SCIP *scip, SCIP_SOL **sol, SCIP_SOL *sourcesol)
SCIP_VAR ** SCIPnlrowGetQuadVars(SCIP_NLROW *nlrow)
int SCIPnlpiOracleGetConstraintDegree(SCIP_NLPIORACLE *oracle, int considx)
static SCIP_RETCODE storeNonlinearConvexNlrows(SCIP *scip, SCIP_SEPADATA *sepadata, SCIP_NLROW **nlrows, int nnlrows)
SCIP_RETCODE SCIPexprintCreate(BMS_BLKMEM *blkmem, SCIP_EXPRINT **exprint)
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
static SCIP_DECL_SEPAEXECLP(sepaExeclpGauge)
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
void SCIPsepaSetData(SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata)
SCIP_RETCODE SCIPaddNlpiProbRows(SCIP *scip, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *nlpiprob, SCIP_HASHMAP *var2idx, SCIP_ROW **rows, int nrows)
int SCIPgetNNlpis(SCIP *scip)
int SCIPexprtreeGetNVars(SCIP_EXPRTREE *tree)
int SCIPgetNLPRows(SCIP *scip)
SCIP_QUADELEM * SCIPnlrowGetQuadElems(SCIP_NLROW *nlrow)
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPaddCut(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut, SCIP_Bool forcecut, SCIP_Bool *infeasible)
SCIP_RETCODE SCIPincludeSepaGauge(SCIP *scip)
SCIP_NLPSOLSTAT SCIPnlpiGetSolstat(SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem)
SCIP_RETCODE SCIPnlpiSetObjective(SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int nlins, const int *lininds, const SCIP_Real *linvals, int nquadelems, const SCIP_QUADELEM *quadelems, const int *exprvaridxs, const SCIP_EXPRTREE *exprtree, const SCIP_Real constant)
SCIP_RETCODE SCIPincludeSepaBasic(SCIP *scip, SCIP_SEPA **sepa, const char *name, const char *desc, int priority, int freq, SCIP_Real maxbounddist, SCIP_Bool usessubscip, SCIP_Bool delay, SCIP_DECL_SEPAEXECLP((*sepaexeclp)), SCIP_DECL_SEPAEXECSOL((*sepaexecsol)), SCIP_SEPADATA *sepadata)
SCIP_RETCODE SCIPnlpiFreeProblem(SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM **problem)
#define SCIPallocBufferArray(scip, ptr, num)
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
SCIP_RETCODE SCIPnlpiOraclePrintProblem(SCIP_NLPIORACLE *oracle, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
SCIP_RETCODE SCIPsetSepaExitsol(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAEXITSOL((*sepaexitsol)))
SCIP_RETCODE SCIPchgRowRhs(SCIP *scip, SCIP_ROW *row, SCIP_Real rhs)
#define DEFAULT_NLPTIMELIMIT
SCIP_RETCODE SCIPnlpiSetIntPar(SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, SCIP_NLPPARAM type, int ival)
SCIP_EXPRINTDATA * SCIPexprtreeGetInterpreterData(SCIP_EXPRTREE *tree)
SCIP_RETCODE SCIPcreateEmptyRowSepa(SCIP *scip, SCIP_ROW **row, SCIP_SEPA *sepa, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
SCIP_RETCODE SCIPchgRowLhs(SCIP *scip, SCIP_ROW *row, SCIP_Real lhs)
SCIP_Real SCIPgetCutEfficacy(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
int SCIPgetNSols(SCIP *scip)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
#define BMSclearMemory(ptr)
SCIP_RETCODE SCIPexprintGrad(SCIP_EXPRINT *exprint, SCIP_EXPRTREE *tree, SCIP_Real *varvals, SCIP_Bool new_varvals, SCIP_Real *val, SCIP_Real *gradient)
int SCIPgetNVars(SCIP *scip)
SCIP_EXPRTREE * SCIPnlrowGetExprtree(SCIP_NLROW *nlrow)
SCIP_Bool SCIPhasNLPSolution(SCIP *scip)
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
SCIP_RETCODE SCIPcreateNLPSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
SCIP_RETCODE SCIPsetSepaFree(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAFREE((*sepafree)))
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
SCIP_VAR ** SCIPgetVars(SCIP *scip)
static SCIP_RETCODE buildConvexCombination(SCIP *scip, SCIP_Real lambda, SCIP_SOL *startpoint, SCIP_SOL *endpoint, SCIP_SOL *convexcomb)
static SCIP_RETCODE separateCuts(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *tosepasol, SCIP_RESULT *result)
SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
SCIP_RETCODE SCIPprintNlRow(SCIP *scip, SCIP_NLROW *nlrow, FILE *file)
int SCIPnlpStatisticsGetNIterations(SCIP_NLPSTATISTICS *statistics)
SCIP_RETCODE SCIPcreateCurrentSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
SCIP_RETCODE SCIPnlpiChgLinearCoefs(SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, const int idx, int nvals, const int *varidxs, const SCIP_Real *vals)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Real * SCIPnlrowGetLinearCoefs(SCIP_NLROW *nlrow)
const char * SCIPnlrowGetName(SCIP_NLROW *nlrow)
SCIP_VAR ** SCIPnlrowGetLinearVars(SCIP_NLROW *nlrow)
SCIP_NLPI ** SCIPgetNlpis(SCIP *scip)
SCIP_RETCODE SCIPexprintFree(SCIP_EXPRINT **exprint)
static SCIP_RETCODE findPointPosition(SCIP *scip, SCIP_NLROW **nlrows, int *nlrowsidx, int nnlrowsidx, CONVEXSIDE *convexsides, SCIP_SOL *point, POSITION *position)
SCIP_Real SCIPnlrowGetLhs(SCIP_NLROW *nlrow)
static SCIP_RETCODE findBoundaryPoint(SCIP *scip, SCIP_NLROW **nlrows, int *nlrowsidx, int nnlrowsidx, CONVEXSIDE *convexsides, SCIP_SOL *intsol, SCIP_SOL *tosepasol, SCIP_SOL *sol, POSITION *position)
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
enum ConvexSide CONVEXSIDE
struct SCIP_SepaData SCIP_SEPADATA
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
SCIP_RETCODE SCIPnlpiSetRealPar(SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, SCIP_NLPPARAM type, SCIP_Real dval)
SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)