1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /*                                                                           */
3 /*                  This file is part of the program and library             */
4 /*         SCIP --- Solving Constraint Integer Programs                      */
5 /*                                                                           */
6 /*    Copyright (C) 2002-2021 Konrad-Zuse-Zentrum                            */
7 /*                            fuer Informationstechnik Berlin                */
8 /*                                                                           */
9 /*  SCIP is distributed under the terms of the ZIB Academic License.         */
10 /*                                                                           */
11 /*  You should have received a copy of the ZIB Academic License              */
12 /*  along with SCIP; see the file COPYING. If not visit scipopt.org.         */
13 /*                                                                           */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file   cons_pseudoboolean.h
17  * @ingroup CONSHDLRS
18  * @brief  constraint handler for pseudoboolean constraints
19  * @author Stefan Heinz
20  * @author Michael Winkler
21  */
22 
23 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
24 
25 #ifndef __SCIP_CONS_PSEUDOBOOLEAN_H__
26 #define __SCIP_CONS_PSEUDOBOOLEAN_H__
27 
28 
29 #include "scip/def.h"
30 #include "scip/type_cons.h"
31 #include "scip/type_retcode.h"
32 #include "scip/type_scip.h"
33 #include "scip/type_var.h"
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
39 #define ARTIFICIALVARNAMEPREFIX "andresultant_"
40 
41 
42 
43 /** creates the handler for pseudoboolean constraints and includes it in SCIP
44  *
45  * @ingroup ConshdlrIncludes
46  * */
47 SCIP_EXPORT
48 SCIP_RETCODE SCIPincludeConshdlrPseudoboolean(
49    SCIP*                 scip                /**< SCIP data structure */
50    );
51 
52 /**@addtogroup CONSHDLRS
53  *
54  * @{
55  *
56  * @name Pseudoboolean Constraints
57  *
58  * @{
59  *
60  * The constraint handler deals with pseudo boolean constraints. These are constraints of the form
61  * \f[
62  * \mbox{lhs} \leq \sum_{k=0}^m c_k \cdot x_k  +  \sum_{i=0}^n c_i \cdot \prod_{j \in I_i} x_j \leq \mbox{rhs}
63  * \f]
64  * where all \f$x\f$ are binary.
65  */
66 
67 /** solution status after solving LP */
68 enum SCIP_LinearConsType
69 {
70    SCIP_LINEARCONSTYPE_INVALIDCONS = -1,     /**< this is no valid linear constraint type */
71    SCIP_LINEARCONSTYPE_LINEAR      =  0,     /**< this is the common linear constraint */
72    SCIP_LINEARCONSTYPE_LOGICOR     =  1,     /**< this is a logicor constraint */
73    SCIP_LINEARCONSTYPE_KNAPSACK    =  2,     /**< this is a knapsack constraint */
74 #ifndef WITHEQKNAPSACK
75    SCIP_LINEARCONSTYPE_SETPPC      =  3      /**< this is a setppc constraint */
76 #else
77    SCIP_LINEARCONSTYPE_SETPPC      =  3,     /**< this is a setppc constraint */
78    SCIP_LINEARCONSTYPE_EQKNAPSACK  =  4      /**< this is a equality knapsack constraint */
79 #endif
80 };
81 typedef enum SCIP_LinearConsType SCIP_LINEARCONSTYPE;
82 
83 /** creates and captures a pseudoboolean constraint, with given linear and and-constraints
84  *
85  *  @note intvar must currently be NULL
86  */
87 SCIP_EXPORT
88 SCIP_RETCODE SCIPcreateConsPseudobooleanWithConss(
89    SCIP*                 scip,               /**< SCIP data structure */
90    SCIP_CONS**           cons,               /**< pointer to hold the created constraint */
91    const char*           name,               /**< name of constraint */
92    SCIP_CONS*            lincons,            /**< associated linear constraint */
93    SCIP_LINEARCONSTYPE   linconstype,        /**< linear constraint type of associated linear constraint */
94    SCIP_CONS**           andconss,           /**< associated and-constraints */
95    SCIP_Real*            andcoefs,           /**< associated coefficients of and-constraints */
96    int                   nandconss,          /**< number of associated and-constraints */
97    SCIP_VAR*             indvar,             /**< indicator variable if it's a soft constraint, or NULL */
98    SCIP_Real             weight,             /**< weight of the soft constraint, if it is one */
99    SCIP_Bool             issoftcons,         /**< is this a soft constraint */
100    SCIP_VAR*             intvar,             /**< an artificial variable which was added only for the objective function,
101                                               *   if this variable is not NULL this constraint (without this integer
102                                               *   variable) describes the objective function */
103    SCIP_Real             lhs,                /**< left hand side of constraint */
104    SCIP_Real             rhs,                /**< right hand side of constraint */
105    SCIP_Bool             initial,            /**< should the LP relaxation of constraint be in the initial LP?
106                                               *   Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
107    SCIP_Bool             separate,           /**< should the constraint be separated during LP processing?
108                                               *   Usually set to TRUE. */
109    SCIP_Bool             enforce,            /**< should the constraint be enforced during node processing?
110                                               *   TRUE for model constraints, FALSE for additional, redundant
111                                               *   constraints. */
112    SCIP_Bool             check,              /**< should the constraint be checked for feasibility?
113                                               *   TRUE for model constraints, FALSE for additional, redundant
114                                               *   constraints. */
115    SCIP_Bool             propagate,          /**< should the constraint be propagated during node processing?
116                                               *   Usually set to TRUE. */
117    SCIP_Bool             local,              /**< is constraint only valid locally?
118                                               *   Usually set to FALSE. Has to be set to TRUE, e.g., for branching
119                                               *   constraints. */
120    SCIP_Bool             modifiable,         /**< is constraint modifiable (subject to column generation)?
121                                               *   Usually set to FALSE. In column generation applications, set to TRUE if
122                                               *   pricing adds coefficients to this constraint. */
123    SCIP_Bool             dynamic,            /**< is constraint subject to aging?
124                                               *   Usually set to FALSE. Set to TRUE for own cuts which are seperated as
125                                               *   constraints. */
126    SCIP_Bool             removable,          /**< should the relaxation be removed from the LP due to aging or cleanup?
127                                               *   Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user
128                                               *   cuts'. */
129    SCIP_Bool             stickingatnode      /**< should the constraint always be kept at the node where it was added, even
130                                               *   if it may be moved to a more global node?
131                                               *   Usually set to FALSE. Set to TRUE to for constraints that represent
132                                               *   node data. */
133    );
134 
135 /** creates and captures a pseudoboolean constraint
136  *
137  *  @note linear and nonlinear terms can be added using SCIPaddCoefPseudoboolean() and SCIPaddTermPseudoboolean(),
138  *        respectively
139  *
140  *  @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
141  *
142  *  @note intvar must currently be NULL
143  */
144 SCIP_EXPORT
145 SCIP_RETCODE SCIPcreateConsPseudoboolean(
146    SCIP*                 scip,               /**< SCIP data structure */
147    SCIP_CONS**           cons,               /**< pointer to hold the created constraint */
148    const char*           name,               /**< name of constraint */
149    SCIP_VAR**            linvars,            /**< variables of the linear part, or NULL */
150    int                   nlinvars,           /**< number of variables of the linear part */
151    SCIP_Real*            linvals,            /**< coefficients of linear part, or NULL */
152    SCIP_VAR***           terms,              /**< nonlinear terms of variables, or NULL */
153    int                   nterms,             /**< number of terms of variables of nonlinear term */
154    int*                  ntermvars,          /**< number of variables in nonlinear terms, or NULL */
155    SCIP_Real*            termvals,           /**< coefficients of nonlinear parts, or NULL */
156    SCIP_VAR*             indvar,             /**< indicator variable if it's a soft constraint, or NULL */
157    SCIP_Real             weight,             /**< weight of the soft constraint, if it is one */
158    SCIP_Bool             issoftcons,         /**< is this a soft constraint */
159    SCIP_VAR*             intvar,             /**< an artificial variable which was added only for the objective function,
160                                               *   if this variable is not NULL this constraint (without this integer
161                                               *   variable) describes the objective function */
162    SCIP_Real             lhs,                /**< left hand side of constraint */
163    SCIP_Real             rhs,                /**< right hand side of constraint */
164    SCIP_Bool             initial,            /**< should the LP relaxation of constraint be in the initial LP?
165                                               *   Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
166    SCIP_Bool             separate,           /**< should the constraint be separated during LP processing?
167                                               *   Usually set to TRUE. */
168    SCIP_Bool             enforce,            /**< should the constraint be enforced during node processing?
169                                               *   TRUE for model constraints, FALSE for additional, redundant constraints. */
170    SCIP_Bool             check,              /**< should the constraint be checked for feasibility?
171                                               *   TRUE for model constraints, FALSE for additional, redundant constraints. */
172    SCIP_Bool             propagate,          /**< should the constraint be propagated during node processing?
173                                               *   Usually set to TRUE. */
174    SCIP_Bool             local,              /**< is constraint only valid locally?
175                                               *   Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
176    SCIP_Bool             modifiable,         /**< is constraint modifiable (subject to column generation)?
177                                               *   Usually set to FALSE. In column generation applications, set to TRUE if pricing
178                                               *   adds coefficients to this constraint. */
179    SCIP_Bool             dynamic,            /**< is constraint subject to aging?
180                                               *   Usually set to FALSE. Set to TRUE for own cuts which
181                                               *   are separated as constraints. */
182    SCIP_Bool             removable,          /**< should the relaxation be removed from the LP due to aging or cleanup?
183                                               *   Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
184    SCIP_Bool             stickingatnode      /**< should the constraint always be kept at the node where it was added, even
185                                               *   if it may be moved to a more global node?
186                                               *   Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
187    );
188 
189 /** creates and captures a pseudoboolean constraint
190  *  in its most basic variant, i. e., with all constraint flags set to their default values, which can be set
191  *  afterwards using SCIPsetConsFLAGNAME() in scip.h
192  *
193  *  @see SCIPcreateConsPseudoboolean() for the default constraint flag configuration
194  *
195  *  @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
196  *
197  *  @note intvar must currently be NULL
198  */
199 SCIP_EXPORT
200 SCIP_RETCODE SCIPcreateConsBasicPseudoboolean(
201    SCIP*                 scip,               /**< SCIP data structure */
202    SCIP_CONS**           cons,               /**< pointer to hold the created constraint */
203    const char*           name,               /**< name of constraint */
204    SCIP_VAR**            linvars,            /**< variables of the linear part, or NULL */
205    int                   nlinvars,           /**< number of variables of the linear part */
206    SCIP_Real*            linvals,            /**< coefficients of linear part, or NULL */
207    SCIP_VAR***           terms,              /**< nonlinear terms of variables, or NULL */
208    int                   nterms,             /**< number of terms of variables of nonlinear term */
209    int*                  ntermvars,          /**< number of variables in nonlinear terms, or NULL */
210    SCIP_Real*            termvals,           /**< coefficients of nonlinear parts, or NULL */
211    SCIP_VAR*             indvar,             /**< indicator variable if it's a soft constraint, or NULL */
212    SCIP_Real             weight,             /**< weight of the soft constraint, if it is one */
213    SCIP_Bool             issoftcons,         /**< is this a soft constraint */
214    SCIP_VAR*             intvar,             /**< a artificial variable which was added only for the objective function,
215                                               *   if this variable is not NULL this constraint (without this integer
216                                               *   variable) describes the objective function */
217    SCIP_Real             lhs,                /**< left hand side of constraint */
218    SCIP_Real             rhs                 /**< right hand side of constraint */
219    );
220 
221 /** adds linear term pseudo boolean constraint (if it is not zero)
222  *
223  * @note you can only add a coefficient if the special type of linear constraint won't changed
224  *
225  * @todo if adding a coefficient would change the type of the special linear constraint, we need to erase it and
226  *       create a new linear constraint
227  */
228 SCIP_EXPORT
229 SCIP_RETCODE SCIPaddCoefPseudoboolean(
230    SCIP*const            scip,               /**< SCIP data structure */
231    SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
232    SCIP_VAR* const       var,                /**< variable of constraint entry */
233    SCIP_Real const       val                 /**< coefficient of constraint entry */
234    );
235 
236 /** adds nonlinear term to pseudo boolean constraint (if it is not zero)
237  *
238  * @note you can only add a coefficient if the special type of linear constraint won't changed
239  *
240  * @todo if adding a coefficient would change the type of the special linear constraint, we need to erase it and
241  *       create a new linear constraint
242  */
243 SCIP_EXPORT
244 SCIP_RETCODE SCIPaddTermPseudoboolean(
245    SCIP*const            scip,               /**< SCIP data structure */
246    SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
247    SCIP_VAR**const       vars,               /**< variables of the nonlinear term */
248    int const             nvars,              /**< number of variables of the nonlinear term */
249    SCIP_Real const       val                 /**< coefficient of constraint entry */
250    );
251 
252 /** gets indicator variable of pseudoboolean constraint, or NULL if there is no */
253 SCIP_EXPORT
254 SCIP_VAR* SCIPgetIndVarPseudoboolean(
255    SCIP*const            scip,               /**< SCIP data structure */
256    SCIP_CONS*const       cons                /**< pseudoboolean constraint */
257    );
258 
259 /** gets linear constraint of pseudoboolean constraint */
260 SCIP_EXPORT
261 SCIP_CONS* SCIPgetLinearConsPseudoboolean(
262    SCIP*const            scip,               /**< SCIP data structure */
263    SCIP_CONS*const       cons                /**< pseudoboolean constraint */
264    );
265 
266 /** gets type of linear constraint of pseudoboolean constraint */
267 SCIP_EXPORT
268 SCIP_LINEARCONSTYPE SCIPgetLinearConsTypePseudoboolean(
269    SCIP*const            scip,               /**< SCIP data structure */
270    SCIP_CONS*const       cons                /**< pseudoboolean constraint */
271    );
272 
273 /** gets number of linear variables without artificial terms variables of pseudoboolean constraint */
274 SCIP_EXPORT
275 int SCIPgetNLinVarsWithoutAndPseudoboolean(
276    SCIP*const            scip,               /**< SCIP data structure */
277    SCIP_CONS*const       cons                /**< pseudoboolean constraint */
278    );
279 
280 /** gets linear constraint of pseudoboolean constraint */
281 SCIP_EXPORT
282 SCIP_RETCODE SCIPgetLinDatasWithoutAndPseudoboolean(
283    SCIP*const            scip,               /**< SCIP data structure */
284    SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
285    SCIP_VAR**const       linvars,            /**< array to store and-constraints */
286    SCIP_Real*const       lincoefs,           /**< array to store and-coefficients */
287    int*const             nlinvars            /**< pointer to store the required array size for and-constraints, have to
288                                               *   be initialized with size of given array */
289    );
290 
291 /** gets and-constraints of pseudoboolean constraint */
292 SCIP_EXPORT
293 SCIP_RETCODE SCIPgetAndDatasPseudoboolean(
294    SCIP*const            scip,               /**< SCIP data structure */
295    SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
296    SCIP_CONS**const      andconss,           /**< array to store and-constraints */
297    SCIP_Real*const       andcoefs,           /**< array to store and-coefficients */
298    int*const             nandconss           /**< pointer to store the required array size for and-constraints, have to
299                                               *   be initialized with size of given array */
300    );
301 
302 /** gets number of and constraints of pseudoboolean constraint */
303 SCIP_EXPORT
304 int SCIPgetNAndsPseudoboolean(
305    SCIP*const            scip,               /**< SCIP data structure */
306    SCIP_CONS*const       cons                /**< pseudoboolean constraint */
307    );
308 
309 /** changes left hand side of pseudoboolean constraint
310  *
311  * @note you can only change the left hand side if the special type of linear constraint won't changed
312  *
313  * @todo if changing the left hand side would change the type of the special linear constraint, we need to erase it
314  *       and create a new linear constraint
315  */
316 SCIP_EXPORT
317 SCIP_RETCODE SCIPchgLhsPseudoboolean(
318    SCIP*const            scip,               /**< SCIP data structure */
319    SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
320    SCIP_Real const       lhs                 /**< new left hand side */
321    );
322 
323 /** changes right hand side of pseudoboolean constraint
324  *
325  * @note you can only change the right hand side if the special type of linear constraint won't changed
326  *
327  * @todo if changing the right hand side would change the type of the special linear constraint, we need to erase it
328  *       and create a new linear constraint
329  */
330 SCIP_EXPORT
331 SCIP_RETCODE SCIPchgRhsPseudoboolean(
332    SCIP*const            scip,               /**< SCIP data structure */
333    SCIP_CONS*const       cons,               /**< pseudoboolean constraint */
334    SCIP_Real const       rhs                 /**< new right hand side */
335    );
336 
337 /** get left hand side of pseudoboolean constraint */
338 SCIP_EXPORT
339 SCIP_Real SCIPgetLhsPseudoboolean(
340    SCIP*const            scip,               /**< SCIP data structure */
341    SCIP_CONS*const       cons                /**< pseudoboolean constraint */
342    );
343 
344 /** get right hand side of pseudoboolean constraint */
345 SCIP_EXPORT
346 SCIP_Real SCIPgetRhsPseudoboolean(
347    SCIP*const            scip,               /**< SCIP data structure */
348    SCIP_CONS*const       cons                /**< pseudoboolean constraint */
349    );
350 
351 /** @} */
352 
353 /** @} */
354 
355 #ifdef __cplusplus
356 }
357 #endif
358 
359 #endif
360