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_soc.c 26 * @ingroup DEFPLUGINS_CONS 27 * @brief some API functions of removed constraint handler for second order cone constraints \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$ 28 * @author Stefan Vigerske 29 */ 30 31 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/ 32 33 #include "scip/cons_soc.h" 34 #include "scip/cons_nonlinear.h" 35 #include "scip/expr_var.h" 36 #include "scip/expr_pow.h" 37 #include "scip/expr_sum.h" 38 39 /** creates expression for \f$\sqrt{\gamma + \sum_{i=1}^{n} (\alpha_i\, (x_i + \beta_i))^2} - \alpha_{n+1} x_{n+1}\f$ */ 40 static 41 SCIP_RETCODE createSOCExpression( 42 SCIP* scip, /**< SCIP data structure */ 43 SCIP_EXPR** expr, /**< buffer to store expression */ 44 int nvars, /**< number of variables on left hand side of constraint (n) */ 45 SCIP_VAR** vars, /**< array with variables on left hand side (x_i) */ 46 SCIP_Real* coefs, /**< array with coefficients of left hand side variables (alpha_i), or NULL if all 1.0 */ 47 SCIP_Real* offsets, /**< array with offsets of variables (beta_i), or NULL if all 0.0 */ 48 SCIP_Real constant, /**< constant on left hand side (gamma) */ 49 SCIP_VAR* rhsvar, /**< variable on right hand side of constraint (x_{n+1}) */ 50 SCIP_Real rhscoeff /**< coefficient of variable on right hand side (alpha_{n+1}) */ 51 ) 52 { 53 SCIP_EXPR* lhssum; 54 SCIP_EXPR* terms[2]; 55 SCIP_Real termcoefs[2]; 56 int i; 57 58 assert(expr != NULL); 59 assert(vars != NULL || nvars == 0); 60 61 SCIP_CALL( SCIPcreateExprSum(scip, &lhssum, 0, NULL, NULL, constant, NULL, NULL) ); /* gamma */ 62 for( i = 0; i < nvars; ++i ) 63 { 64 SCIP_EXPR* varexpr; 65 SCIP_EXPR* powexpr; 66 67 SCIP_CALL( SCIPcreateExprVar(scip, &varexpr, vars[i], NULL, NULL) ); /* x_i */ 68 if( offsets != NULL && offsets[i] != 0.0 ) 69 { 70 SCIP_EXPR* sum; 71 SCIP_CALL( SCIPcreateExprSum(scip, &sum, 1, &varexpr, NULL, offsets[i], NULL, NULL) ); /* x_i + beta_i */ 72 SCIP_CALL( SCIPcreateExprPow(scip, &powexpr, sum, 2.0, NULL, NULL) ); /* (x_i + beta_i)^2 */ 73 SCIP_CALL( SCIPreleaseExpr(scip, &sum) ); 74 } 75 else 76 { 77 SCIP_CALL( SCIPcreateExprPow(scip, &powexpr, varexpr, 2.0, NULL, NULL) ); /* x_i^2 */ 78 } 79 80 SCIP_CALL( SCIPappendExprSumExpr(scip, lhssum, powexpr, coefs != NULL ? coefs[i]*coefs[i] : 1.0) ); /* + alpha_i^2 (x_i + beta_i)^2 */ 81 SCIP_CALL( SCIPreleaseExpr(scip, &varexpr) ); 82 SCIP_CALL( SCIPreleaseExpr(scip, &powexpr) ); 83 } 84 85 SCIP_CALL( SCIPcreateExprPow(scip, &terms[0], lhssum, 0.5, NULL, NULL) ); /* sqrt(...) */ 86 SCIP_CALL( SCIPreleaseExpr(scip, &lhssum) ); 87 termcoefs[0] = 1.0; 88 89 SCIP_CALL( SCIPcreateExprVar(scip, &terms[1], rhsvar, NULL, NULL) ); /* x_{n+1} */ 90 termcoefs[1] = -rhscoeff; 91 92 SCIP_CALL( SCIPcreateExprSum(scip, expr, 2, terms, termcoefs, 0.0, NULL, NULL) ); /* sqrt(...) - alpha_{n+1}x_{n_1} */ 93 94 SCIP_CALL( SCIPreleaseExpr(scip, &terms[1]) ); 95 SCIP_CALL( SCIPreleaseExpr(scip, &terms[0]) ); 96 97 return SCIP_OKAY; 98 } 99 100 /** creates and captures a second order cone nonlinear constraint 101 * 102 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons() 103 * 104 * @deprecated Use SCIPcreateConsNonlinear() instead 105 */ 106 SCIP_RETCODE SCIPcreateConsSOC( 107 SCIP* scip, /**< SCIP data structure */ 108 SCIP_CONS** cons, /**< pointer to hold the created constraint */ 109 const char* name, /**< name of constraint */ 110 int nvars, /**< number of variables on left hand side of constraint (n) */ 111 SCIP_VAR** vars, /**< array with variables on left hand side (x_i) */ 112 SCIP_Real* coefs, /**< array with coefficients of left hand side variables (alpha_i), or NULL if all 1.0 */ 113 SCIP_Real* offsets, /**< array with offsets of variables (beta_i), or NULL if all 0.0 */ 114 SCIP_Real constant, /**< constant on left hand side (gamma) */ 115 SCIP_VAR* rhsvar, /**< variable on right hand side of constraint (x_{n+1}) */ 116 SCIP_Real rhscoeff, /**< coefficient of variable on right hand side (alpha_{n+1}) */ 117 SCIP_Real rhsoffset, /**< offset of variable on right hand side (beta_{n+1}) */ 118 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP? 119 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */ 120 SCIP_Bool separate, /**< should the constraint be separated during LP processing? 121 * Usually set to TRUE. */ 122 SCIP_Bool enforce, /**< should the constraint be enforced during node processing? 123 * TRUE for model constraints, FALSE for additional, redundant constraints. */ 124 SCIP_Bool check, /**< should the constraint be checked for feasibility? 125 * TRUE for model constraints, FALSE for additional, redundant constraints. */ 126 SCIP_Bool propagate, /**< should the constraint be propagated during node processing? 127 * Usually set to TRUE. */ 128 SCIP_Bool local, /**< is constraint only valid locally? 129 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */ 130 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)? 131 * Usually set to FALSE. In column generation applications, set to TRUE if pricing 132 * adds coefficients to this constraint. */ 133 SCIP_Bool dynamic, /**< is constraint subject to aging? 134 * Usually set to FALSE. Set to TRUE for own cuts which 135 * are separated as constraints. */ 136 SCIP_Bool removable /**< should the relaxation be removed from the LP due to aging or cleanup? 137 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */ 138 ) 139 { 140 SCIP_EXPR* expr; 141 142 SCIP_CALL( createSOCExpression(scip, &expr, nvars, vars, coefs, offsets, constant, rhsvar, rhscoeff) ); 143 144 SCIP_CALL( SCIPcreateConsNonlinear(scip, cons, name, expr, -SCIPinfinity(scip), rhscoeff * rhsoffset, 145 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable) ); 146 147 SCIP_CALL( SCIPreleaseExpr(scip, &expr) ); 148 149 return SCIP_OKAY; 150 } 151 152 /** creates and captures a second order cone nonlinear constraint 153 * in its most basic variant, i. e., with all constraint flags set to their default values, which can be set 154 * afterwards using SCIPsetConsFLAGNAME() 155 * 156 * @see SCIPcreateConsSOC() for the default constraint flag configuration 157 * 158 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons() 159 * 160 * @deprecated Use SCIPcreateConsBasicNonlinear() instead 161 */ 162 SCIP_RETCODE SCIPcreateConsBasicSOC( 163 SCIP* scip, /**< SCIP data structure */ 164 SCIP_CONS** cons, /**< pointer to hold the created constraint */ 165 const char* name, /**< name of constraint */ 166 int nvars, /**< number of variables on left hand side of constraint (n) */ 167 SCIP_VAR** vars, /**< array with variables on left hand side (x_i) */ 168 SCIP_Real* coefs, /**< array with coefficients of left hand side variables (alpha_i), or NULL if all 1.0 */ 169 SCIP_Real* offsets, /**< array with offsets of variables (beta_i), or NULL if all 0.0 */ 170 SCIP_Real constant, /**< constant on left hand side (gamma) */ 171 SCIP_VAR* rhsvar, /**< variable on right hand side of constraint (x_{n+1}) */ 172 SCIP_Real rhscoeff, /**< coefficient of variable on right hand side (alpha_{n+1}) */ 173 SCIP_Real rhsoffset /**< offset of variable on right hand side (beta_{n+1}) */ 174 ) 175 { 176 SCIP_EXPR* expr; 177 178 SCIP_CALL( createSOCExpression(scip, &expr, nvars, vars, coefs, offsets, constant, rhsvar, rhscoeff) ); 179 180 SCIP_CALL( SCIPcreateConsBasicNonlinear(scip, cons, name, expr, -SCIPinfinity(scip), rhscoeff * rhsoffset) ); 181 182 SCIP_CALL( SCIPreleaseExpr(scip, &expr) ); 183 184 return SCIP_OKAY; 185 } 186 187 /** Gets the SOC constraint as a nonlinear row representation. 188 * 189 * @deprecated Use SCIPgetNlRowNonlinear() instead. 190 */ 191 SCIP_RETCODE SCIPgetNlRowSOC( 192 SCIP* scip, /**< SCIP data structure */ 193 SCIP_CONS* cons, /**< constraint */ 194 SCIP_NLROW** nlrow /**< pointer to store nonlinear row */ 195 ) 196 { 197 assert(cons != NULL); 198 assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), "nonlinear") == 0); 199 200 SCIP_CALL( SCIPgetNlRowNonlinear(scip, cons, nlrow) ); 201 202 return SCIP_OKAY; 203 } 204