1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 2 /* */ 3 /* This file is part of the program and library */ 4 /* SCIP --- Solving Constraint Integer Programs */ 5 /* */ 6 /* Copyright (c) 2002-2023 Zuse Institute Berlin (ZIB) */ 7 /* */ 8 /* Licensed under the Apache License, Version 2.0 (the "License"); */ 9 /* you may not use this file except in compliance with the License. */ 10 /* You may obtain a copy of the License at */ 11 /* */ 12 /* http://www.apache.org/licenses/LICENSE-2.0 */ 13 /* */ 14 /* Unless required by applicable law or agreed to in writing, software */ 15 /* distributed under the License is distributed on an "AS IS" BASIS, */ 16 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ 17 /* See the License for the specific language governing permissions and */ 18 /* limitations under the License. */ 19 /* */ 20 /* You should have received a copy of the Apache-2.0 license */ 21 /* along with SCIP; see the file LICENSE. If not visit scipopt.org. */ 22 /* */ 23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 24 25 /**@file cons_nonlinear.h 26 * @ingroup CONSHDLRS 27 * @brief constraint handler for nonlinear constraints specified by algebraic expressions 28 * @author Ksenia Bestuzheva 29 * @author Benjamin Mueller 30 * @author Felipe Serrano 31 * @author Stefan Vigerske 32 * 33 * For additional documentation on this constraint handler, see also the SCIP 8 release report. 34 */ 35 36 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/ 37 38 #ifndef __SCIP_CONS_NONLINEAR_H__ 39 #define __SCIP_CONS_NONLINEAR_H__ 40 41 42 #include "scip/scip.h" 43 #include "scip/type_nlhdlr.h" 44 45 #ifdef __cplusplus 46 extern "C" { 47 #endif 48 49 /**@addtogroup CONSHDLRS 50 * @{ 51 * 52 * @name Nonlinear Constraints 53 * @{ 54 */ 55 56 /** linear auxiliary expression of the form xy {≤,≥,=} coefs[0]w + coefs[1]x + coefs[2]y + cst */ 57 struct SCIP_ConsNonlinear_Auxexpr 58 { 59 SCIP_Real coefs[3]; /**< coefficients in the auxiliary expression */ 60 SCIP_Real cst; /**< constant */ 61 SCIP_VAR* auxvar; /**< auxiliary variable w in xy {≤,≥,=} auxexpr(w, x, y) */ 62 SCIP_Bool underestimate; /**< whether the auxexpr underestimates the product */ 63 SCIP_Bool overestimate; /**< whether the auxexpr overestimates the product */ 64 }; 65 typedef struct SCIP_ConsNonlinear_Auxexpr SCIP_CONSNONLINEAR_AUXEXPR; 66 67 /** bilinear term structure 68 * 69 * This can represent a product which 70 * - explicitly exists in the problem and is under- and/or overestimated by a single auxiliary variable 71 * stored as `var` in the union `aux` (case `nauxexprs` = 0) or 72 * - is involved in bilinear relations implicitly given by linear constraints with binary variables, and 73 * is under- and/or overestimated by linear expression(s) stored as `exprs` in the union `aux` (case `nauxexprs` > 0). 74 * 75 * An explicitly existing product can also be involved in implicit relations, then it will be stored as in 76 * the second case. 77 */ 78 struct SCIP_ConsNonlinear_BilinTerm 79 { 80 SCIP_VAR* x; /**< first variable */ 81 SCIP_VAR* y; /**< second variable */ 82 union 83 { 84 SCIP_CONSNONLINEAR_AUXEXPR** exprs; /**< auxiliary expressions for the implicit product of x and y */ 85 SCIP_VAR* var; /**< auxiliary variable for the explicit product of x and y */ 86 } aux; 87 int nauxexprs; /**< number of aux.exprs (0 for products without implicit relations) */ 88 int auxexprssize; /**< size of the aux.exprs array */ 89 int nlockspos; /**< number of positive expression locks */ 90 int nlocksneg; /**< number of negative expression locks */ 91 SCIP_Bool existing; /**< does the product exist explicitly in the problem? */ 92 }; 93 typedef struct SCIP_ConsNonlinear_BilinTerm SCIP_CONSNONLINEAR_BILINTERM; /**< bilinear term structure */ 94 95 /** evaluation callback for (vertex-polyhedral) functions used as input for facet computation of its envelopes 96 * 97 * \param[in] args the point to be evaluated 98 * \param[in] nargs the number of arguments of the function (length of array `args`) 99 * \param[in] funcdata user-data of function evaluation callback 100 * \return value of function in point given by `args` or SCIP_INVALID if could not be evaluated 101 */ 102 #define SCIP_DECL_VERTEXPOLYFUN(f) SCIP_Real f (SCIP_Real* args, int nargs, void* funcdata) 103 104 /** maximum dimension of vertex-polyhedral function for which we can try to compute a facet of its convex or concave envelope */ 105 #define SCIP_MAXVERTEXPOLYDIM 14 106 107 /** upgrading method for nonlinear constraints into more specific constraints 108 * 109 * The method might upgrade a nonlinear constraint into a set of upgrade constraints. 110 * The caller provided an array `upgdconss` of size `upgdconsssize` to store upgrade constraints. 111 * If an upgrade is not possible, set `*nupgdconss` to zero. 112 * If more than `upgdconsssize` many constraints shall replace `cons`, the function 113 * should return the required number as negated value in `*nupgdconss`, 114 * e.g., if `cons` should be replaced by 3 constraints, the function should set 115 * `*nupgdconss` to -3 and return with SCIP_OKAY. 116 * 117 * \param[in] scip SCIP main data structure 118 * \param[in] cons the nonlinear constraint to upgrade 119 * \param[in] nvarexprs total number of variable expressions in the nonlinear constraint 120 * \param[out] nupgdconss pointer to store number of constraints that replace this constraint 121 * \param[out] upgdconss array to store constraints that replace this constraint 122 * \param[in] upgdconsssize length of the provided `upgdconss` array 123 */ 124 #define SCIP_DECL_NONLINCONSUPGD(x) SCIP_RETCODE x (SCIP* scip, SCIP_CONS* cons, int nvarexprs, \ 125 int* nupgdconss, SCIP_CONS** upgdconss, int upgdconsssize) 126 127 /** @} */ 128 /** @} */ 129 130 /** creates the handler for nonlinear constraints and includes it in SCIP 131 * 132 * @ingroup ConshdlrIncludes 133 */ 134 SCIP_EXPORT 135 SCIP_RETCODE SCIPincludeConshdlrNonlinear( 136 SCIP* scip /**< SCIP data structure */ 137 ); 138 139 /**@addtogroup CONSHDLRS 140 * 141 * @{ 142 * 143 * @name Nonlinear Constraints 144 * 145 * @{ 146 */ 147 148 /* Nonlinear Constraint Handler Methods */ 149 150 /** includes a nonlinear constraint upgrade method into the nonlinear constraint handler */ 151 SCIP_EXPORT 152 SCIP_RETCODE SCIPincludeConsUpgradeNonlinear( 153 SCIP* scip, /**< SCIP data structure */ 154 SCIP_DECL_NONLINCONSUPGD((*nlconsupgd)), /**< method to call for upgrading nonlinear constraint */ 155 int priority, /**< priority of upgrading method */ 156 SCIP_Bool active, /**< should the upgrading method by active by default? */ 157 const char* conshdlrname /**< name of the constraint handler */ 158 ); 159 160 /** creates and captures a nonlinear constraint 161 * 162 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons() 163 */ 164 SCIP_EXPORT 165 SCIP_RETCODE SCIPcreateConsNonlinear( 166 SCIP* scip, /**< SCIP data structure */ 167 SCIP_CONS** cons, /**< pointer to hold the created constraint */ 168 const char* name, /**< name of constraint */ 169 SCIP_EXPR* expr, /**< expression of constraint (must not be NULL) */ 170 SCIP_Real lhs, /**< left hand side of constraint */ 171 SCIP_Real rhs, /**< right hand side of constraint */ 172 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP? 173 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */ 174 SCIP_Bool separate, /**< should the constraint be separated during LP processing? 175 * Usually set to TRUE. */ 176 SCIP_Bool enforce, /**< should the constraint be enforced during node processing? 177 * TRUE for model constraints, FALSE for additional, redundant constraints. */ 178 SCIP_Bool check, /**< should the constraint be checked for feasibility? 179 * TRUE for model constraints, FALSE for additional, redundant constraints. */ 180 SCIP_Bool propagate, /**< should the constraint be propagated during node processing? 181 * Usually set to TRUE. */ 182 SCIP_Bool local, /**< is constraint only valid locally? 183 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */ 184 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)? 185 * Usually set to FALSE. In column generation applications, set to TRUE if pricing 186 * adds coefficients to this constraint. */ 187 SCIP_Bool dynamic, /**< is constraint subject to aging? 188 * Usually set to FALSE. Set to TRUE for own cuts which 189 * are separated as constraints. */ 190 SCIP_Bool removable /**< should the relaxation be removed from the LP due to aging or cleanup? 191 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */ 192 ); 193 194 /** creates and captures a nonlinear constraint with all its constraint flags set to their default values 195 * 196 * All flags can be set via SCIPconsSetFLAGNAME-methods. 197 * 198 * @see SCIPcreateConsNonlinear() for information about the basic constraint flag configuration. 199 * 200 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons() 201 */ 202 SCIP_EXPORT 203 SCIP_RETCODE SCIPcreateConsBasicNonlinear( 204 SCIP* scip, /**< SCIP data structure */ 205 SCIP_CONS** cons, /**< pointer to hold the created constraint */ 206 const char* name, /**< name of constraint */ 207 SCIP_EXPR* expr, /**< expression of constraint (must not be NULL) */ 208 SCIP_Real lhs, /**< left hand side of constraint */ 209 SCIP_Real rhs /**< right hand side of constraint */ 210 ); 211 212 /** creates and captures a quadratic nonlinear constraint 213 * 214 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons() 215 */ 216 SCIP_EXPORT 217 SCIP_RETCODE SCIPcreateConsQuadraticNonlinear( 218 SCIP* scip, /**< SCIP data structure */ 219 SCIP_CONS** cons, /**< pointer to hold the created constraint */ 220 const char* name, /**< name of constraint */ 221 int nlinvars, /**< number of linear terms */ 222 SCIP_VAR** linvars, /**< array with variables in linear part */ 223 SCIP_Real* lincoefs, /**< array with coefficients of variables in linear part */ 224 int nquadterms, /**< number of quadratic terms */ 225 SCIP_VAR** quadvars1, /**< array with first variables in quadratic terms */ 226 SCIP_VAR** quadvars2, /**< array with second variables in quadratic terms */ 227 SCIP_Real* quadcoefs, /**< array with coefficients of quadratic terms */ 228 SCIP_Real lhs, /**< left hand side of quadratic equation */ 229 SCIP_Real rhs, /**< right hand side of quadratic equation */ 230 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP? 231 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */ 232 SCIP_Bool separate, /**< should the constraint be separated during LP processing? 233 * Usually set to TRUE. */ 234 SCIP_Bool enforce, /**< should the constraint be enforced during node processing? 235 * TRUE for model constraints, FALSE for additional, redundant constraints. */ 236 SCIP_Bool check, /**< should the constraint be checked for feasibility? 237 * TRUE for model constraints, FALSE for additional, redundant constraints. */ 238 SCIP_Bool propagate, /**< should the constraint be propagated during node processing? 239 * Usually set to TRUE. */ 240 SCIP_Bool local, /**< is constraint only valid locally? 241 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */ 242 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)? 243 * Usually set to FALSE. In column generation applications, set to TRUE if pricing 244 * adds coefficients to this constraint. */ 245 SCIP_Bool dynamic, /**< is constraint subject to aging? 246 * Usually set to FALSE. Set to TRUE for own cuts which 247 * are separated as constraints. */ 248 SCIP_Bool removable /**< should the relaxation be removed from the LP due to aging or cleanup? 249 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */ 250 ); 251 252 /** creates and captures a quadratic nonlinear constraint with all its constraint flags set to their default values 253 * 254 * All flags can be set via SCIPconsSetFLAGNAME-methods. 255 * 256 * @see SCIPcreateConsQuadraticNonlinear() for information about the basic constraint flag configuration. 257 * 258 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons() 259 */ 260 SCIP_EXPORT 261 SCIP_RETCODE SCIPcreateConsBasicQuadraticNonlinear( 262 SCIP* scip, /**< SCIP data structure */ 263 SCIP_CONS** cons, /**< pointer to hold the created constraint */ 264 const char* name, /**< name of constraint */ 265 int nlinvars, /**< number of linear terms */ 266 SCIP_VAR** linvars, /**< array with variables in linear part */ 267 SCIP_Real* lincoefs, /**< array with coefficients of variables in linear part */ 268 int nquadterms, /**< number of quadratic terms */ 269 SCIP_VAR** quadvars1, /**< array with first variables in quadratic terms */ 270 SCIP_VAR** quadvars2, /**< array with second variables in quadratic terms */ 271 SCIP_Real* quadcoefs, /**< array with coefficients of quadratic terms */ 272 SCIP_Real lhs, /**< left hand side of quadratic equation */ 273 SCIP_Real rhs /**< right hand side of quadratic equation */ 274 ); 275 276 /** creates and captures a nonlinear constraint that is a second-order cone constraint with all its constraint flags set to their default values 277 * 278 * \f$\sqrt{\gamma + \sum_{i=1}^{n} (\alpha_i\, (x_i + \beta_i))^2} \leq \alpha_{n+1}\, (x_{n+1}+\beta_{n+1})\f$ 279 * 280 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons() 281 */ 282 SCIP_EXPORT 283 SCIP_RETCODE SCIPcreateConsBasicSOCNonlinear( 284 SCIP* scip, /**< SCIP data structure */ 285 SCIP_CONS** cons, /**< pointer to hold the created constraint */ 286 const char* name, /**< name of constraint */ 287 int nvars, /**< number of variables on left hand side of constraint (n) */ 288 SCIP_VAR** vars, /**< array with variables on left hand side (x_i) */ 289 SCIP_Real* coefs, /**< array with coefficients of left hand side variables (alpha_i), or NULL if all 1.0 */ 290 SCIP_Real* offsets, /**< array with offsets of variables (beta_i), or NULL if all 0.0 */ 291 SCIP_Real constant, /**< constant on left hand side (gamma) */ 292 SCIP_VAR* rhsvar, /**< variable on right hand side of constraint (x_{n+1}) */ 293 SCIP_Real rhscoeff, /**< coefficient of variable on right hand side (alpha_{n+1}) */ 294 SCIP_Real rhsoffset /**< offset of variable on right hand side (beta_{n+1}) */ 295 ); 296 297 /** creates and captures a signpower nonlinear constraint with all its constraint flags set to their default values 298 * 299 * \f$\textrm{lhs} \leq \textrm{sign}(x+a) |x+a|^n + c z \leq \textrm{rhs}\f$ 300 * 301 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons() 302 */ 303 SCIP_EXPORT 304 SCIP_RETCODE SCIPcreateConsBasicSignpowerNonlinear( 305 SCIP* scip, /**< SCIP data structure */ 306 SCIP_CONS** cons, /**< pointer to hold the created constraint */ 307 const char* name, /**< name of constraint */ 308 SCIP_VAR* x, /**< nonlinear variable x in constraint */ 309 SCIP_VAR* z, /**< linear variable z in constraint */ 310 SCIP_Real exponent, /**< exponent n of |x+offset|^n term in constraint */ 311 SCIP_Real xoffset, /**< offset in |x+offset|^n term in constraint */ 312 SCIP_Real zcoef, /**< coefficient of z in constraint */ 313 SCIP_Real lhs, /**< left hand side of constraint */ 314 SCIP_Real rhs /**< right hand side of constraint */ 315 ); 316 317 /** gets tag indicating current local variable bounds */ 318 SCIP_EXPORT 319 SCIP_Longint SCIPgetCurBoundsTagNonlinear( 320 SCIP_CONSHDLR* conshdlr /**< nonlinear constraint handler */ 321 ); 322 323 /** gets the `curboundstag` from the last time where variable bounds were relaxed */ 324 SCIP_EXPORT 325 SCIP_Longint SCIPgetLastBoundRelaxTagNonlinear( 326 SCIP_CONSHDLR* conshdlr /**< nonlinear constraint handler */ 327 ); 328 329 /** increments `curboundstag` and resets `lastboundrelax` in constraint handler data 330 * 331 * @attention This method is not intended for normal use. 332 * These tags are maintained by the event handler for variable bound change events. 333 * This method is used by some unittests. 334 */ 335 SCIP_EXPORT 336 void SCIPincrementCurBoundsTagNonlinear( 337 SCIP_CONSHDLR* conshdlr, /**< nonlinear constraint handler */ 338 SCIP_Bool boundrelax /**< indicates whether a bound was relaxed, i.e., lastboundrelax should be set too */ 339 ); 340 341 /** returns the hashmap that is internally used to map variables to their corresponding variable expressions */ 342 SCIP_EXPORT 343 SCIP_HASHMAP* SCIPgetVarExprHashmapNonlinear( 344 SCIP_CONSHDLR* conshdlr /**< nonlinear constraint handler */ 345 ); 346 347 /** processes a rowprep for cut addition and maybe report branchscores */ 348 SCIP_EXPORT 349 SCIP_RETCODE SCIPprocessRowprepNonlinear( 350 SCIP* scip, /**< SCIP data structure */ 351 SCIP_NLHDLR* nlhdlr, /**< nonlinear handler which provided the estimator */ 352 SCIP_CONS* cons, /**< nonlinear constraint */ 353 SCIP_EXPR* expr, /**< expression */ 354 SCIP_ROWPREP* rowprep, /**< cut to be added */ 355 SCIP_Bool overestimate, /**< whether the expression needs to be over- or underestimated */ 356 SCIP_VAR* auxvar, /**< auxiliary variable */ 357 SCIP_Real auxvalue, /**< current value of expression w.r.t. auxiliary variables as obtained from EVALAUX */ 358 SCIP_Bool allowweakcuts, /**< whether we should only look for "strong" cuts, or anything that separates is fine */ 359 SCIP_Bool branchscoresuccess, /**< whether the estimator generation generated branching scores */ 360 SCIP_Bool inenforcement, /**< whether we are in enforcement, or only in separation */ 361 SCIP_SOL* sol, /**< solution to be separated (NULL for the LP solution) */ 362 SCIP_RESULT* result /**< pointer to store the result */ 363 ); 364 365 /** returns whether all nonlinear constraints are assumed to be convex */ 366 SCIP_EXPORT 367 SCIP_Bool SCIPassumeConvexNonlinear( 368 SCIP_CONSHDLR* conshdlr 369 ); 370 371 /** collects all bilinear terms for a given set of constraints 372 * 373 * @attention This method should only be used for unit tests that depend on SCIPgetBilinTermsNonlinear(), 374 * SCIPgetBilinTermNonlinear() or SCIPgetBilinTermIdxNonlinear(). 375 */ 376 SCIP_EXPORT 377 SCIP_RETCODE SCIPcollectBilinTermsNonlinear( 378 SCIP* scip, /**< SCIP data structure */ 379 SCIP_CONSHDLR* conshdlr, /**< nonlinear constraint handler */ 380 SCIP_CONS** conss, /**< nonlinear constraints */ 381 int nconss /**< total number of nonlinear constraints */ 382 ); 383 384 /** returns the total number of bilinear terms that are contained in all nonlinear constraints 385 * 386 * @note This method should only be used after auxiliary variables have been created, i.e., after CONSINITLP. 387 */ 388 SCIP_EXPORT 389 int SCIPgetNBilinTermsNonlinear( 390 SCIP_CONSHDLR* conshdlr /**< nonlinear constraint handler */ 391 ); 392 393 /** returns all bilinear terms that are contained in all nonlinear constraints 394 * 395 * @note This method should only be used after auxiliary variables have been created, i.e., after CONSINITLP. 396 * @note The value of the auxiliary variable of a bilinear term might be NULL, which indicates that the term does not have an auxiliary variable. 397 */ 398 SCIP_EXPORT 399 SCIP_CONSNONLINEAR_BILINTERM* SCIPgetBilinTermsNonlinear( 400 SCIP_CONSHDLR* conshdlr /**< nonlinear constraint handler */ 401 ); 402 403 /** returns the index of the bilinear term representing the product of the two given variables 404 * 405 * @note The method should only be used after auxiliary variables have been created, i.e., after CONSINITLP. 406 * @return The method returns -1 if the variables do not appear bilinearly. 407 */ 408 SCIP_EXPORT 409 int SCIPgetBilinTermIdxNonlinear( 410 SCIP_CONSHDLR* conshdlr, /**< nonlinear constraint handler */ 411 SCIP_VAR* x, /**< first variable */ 412 SCIP_VAR* y /**< second variable */ 413 ); 414 415 /** returns the bilinear term that represents the product of two given variables 416 * 417 * @note The method should only be used after auxiliary variables have been created, i.e., after CONSINITLP. 418 * @return The method returns NULL if the variables do not appear bilinearly. 419 */ 420 SCIP_EXPORT 421 SCIP_CONSNONLINEAR_BILINTERM* SCIPgetBilinTermNonlinear( 422 SCIP_CONSHDLR* conshdlr, /**< nonlinear constraint handler */ 423 SCIP_VAR* x, /**< first variable */ 424 SCIP_VAR* y /**< second variable */ 425 ); 426 427 /** evaluates an auxiliary expression for a bilinear term */ 428 SCIP_EXPORT 429 SCIP_Real SCIPevalBilinAuxExprNonlinear( 430 SCIP* scip, /**< SCIP data structure */ 431 SCIP_VAR* x, /**< first variable of the bilinear term */ 432 SCIP_VAR* y, /**< second variable of the bilinear term */ 433 SCIP_CONSNONLINEAR_AUXEXPR* auxexpr, /**< auxiliary expression */ 434 SCIP_SOL* sol /**< solution at which to evaluate (can be NULL) */ 435 ); 436 437 /** stores the variables of a bilinear term in the data of the constraint handler */ 438 SCIP_EXPORT 439 SCIP_RETCODE SCIPinsertBilinearTermExistingNonlinear( 440 SCIP* scip, /**< SCIP data structure */ 441 SCIP_CONSHDLR* conshdlr, /**< constraint handler */ 442 SCIP_VAR* x, /**< first variable */ 443 SCIP_VAR* y, /**< second variable */ 444 SCIP_VAR* auxvar, /**< auxiliary variable (might be NULL) */ 445 int nlockspos, /**< number of positive expression locks */ 446 int nlocksneg /**< number of negative expression locks */ 447 ); 448 449 /** stores the variables of a bilinear term in the data of the constraint handler */ 450 SCIP_EXPORT 451 SCIP_RETCODE SCIPinsertBilinearTermImplicitNonlinear( 452 SCIP* scip, /**< SCIP data structure */ 453 SCIP_CONSHDLR* conshdlr, /**< constraint handler */ 454 SCIP_VAR* x, /**< first variable */ 455 SCIP_VAR* y, /**< second variable */ 456 SCIP_VAR* auxvar, /**< auxiliary variable (might be NULL) */ 457 SCIP_Real coefx, /**< coefficient of x in the auxiliary expression */ 458 SCIP_Real coefy, /**< coefficient of y in the auxiliary expression */ 459 SCIP_Real coefaux, /**< coefficient of auxvar in the auxiliary expression */ 460 SCIP_Real cst, /**< constant of the auxiliary expression */ 461 SCIP_Bool overestimate /**< whether the auxiliary expression overestimates the bilinear product */ 462 ); 463 464 /** computes a facet of the convex or concave envelope of a vertex polyhedral function 465 * 466 * If \f$ f(x) \f$ is vertex-polyhedral, then \f$ g \f$ is a convex underestimator if and only if 467 * \f$ g(v^i) \leq f(v^i), \forall i \f$, where \f$ \{ v^i \}_{i = 1}^{2^n} \subseteq \mathbb R^n \f$ are the vertices 468 * of the domain of \f$ x \f$, \f$ [\ell,u] \f$. Hence, we can compute a linear underestimator by solving the following 469 * LP (we don't necessarily get a facet of the convex envelope, see below): 470 * 471 * \f{align*}{ 472 * \max \, & \alpha^T x^* + \beta \\ 473 * s.t. \; & \alpha^T v^i + \beta \le f(v^i), \, \forall i = 1, \ldots, 2^n 474 * \f} 475 * 476 * In principle, one would need to update the LP whenever the domain changes. However, \f$ [\ell,u] = T([0, 1]^n) \f$, 477 * where \f$ T \f$ is an affine linear invertible transformation given by \f$ T(y)_i = (u_i - \ell_i) y_i + \ell_i \f$. 478 * Working with the change of variables \f$ x = T(y) \f$ allows us to keep the constraints of the LP, even if the domain 479 * changes. Indeed, after the change of variables, the problem is: find an affine underestimator \f$ g \f$ such that \f$ 480 * g(T(y)) \le f(T(y)) \f$, for all \f$ y \in [0, 1]^n \f$. Now \f$ f(T(y)) \f$ is componentwise affine, but still 481 * satisfies that \f$ g \f$ is a valid underestimator if and only if \f$ g(T(u)) \leq f(T(u)), \forall u \in \{0, 1\}^n 482 * \f$. So we now look for \f$ \bar g(y) := g(T(y)) = g(((u_i - \ell_i) y_i + \ell_i)_i) = \bar \alpha^T y + \bar \beta 483 * \f$, where \f$ \bar \alpha_i = (u_i - \ell_i) \alpha_i \f$ and \f$ \bar \beta = \sum_i \alpha_i \ell_i + \beta \f$. So 484 * we find \f$ \bar g \f$ by solving the LP: 485 * 486 * \f{align*}{ 487 * \max \, & \bar \alpha^T T^{-1}(x^*) + \bar \beta \\ 488 * s.t. \; & \bar \alpha^T u + \bar \beta \le f(T(u)), \, \forall u \in \{0, 1\}^n 489 * \f} 490 * 491 * and recover \f$ g \f$ by calculating \f$ \bar \alpha_i = (u_i - \ell_i) \alpha_i, \bar \beta = \sum_i \alpha_i \ell_i + 492 * \beta \f$. Notice that \f$ f(T(u^i)) = f(v^i) \f$ so the right hand side doesn't change after the change of variables. 493 * 494 * Furthermore, the LP has more constraints than variables, so we solve its dual: 495 * \f{align*}{ 496 * \min \, & \sum_i \lambda_i f(v^i) \\ 497 * s.t. \; & \sum_i \lambda_i u^i = T^{-1}(x^*) \\ 498 * & \sum_i \lambda_i = 1 \\ 499 * & \forall i, \, \lambda_i \geq 0 500 * \f} 501 * 502 * In case we look for an overestimate, we do exactly the same, but have to maximize in the dual LP instead 503 * of minimize. 504 * 505 * #### Technical and implementation details 506 * -# \f$ U \f$ has exponentially many variables, so we only apply this separator for \f$n\f$ ≤ \ref SCIP_MAXVERTEXPOLYDIM. 507 * -# If the bounds are not finite, there is no underestimator. Also, \f$ T^{-1}(x^*) \f$ must be in the domain, 508 * otherwise the dual is infeasible. 509 * -# After a facet is computed, we check whether it is a valid facet (i.e. we check \f$ \alpha^T v + \beta \le f(v) \f$ 510 * for every vertex \f$ v \f$). If we find a violation of at most ADJUSTFACETFACTOR * SCIPlpfeastol(), then we weaken \f$ 511 * \beta \f$ by this amount, otherwise, we discard the cut. 512 * -# If a variable is fixed within tolerances, we replace it with its value and compute the facet of the remaining 513 * expression. Note that since we are checking the cut for validity, this will never produce wrong result. 514 * -# If \f$ x^* \f$ is in the boundary of the domain, then the LP has infinitely many solutions, some of which might 515 * have very bad numerical properties. For this reason, we perturb \f$ x^* \f$ to be in the interior of the region. 516 * Furthermore, for some interior points, there might also be infinitely many solutions (e.g. for \f$ x y \f$ in \f$ 517 * [0,1]^2 \f$ any point \f$ (x^*, y^*) \f$ such that \f$ y^* = 1 - x^* \f$ has infinitely many solutions). For this 518 * reason, we perturb any given \f$ x^* \f$. The idea is to try to get a facet of the convex/concave envelope. This only 519 * happens when the solution has \f$ n + 1 \f$ non zero \f$ \lambda \f$'s (i.e. the primal has a unique solution). 520 * -# We need to compute \f$ f(v^i) \f$ for every vertex of \f$ [\ell,u] \f$. A vertex is encoded by a number between 0 521 * and \f$ 2^n - 1 \f$, via its binary representation (0 bit is lower bound, 1 bit is upper bound), so we can compute 522 * all these values by iterating between 0 and \f$ 2^n - 1 \f$. 523 * -# To check that the computed cut is valid we do the following: we use a gray code to loop over the vertices 524 * of the box domain w.r.t. unfixed variables in order to evaluate the underestimator. To ensure the validity of the 525 * underestimator, we check whether \f$ \alpha v^i + \beta \le f(v^i) \f$ for every vertex \f$ v^i \f$ and adjust 526 * \f$ \beta \f$ if the maximal violation is small. 527 * 528 * @todo the solution is a facet if all variables of the primal have positive reduced costs (i.e. the solution is 529 * unique). In the dual, this means that there are \f$ n + 1 \f$ variables with positive value. Can we use this or some 530 * other information to handle any of both cases (point in the boundary or point in the intersection of polytopes 531 * defining different pieces of the convex envelope)? In the case where the point is in the boundary, can we use that 532 * information to maybe solve another to find a facet? How do the polytopes defining the pieces where the convex 533 * envelope is linear looks like, i.e, given a point in the interior of a facet of the domain, does the midpoint of the 534 * segment joining \f$ x^* \f$ with the center of the domain, always belongs to the interior of one of those polytopes? 535 */ 536 SCIP_EXPORT 537 SCIP_RETCODE SCIPcomputeFacetVertexPolyhedralNonlinear( 538 SCIP* scip, /**< SCIP data structure */ 539 SCIP_CONSHDLR* conshdlr, /**< nonlinear constraint handler */ 540 SCIP_Bool overestimate, /**< whether to compute facet of concave (TRUE) or convex (FALSE) envelope */ 541 SCIP_DECL_VERTEXPOLYFUN((*function)), /**< pointer to vertex polyhedral function */ 542 void* fundata, /**< data for function evaluation (can be NULL) */ 543 SCIP_Real* xstar, /**< point to be separated */ 544 SCIP_Real* box, /**< box where to compute facet: should be lb_1, ub_1, lb_2, ub_2... */ 545 int nallvars, /**< half of the length of box */ 546 SCIP_Real targetvalue, /**< target value: no need to compute facet if value in xstar would be worse than this value */ 547 SCIP_Bool* success, /**< buffer to store whether a facet could be computed successfully */ 548 SCIP_Real* facetcoefs, /**< buffer to store coefficients of facet defining inequality; must be an array of length at least nallvars */ 549 SCIP_Real* facetconstant /**< buffer to store constant part of facet defining inequality */ 550 ); 551 552 553 /* Nonlinear Constraint Methods */ 554 555 /** returns the expression of the given nonlinear constraint */ 556 SCIP_EXPORT 557 SCIP_EXPR* SCIPgetExprNonlinear( 558 SCIP_CONS* cons /**< constraint data */ 559 ); 560 561 /** gets the left hand side of a nonlinear constraint */ 562 SCIP_EXPORT 563 SCIP_Real SCIPgetLhsNonlinear( 564 SCIP_CONS* cons /**< constraint data */ 565 ); 566 567 /** gets the right hand side of a nonlinear constraint */ 568 SCIP_EXPORT 569 SCIP_Real SCIPgetRhsNonlinear( 570 SCIP_CONS* cons /**< constraint data */ 571 ); 572 573 /** gets the nonlinear constraint as a nonlinear row representation. */ 574 SCIP_EXPORT 575 SCIP_RETCODE SCIPgetNlRowNonlinear( 576 SCIP* scip, /**< SCIP data structure */ 577 SCIP_CONS* cons, /**< constraint */ 578 SCIP_NLROW** nlrow /**< pointer to store nonlinear row */ 579 ); 580 581 /** returns the curvature of the expression of a given nonlinear constraint 582 * 583 * @note The curvature information is computed during CONSINITSOL. 584 */ 585 SCIP_EXPORT 586 SCIP_EXPRCURV SCIPgetCurvatureNonlinear( 587 SCIP_CONS* cons /**< constraint data */ 588 ); 589 590 /** checks whether expression of constraint can be represented as quadratic form 591 * 592 * Only sets `*isquadratic` to TRUE if the whole expression is quadratic (in the non-extended formulation) and non-linear. 593 * That is, the expression in each \ref SCIP_QUADEXPR_QUADTERM will be a variable expressions and 594 * \ref SCIPgetVarExprVar() can be used to retrieve the variable. 595 */ 596 SCIP_EXPORT 597 SCIP_RETCODE SCIPcheckQuadraticNonlinear( 598 SCIP* scip, /**< SCIP data structure */ 599 SCIP_CONS* cons, /**< constraint data */ 600 SCIP_Bool* isquadratic /**< buffer to store whether constraint is quadratic */ 601 ); 602 603 /** changes left-hand-side of a nonlinear constraint 604 * 605 * @attention This method can only be called in the problem stage. 606 */ 607 SCIP_EXPORT 608 SCIP_RETCODE SCIPchgLhsNonlinear( 609 SCIP* scip, /**< SCIP data structure */ 610 SCIP_CONS* cons, /**< constraint data */ 611 SCIP_Real lhs /**< new left-hand-side */ 612 ); 613 614 /** changes right-hand-side of a nonlinear constraint 615 * 616 * @attention This method can only be called in the problem stage. 617 */ 618 SCIP_EXPORT 619 SCIP_RETCODE SCIPchgRhsNonlinear( 620 SCIP* scip, /**< SCIP data structure */ 621 SCIP_CONS* cons, /**< constraint data */ 622 SCIP_Real rhs /**< new right-hand-side */ 623 ); 624 625 /** changes expression of a nonlinear constraint 626 * 627 * @attention This method can only be called in the problem stage. 628 */ 629 SCIP_EXPORT 630 SCIP_RETCODE SCIPchgExprNonlinear( 631 SCIP* scip, /**< SCIP data structure */ 632 SCIP_CONS* cons, /**< constraint data */ 633 SCIP_EXPR* expr /**< new expression */ 634 ); 635 636 /** adds coef * var to nonlinear constraint 637 * 638 * @attention This method can only be called in the problem stage. 639 */ 640 SCIP_EXPORT 641 SCIP_RETCODE SCIPaddLinearVarNonlinear( 642 SCIP* scip, /**< SCIP data structure */ 643 SCIP_CONS* cons, /**< constraint data */ 644 SCIP_VAR* var, /**< variable */ 645 SCIP_Real coef /**< coefficient */ 646 ); 647 648 /** adds coef * expr to nonlinear constraint 649 * 650 * @attention This method can only be called in the problem stage. 651 */ 652 SCIP_EXPORT 653 SCIP_RETCODE SCIPaddExprNonlinear( 654 SCIP* scip, /**< SCIP data structure */ 655 SCIP_CONS* cons, /**< nonlinear constraint */ 656 SCIP_EXPR* expr, /**< expression */ 657 SCIP_Real coef /**< coefficient */ 658 ); 659 660 /** gets absolute violation of nonlinear constraint 661 * 662 * This function evaluates the constraints in the given solution. 663 * 664 * If this value is at most SCIPfeastol(), the constraint would be considered feasible. 665 */ 666 SCIP_EXPORT 667 SCIP_RETCODE SCIPgetAbsViolationNonlinear( 668 SCIP* scip, /**< SCIP data structure */ 669 SCIP_CONS* cons, /**< constraint */ 670 SCIP_SOL* sol, /**< solution to check */ 671 SCIP_Real* viol /**< buffer to store computed violation */ 672 ); 673 674 /** gets scaled violation of nonlinear constraint 675 * 676 * This function evaluates the constraints in the given solution. 677 * 678 * The scaling that is applied to the absolute violation of the constraint 679 * depends on the setting of parameter constraints/nonlinear/violscale. 680 */ 681 SCIP_EXPORT 682 SCIP_RETCODE SCIPgetRelViolationNonlinear( 683 SCIP* scip, /**< SCIP data structure */ 684 SCIP_CONS* cons, /**< constraint */ 685 SCIP_SOL* sol, /**< solution to check */ 686 SCIP_Real* viol /**< buffer to store computed violation */ 687 ); 688 689 /** returns a variable that appears linearly that may be decreased without making any other constraint infeasible */ 690 SCIP_EXPORT 691 void SCIPgetLinvarMayDecreaseNonlinear( 692 SCIP* scip, /**< SCIP data structure */ 693 SCIP_CONS* cons, /**< nonlinear constraint */ 694 SCIP_VAR** var, /**< pointer to store the variable */ 695 SCIP_Real* coef /**< pointer to store the coefficient */ 696 ); 697 698 /** returns a variable that appears linearly that may be increased without making any other constraint infeasible */ 699 SCIP_EXPORT 700 void SCIPgetLinvarMayIncreaseNonlinear( 701 SCIP* scip, /**< SCIP data structure */ 702 SCIP_CONS* cons, /**< nonlinear constraint */ 703 SCIP_VAR** var, /**< pointer to store the variable */ 704 SCIP_Real* coef /**< pointer to store the coefficient */ 705 ); 706 707 708 /* Methods for Expressions in Nonlinear Constraints 709 * All functions in this group assume that the expression is owned by a the nonlinear constraint handler. 710 */ 711 712 /** returns the number of positive rounding locks of an expression */ 713 SCIP_EXPORT 714 int SCIPgetExprNLocksPosNonlinear( 715 SCIP_EXPR* expr /**< expression */ 716 ); 717 718 /** returns the number of negative rounding locks of an expression */ 719 SCIP_EXPORT 720 int SCIPgetExprNLocksNegNonlinear( 721 SCIP_EXPR* expr /**< expression */ 722 ); 723 724 /** returns the variable used for linearizing a given expression (return value might be NULL) 725 * 726 * @note for variable expression it returns the corresponding variable 727 */ 728 SCIP_EXPORT 729 SCIP_VAR* SCIPgetExprAuxVarNonlinear( 730 SCIP_EXPR* expr /**< expression */ 731 ); 732 733 /** returns the number of enforcements for an expression */ 734 SCIP_EXPORT 735 int SCIPgetExprNEnfosNonlinear( 736 SCIP_EXPR* expr /**< expression */ 737 ); 738 739 /** returns the data for one of the enforcements of an expression */ 740 SCIP_EXPORT 741 void SCIPgetExprEnfoDataNonlinear( 742 SCIP_EXPR* expr, /**< expression */ 743 int idx, /**< position of enforcement in enfos array */ 744 SCIP_NLHDLR** nlhdlr, /**< buffer to store nlhldr */ 745 SCIP_NLHDLREXPRDATA** nlhdlrexprdata, /**< buffer to store nlhdlr data for expression, or NULL */ 746 SCIP_NLHDLR_METHOD* nlhdlrparticipation, /**< buffer to store methods where nonlinear handler participates, or NULL */ 747 SCIP_Bool* sepabelowusesactivity, /**< buffer to store whether sepabelow uses activity of some expression, or NULL */ 748 SCIP_Bool* sepaaboveusesactivity, /**< buffer to store whether sepaabove uses activity of some expression, or NULL */ 749 SCIP_Real* auxvalue /**< buffer to store current auxvalue, or NULL */ 750 ); 751 752 /** sets the auxiliary value of expression for one of the enforcements of an expression */ 753 SCIP_EXPORT 754 void SCIPsetExprEnfoAuxValueNonlinear( 755 SCIP_EXPR* expr, /**< expression */ 756 int idx, /**< position of enforcement in enfos array */ 757 SCIP_Real auxvalue /**< the new value of auxval */ 758 ); 759 760 /** number of nonlinear handlers whose activity computation and propagation methods depend on the activity of the expression 761 * 762 * @note This method can only be used after the detection methods of the nonlinear handlers have been called. 763 */ 764 SCIP_EXPORT 765 unsigned int SCIPgetExprNPropUsesActivityNonlinear( 766 SCIP_EXPR* expr /**< expression */ 767 ); 768 769 /** number of nonlinear handlers whose separation methods (estimate or enforcement) depend on the activity of the expression 770 * 771 * @note This method can only be used after the detection methods of the nonlinear handlers have been called. 772 */ 773 SCIP_EXPORT 774 unsigned int SCIPgetExprNSepaUsesActivityNonlinear( 775 SCIP_EXPR* expr /**< expression */ 776 ); 777 778 /** number of nonlinear handlers whose separation methods (estimate or enforcement) use auxiliary variable of the expression 779 * 780 * @note This method can only be used after the detection methods of the nonlinear handlers have been called. 781 */ 782 SCIP_EXPORT 783 unsigned int SCIPgetExprNAuxvarUsesNonlinear( 784 SCIP_EXPR* expr /**< expression */ 785 ); 786 787 /** method to be called by a nlhdlr during NLHDLRDETECT to notify an expression that it will be used 788 * 789 * - if `useauxvar` is enabled, then ensures that an auxiliary variable will be created in INITLP 790 * - if `useactivityforprop` or `useactivityforsepa{below,above}` is enabled, then ensured that activity will be updated for `expr` 791 * - if `useactivityforprop` is enabled, then increments the count returned by SCIPgetExprNPropUsesActivityNonlinear() 792 * - if `useactivityforsepa{below,above}` is enabled, then increments the count returned by SCIPgetExprNSepaUsesActivityNonlinear() 793 * and also increments this count for all variables in the expression. 794 * 795 * The distinction into `useactivityforprop` and `useactivityforsepa{below,above}` is to recognize variables which domain influences 796 * under/overestimators. Domain propagation routines (like OBBT) may invest more work for these variables. 797 * The distinction into `useactivityforsepabelow` and `useactivityforsepaabove` is to recognize whether a nlhdlr that called this method 798 * will use activity of `expr` in enfomethod \ref SCIP_NLHDLR_METHOD_SEPABELOW or \ref SCIP_NLHDLR_METHOD_SEPAABOVE. 799 */ 800 SCIP_EXPORT 801 SCIP_RETCODE SCIPregisterExprUsageNonlinear( 802 SCIP* scip, /**< SCIP data structure */ 803 SCIP_EXPR* expr, /**< expression */ 804 SCIP_Bool useauxvar, /**< whether an auxiliary variable will be used for estimate or cut generation */ 805 SCIP_Bool useactivityforprop, /**< whether activity of expr will be used by domain propagation or activity calculation (inteval) */ 806 SCIP_Bool useactivityforsepabelow, /**< whether activity of expr will be used by underestimation */ 807 SCIP_Bool useactivityforsepaabove /**< whether activity of expr will be used by overestimation */ 808 ); 809 810 /** computes absolute violation for auxvar relation in an expression w.r.t. original variables 811 * 812 * Assume the expression is f(x), where x are original (i.e., not auxiliary) variables. 813 * Assume that f(x) is associated with auxiliary variable z. 814 * 815 * If there are negative locks, then returns the violation of z ≤ f(x) and sets `violover` to TRUE. 816 * If there are positive locks, then returns the violation of z ≥ f(x) and sets `violunder` to TRUE. 817 * Of course, if there both negative and positive locks, then return the violation of z = f(x). 818 * 819 * If necessary, f is evaluated in the given solution. If that fails (domain error), 820 * then `viol` is set to SCIPinfinity() and both `violover` and `violunder` are set to TRUE. 821 */ 822 SCIP_EXPORT 823 SCIP_RETCODE SCIPgetExprAbsOrigViolationNonlinear( 824 SCIP* scip, /**< SCIP data structure */ 825 SCIP_EXPR* expr, /**< expression */ 826 SCIP_SOL* sol, /**< solution */ 827 SCIP_Longint soltag, /**< tag of solution */ 828 SCIP_Real* viol, /**< buffer to store computed violation */ 829 SCIP_Bool* violunder, /**< buffer to store whether z >= f(x) is violated, or NULL */ 830 SCIP_Bool* violover /**< buffer to store whether z <= f(x) is violated, or NULL */ 831 ); 832 833 /** computes absolute violation for auxvar relation in an expression w.r.t. auxiliary variables 834 * 835 * Assume the expression is f(w), where w are auxiliary variables that were introduced by some nlhdlr. 836 * Assume that f(w) is associated with auxiliary variable z. 837 * 838 * If there are negative locks, then returns the violation of z ≤ f(w) and sets `violover` to TRUE. 839 * If there are positive locks, then returns the violation of z ≥ f(w) and sets `violunder` to TRUE. 840 * Of course, if there both negative and positive locks, then return the violation of z = f(w). 841 * 842 * If the given value of f(w) is SCIP_INVALID, then `viol` is set to SCIPinfinity() and 843 * both `violover` and `violunder` are set to TRUE. 844 */ 845 SCIP_EXPORT 846 SCIP_RETCODE SCIPgetExprAbsAuxViolationNonlinear( 847 SCIP* scip, /**< SCIP data structure */ 848 SCIP_EXPR* expr, /**< expression */ 849 SCIP_Real auxvalue, /**< the value of f(w) */ 850 SCIP_SOL* sol, /**< solution that has been evaluated */ 851 SCIP_Real* viol, /**< buffer to store computed violation */ 852 SCIP_Bool* violunder, /**< buffer to store whether z >= f(w) is violated, or NULL */ 853 SCIP_Bool* violover /**< buffer to store whether z <= f(w) is violated, or NULL */ 854 ); 855 856 /** computes relative violation for auxvar relation in an expression w.r.t. auxiliary variables 857 * 858 * Assume the expression is f(w), where w are auxiliary variables that were introduced by some nlhdlr. 859 * Assume that f(w) is associated with auxiliary variable z. 860 * 861 * Taking the absolute violation from SCIPgetExprAbsAuxViolationNonlinear(), this function returns 862 * the absolute violation divided by max(1,|f(w)|). 863 * 864 * If the given value of f(w) is SCIP_INVALID, then `viol` is set to SCIPinfinity() and 865 * both `violover` and `violunder` are set to TRUE. 866 */ 867 SCIP_EXPORT 868 SCIP_RETCODE SCIPgetExprRelAuxViolationNonlinear( 869 SCIP* scip, /**< SCIP data structure */ 870 SCIP_EXPR* expr, /**< expression */ 871 SCIP_Real auxvalue, /**< the value of f(w) */ 872 SCIP_SOL* sol, /**< solution that has been evaluated */ 873 SCIP_Real* viol, /**< buffer to store computed violation */ 874 SCIP_Bool* violunder, /**< buffer to store whether z >= f(w) is violated, or NULL */ 875 SCIP_Bool* violover /**< buffer to store whether z <= f(w) is violated, or NULL */ 876 ); 877 878 /** returns bounds on the expression 879 * 880 * This gives an intersection of bounds from 881 * - activity calculation (SCIPexprGetActivity()), if valid, 882 * - auxiliary variable, if present, 883 * - stored by SCIPtightenExprIntervalNonlinear() during domain propagation 884 * 885 * @note The returned interval can be empty! 886 */ 887 SCIP_EXPORT 888 SCIP_INTERVAL SCIPgetExprBoundsNonlinear( 889 SCIP* scip, /**< SCIP data structure */ 890 SCIP_EXPR* expr /**< expression */ 891 ); 892 893 /** informs the expression about new bounds that can be used for reverse-propagation and to tighten bounds of 894 * corresponding (auxiliary) variable (if any) 895 * 896 * @attention this function should only be called during domain propagation in cons_nonlinear 897 */ 898 SCIP_EXPORT 899 SCIP_RETCODE SCIPtightenExprIntervalNonlinear( 900 SCIP* scip, /**< SCIP data structure */ 901 SCIP_EXPR* expr, /**< expression to be tightened */ 902 SCIP_INTERVAL newbounds, /**< new bounds for the expression */ 903 SCIP_Bool* cutoff, /**< buffer to store whether a cutoff was detected */ 904 int* ntightenings /**< buffer to add the total number of tightenings, or NULL */ 905 ); 906 907 /** mark constraints that include this expression to be propagated again 908 * 909 * This can be used by, e.g., nlhdlrs, to trigger a new propagation of constraints without 910 * a change of variable bounds, e.g., because new information on the expression is available 911 * that could potentially lead to tighter expression activity values. 912 * 913 * Note, that this call marks also constraints for propagation which only share some variable 914 * with this expression. 915 */ 916 SCIP_EXPORT 917 SCIP_RETCODE SCIPmarkExprPropagateNonlinear( 918 SCIP* scip, /**< SCIP data structure */ 919 SCIP_EXPR* expr /**< expression to propagate again */ 920 ); 921 922 /** adds violation-branching score to an expression 923 * 924 * Adds a score to the expression-specific violation-branching score, thereby marking it as branching candidate. 925 * The expression must either be a variable expression or have an aux-variable. 926 * In the latter case, branching on auxiliary variables must have been enabled. 927 * In case of doubt, use SCIPaddExprsViolScoreNonlinear(). Roughly, the difference between these functions is that the current 928 * function adds `violscore` to the expression directly, while SCIPaddExprsViolScoreNonlinear() will split the 929 * violation score among all the given expressions according to parameter constraints/nonlinear/branching/violsplit. 930 * 931 * @see SCIPaddExprsViolScoreNonlinear() 932 */ 933 SCIP_EXPORT 934 void SCIPaddExprViolScoreNonlinear( 935 SCIP* scip, /**< SCIP data structure */ 936 SCIP_EXPR* expr, /**< expression where to add branching score */ 937 SCIP_Real violscore /**< violation score to add to expression */ 938 ); 939 940 /** adds violation-branching score to a set of expressions, distributing the score among all the expressions 941 * 942 * Each expression must either be a variable expression or have an aux-variable. 943 * If branching on aux-variables is disabled, then the violation branching score will be distributed among all 944 * variables present in `exprs`. 945 */ 946 SCIP_EXPORT 947 SCIP_RETCODE SCIPaddExprsViolScoreNonlinear( 948 SCIP* scip, /**< SCIP data structure */ 949 SCIP_EXPR** exprs, /**< expressions where to add branching score */ 950 int nexprs, /**< number of expressions */ 951 SCIP_Real violscore, /**< violation score to add to expression */ 952 SCIP_SOL* sol, /**< current solution */ 953 SCIP_Bool* success /**< buffer to store whether at least one violscore was added */ 954 ); 955 956 /** gives violation-branching score stored in expression, or 0.0 if no valid score has been stored */ 957 SCIP_EXPORT 958 SCIP_Real SCIPgetExprViolScoreNonlinear( 959 SCIP_EXPR* expr /**< expression */ 960 ); 961 962 /** returns the partial derivative of an expression w.r.t. a variable (or SCIP_INVALID if there was an evaluation error) 963 * 964 * @see SCIPexprGetDerivative() 965 */ 966 SCIP_EXPORT 967 SCIP_Real SCIPgetExprPartialDiffNonlinear( 968 SCIP* scip, /**< SCIP data structure */ 969 SCIP_EXPR* expr, /**< root expression of constraint used in the last SCIPevalExprGradient() call */ 970 SCIP_VAR* var /**< variable (needs to be in the expression) */ 971 ); 972 973 /** returns the var's coordinate of Hu partial derivative of an expression w.r.t. a variable (or SCIP_INVALID if there was an evaluation error) 974 * 975 * @see SCIPexprGetBardot() 976 */ 977 SCIP_EXPORT 978 SCIP_Real SCIPgetExprPartialDiffGradientDirNonlinear( 979 SCIP* scip, /**< SCIP data structure */ 980 SCIP_EXPR* expr, /**< root expression of constraint used in the last SCIPevalExprHessianDir() call */ 981 SCIP_VAR* var /**< variable (needs to be in the expression) */ 982 ); 983 984 /** evaluates quadratic term in a solution w.r.t. auxiliary variables 985 * 986 * \note This requires that for every expr used in the quadratic data, a variable or auxiliary variable is available. 987 */ 988 SCIP_EXPORT 989 SCIP_Real SCIPevalExprQuadraticAuxNonlinear( 990 SCIP* scip, /**< SCIP data structure */ 991 SCIP_EXPR* expr, /**< quadratic expression */ 992 SCIP_SOL* sol /**< solution to evaluate, or NULL for LP solution */ 993 ); 994 995 /** @} */ 996 /** @} */ 997 998 /**@addtogroup PublicNlhdlrInterfaceMethods 999 * @{ 1000 */ 1001 1002 /** creates a nonlinear handler and includes it into the nonlinear constraint handler */ 1003 SCIP_EXPORT 1004 SCIP_RETCODE SCIPincludeNlhdlrNonlinear( 1005 SCIP* scip, /**< SCIP data structure */ 1006 SCIP_NLHDLR** nlhdlr, /**< buffer where to store nonlinear handler */ 1007 const char* name, /**< name of nonlinear handler (must not be NULL) */ 1008 const char* desc, /**< description of nonlinear handler (can be NULL) */ 1009 int detectpriority, /**< detection priority of nonlinear handler */ 1010 int enfopriority, /**< enforcement priority of nonlinear handler */ 1011 SCIP_DECL_NLHDLRDETECT((*detect)), /**< structure detection callback of nonlinear handler */ 1012 SCIP_DECL_NLHDLREVALAUX((*evalaux)), /**< auxiliary evaluation callback of nonlinear handler */ 1013 SCIP_NLHDLRDATA* nlhdlrdata /**< data of nonlinear handler (can be NULL) */ 1014 ); 1015 1016 /** get number of nonlinear handler */ 1017 SCIP_EXPORT 1018 int SCIPgetNNlhdlrsNonlinear( 1019 SCIP_CONSHDLR* conshdlr /**< nonlinear constraint handler */ 1020 ); 1021 1022 /** get nonlinear handlers */ 1023 SCIP_EXPORT 1024 SCIP_NLHDLR** SCIPgetNlhdlrsNonlinear( 1025 SCIP_CONSHDLR* conshdlr /**< nonlinear constraint handler */ 1026 ); 1027 /** returns a nonlinear handler of a given name (or NULL if not found) */ 1028 SCIP_EXPORT 1029 SCIP_NLHDLR* SCIPfindNlhdlrNonlinear( 1030 SCIP_CONSHDLR* conshdlr, /**< nonlinear constraint handler */ 1031 const char* name /**< name of nonlinear handler */ 1032 ); 1033 1034 /** gives expression data that a given nonlinear handler stored in an expression 1035 * 1036 * Returns NULL if expr has not been detected by nlhdlr or nlhdlr did not store data. 1037 */ 1038 SCIP_EXPORT 1039 SCIP_NLHDLREXPRDATA* SCIPgetNlhdlrExprDataNonlinear( 1040 SCIP_NLHDLR* nlhdlr, /**< nonlinear handler */ 1041 SCIP_EXPR* expr /**< expression */ 1042 ); 1043 1044 /** @} */ 1045 1046 #ifdef __cplusplus 1047 } 1048 #endif 1049 1050 #endif 1051