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   objconshdlr.h
17  * @brief  C++ wrapper for constraint handlers
18  * @author Tobias Achterberg
19  */
20 
21 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
22 
23 #ifndef __SCIP_OBJCONSHDLR_H__
24 #define __SCIP_OBJCONSHDLR_H__
25 
26 
27 #include <cassert>
28 #include <cstring>
29 
30 #include "scip/scip.h"
31 #include "objscip/objprobcloneable.h"
32 
33 namespace scip
34 {
35 
36 /**
37  *  @brief C++ wrapper for constraint handlers
38  *
39  *  This class defines the interface for constraint handlers implemented in C++. Note that there are pure virtual
40  *  functions (these have to be implemented). These functions are: scip_trans(), scip_enfolp(), scip_enforelax(),
41  *  scip_enfops(), scip_check(), and scip_lock().
42  *
43  *  - \ref CONS "Instructions for implementing a constraint handler"
44  *  - \ref CONSHDLRS "List of available constraint handlers"
45  *  - \ref type_cons.h "Corresponding C interface"
46  */
47 class ObjConshdlr : public ObjProbCloneable
48 {
49 public:
50    /*lint --e{1540}*/
51 
52    /** SCIP data structure */
53    SCIP* scip_;
54 
55    /** name of the constraint handler */
56    char* scip_name_;
57 
58    /** description of the constraint handler */
59    char* scip_desc_;
60 
61    /** default separation priority of the constraint handler */
62    const int scip_sepapriority_;
63 
64    /** default enforcing priority of the constraint handler */
65    const int scip_enfopriority_;
66 
67    /** default checking priority of the constraint handler */
68    const int scip_checkpriority_;
69 
70    /** default separation frequency of the constraint handler */
71    const int scip_sepafreq_;
72 
73    /** default propagation frequency of the constraint handler */
74    const int scip_propfreq_;
75 
76    /** default frequency of the constraint handler for eager evaluations in separation, propagation and enforcement */
77    const int scip_eagerfreq_;
78 
79    /** maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
80    const int scip_maxprerounds_;
81 
82    /** should separation method be delayed, if other separators found cuts? */
83    const SCIP_Bool scip_delaysepa_;
84 
85    /** should propagation method be delayed, if other propagators found reductions? */
86    const SCIP_Bool scip_delayprop_;
87 
88    /** should the constraint handler be skipped, if no constraints are available? */
89    const SCIP_Bool scip_needscons_;
90 
91    /** positions in the node solving loop where propagation method of constraint handler should be executed */
92    const SCIP_PROPTIMING scip_proptiming_;
93 
94    /**< timing mask of the constraint handler's presolving method */
95    const SCIP_PRESOLTIMING scip_presoltiming_;
96 
97    /** default constructor */
ObjConshdlr(SCIP * scip,const char * name,const char * desc,int sepapriority,int enfopriority,int checkpriority,int sepafreq,int propfreq,int eagerfreq,int maxprerounds,SCIP_Bool delaysepa,SCIP_Bool delayprop,SCIP_Bool needscons,SCIP_PROPTIMING proptiming,SCIP_PRESOLTIMING presoltiming)98    ObjConshdlr(
99       SCIP*              scip,               /**< SCIP data structure */
100       const char*        name,               /**< name of constraint handler */
101       const char*        desc,               /**< description of constraint handler */
102       int                sepapriority,       /**< priority of the constraint handler for separation */
103       int                enfopriority,       /**< priority of the constraint handler for constraint enforcing */
104       int                checkpriority,      /**< priority of the constraint handler for checking infeasibility (and propagation) */
105       int                sepafreq,           /**< frequency for separating cuts; zero means to separate only in the root node */
106       int                propfreq,           /**< frequency for propagating domains; zero means only preprocessing propagation */
107       int                eagerfreq,          /**< frequency for using all instead of only the useful constraints in separation,
108                                               *   propagation and enforcement, -1 for no eager evaluations, 0 for first only */
109       int                maxprerounds,       /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
110       SCIP_Bool          delaysepa,          /**< should separation method be delayed, if other separators found cuts? */
111       SCIP_Bool          delayprop,          /**< should propagation method be delayed, if other propagators found reductions? */
112       SCIP_Bool          needscons,          /**< should the constraint handler be skipped, if no constraints are available? */
113       SCIP_PROPTIMING    proptiming,         /**< positions in the node solving loop where propagation method of constraint handlers should be executed */
114       SCIP_PRESOLTIMING  presoltiming        /**< timing mask of the constraint handler's presolving method */
115       )
116       : scip_(scip),
117         scip_name_(0),
118         scip_desc_(0),
119         scip_sepapriority_(sepapriority),
120         scip_enfopriority_(enfopriority),
121         scip_checkpriority_(checkpriority),
122         scip_sepafreq_(sepafreq),
123         scip_propfreq_(propfreq),
124         scip_eagerfreq_(eagerfreq),
125         scip_maxprerounds_(maxprerounds),
126         scip_delaysepa_(delaysepa),
127         scip_delayprop_(delayprop),
128         scip_needscons_(needscons),
129         scip_proptiming_(proptiming),
130         scip_presoltiming_(presoltiming)
131    {
132       /* the macro SCIPduplicateMemoryArray does not need the first argument: */
133       SCIP_CALL_ABORT( SCIPduplicateMemoryArray(scip_, &scip_name_, name, std::strlen(name)+1) );
134       SCIP_CALL_ABORT( SCIPduplicateMemoryArray(scip_, &scip_desc_, desc, std::strlen(desc)+1) );
135    }
136 
137    /** destructor */
~ObjConshdlr()138    virtual ~ObjConshdlr()
139    {
140       /* the macro SCIPfreeMemoryArray does not need the first argument: */
141       /*lint --e{64}*/
142       SCIPfreeMemoryArray(scip_, &scip_name_);
143       SCIPfreeMemoryArray(scip_, &scip_desc_);
144    }
145 
146    /** destructor of constraint handler to free user data (called when SCIP is exiting)
147     *
148     *  @see SCIP_DECL_CONSFREE(x) in @ref type_cons.h
149     */
SCIP_DECL_CONSFREE(scip_free)150    virtual SCIP_DECL_CONSFREE(scip_free)
151    {  /*lint --e{715}*/
152       return SCIP_OKAY;
153    }
154 
155    /** initialization method of constraint handler (called after problem has been transformed)
156     *
157     *  @see SCIP_DECL_CONSINIT(x) in @ref type_cons.h
158     */
SCIP_DECL_CONSINIT(scip_init)159    virtual SCIP_DECL_CONSINIT(scip_init)
160    {  /*lint --e{715}*/
161       return SCIP_OKAY;
162    }
163 
164    /** deinitialization method of constraint handler (called before transformed problem is freed)
165     *
166     *  @see SCIP_DECL_CONSEXIT(x) in @ref type_cons.h
167     */
SCIP_DECL_CONSEXIT(scip_exit)168    virtual SCIP_DECL_CONSEXIT(scip_exit)
169    {  /*lint --e{715}*/
170       return SCIP_OKAY;
171    }
172 
173    /** presolving initialization method of constraint handler (called when presolving is about to begin)
174     *
175     *  @see SCIP_DECL_CONSINITPRE(x) in @ref type_cons.h
176     */
SCIP_DECL_CONSINITPRE(scip_initpre)177    virtual SCIP_DECL_CONSINITPRE(scip_initpre)
178    {  /*lint --e{715}*/
179       return SCIP_OKAY;
180    }
181 
182    /** presolving deinitialization method of constraint handler (called after presolving has been finished)
183     *
184     *  @see SCIP_DECL_CONSEXITPRE(x) in @ref type_cons.h
185     */
SCIP_DECL_CONSEXITPRE(scip_exitpre)186    virtual SCIP_DECL_CONSEXITPRE(scip_exitpre)
187    {  /*lint --e{715}*/
188       return SCIP_OKAY;
189    }
190 
191    /** solving process initialization method of constraint handler (called when branch and bound process is about to begin)
192     *
193     *  @see SCIP_DECL_CONSINITSOL(x) in @ref type_cons.h
194     */
SCIP_DECL_CONSINITSOL(scip_initsol)195    virtual SCIP_DECL_CONSINITSOL(scip_initsol)
196    {  /*lint --e{715}*/
197       return SCIP_OKAY;
198    }
199 
200    /** solving process deinitialization method of constraint handler (called before branch and bound process data is freed)
201     *
202     *  @see SCIP_DECL_CONSEXITSOL(x) in @ref type_cons.h
203     */
SCIP_DECL_CONSEXITSOL(scip_exitsol)204    virtual SCIP_DECL_CONSEXITSOL(scip_exitsol)
205    {  /*lint --e{715}*/
206       return SCIP_OKAY;
207    }
208 
209    /** frees specific constraint data
210     *
211     *  @see SCIP_DECL_CONSDELETE(x) in @ref type_cons.h
212     */
SCIP_DECL_CONSDELETE(scip_delete)213    virtual SCIP_DECL_CONSDELETE(scip_delete)
214    {  /*lint --e{715}*/
215       return SCIP_OKAY;
216    }
217 
218    /** transforms constraint data into data belonging to the transformed problem
219     *
220     *  @see SCIP_DECL_CONSTRANS(x) in @ref type_cons.h
221     */
222    virtual SCIP_DECL_CONSTRANS(scip_trans) = 0;
223 
224    /** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved)
225     *
226     *  @see SCIP_DECL_CONSINITLP(x) in @ref type_cons.h
227     */
SCIP_DECL_CONSINITLP(scip_initlp)228    virtual SCIP_DECL_CONSINITLP(scip_initlp)
229    {  /*lint --e{715}*/
230       return SCIP_OKAY;
231    }
232 
233    /** separation method of constraint handler for LP solution
234     *
235     *  @see SCIP_DECL_CONSSEPALP(x) in @ref type_cons.h
236     */
SCIP_DECL_CONSSEPALP(scip_sepalp)237    virtual SCIP_DECL_CONSSEPALP(scip_sepalp)
238    {  /*lint --e{715}*/
239       assert(result != NULL);
240       *result = SCIP_DIDNOTRUN;
241       return SCIP_OKAY;
242    }
243 
244    /** separation method of constraint handler for arbitrary primal solution
245     *
246     *  @see SCIP_DECL_CONSSEPASOL(x) in @ref type_cons.h
247     */
SCIP_DECL_CONSSEPASOL(scip_sepasol)248    virtual SCIP_DECL_CONSSEPASOL(scip_sepasol)
249    {  /*lint --e{715}*/
250       assert(result != NULL);
251       *result = SCIP_DIDNOTRUN;
252       return SCIP_OKAY;
253    }
254 
255    /** constraint enforcing method of constraint handler for LP solutions
256     *
257     *  @see SCIP_DECL_CONSENFOLP(x) in @ref type_cons.h
258     */
259    virtual SCIP_DECL_CONSENFOLP(scip_enfolp) = 0;
260 
261    /** constraint enforcing method of constraint handler for relaxation solutions
262     *
263     *  @see SCIP_DECL_CONSENFORELAX(x) in @ref type_cons.h
264     */
SCIP_DECL_CONSENFORELAX(scip_enforelax)265    virtual SCIP_DECL_CONSENFORELAX(scip_enforelax)
266    {  /*lint --e{715}*/
267       assert(result != NULL);
268       *result = SCIP_DIDNOTRUN;
269       return SCIP_OKAY;
270    }
271 
272    /** constraint enforcing method of constraint handler for pseudo solutions
273     *
274     *  @see SCIP_DECL_CONSENFOPS(x) in @ref type_cons.h
275     */
276    virtual SCIP_DECL_CONSENFOPS(scip_enfops) = 0;
277 
278    /** feasibility check method of constraint handler for primal solutions
279     *
280     *  @see SCIP_DECL_CONSCHECK(x) in @ref type_cons.h
281     */
282    virtual SCIP_DECL_CONSCHECK(scip_check) = 0;
283 
284    /** domain propagation method of constraint handler
285     *
286     *  @see SCIP_DECL_CONSPROP(x) in @ref type_cons.h
287     */
SCIP_DECL_CONSPROP(scip_prop)288    virtual SCIP_DECL_CONSPROP(scip_prop)
289    {  /*lint --e{715}*/
290       assert(result != NULL);
291       *result = SCIP_DIDNOTRUN;
292       return SCIP_OKAY;
293    }
294 
295    /** presolving method of constraint handler
296     *
297     *  @see SCIP_DECL_CONSPRESOL(x) in @ref type_cons.h
298     */
SCIP_DECL_CONSPRESOL(scip_presol)299    virtual SCIP_DECL_CONSPRESOL(scip_presol)
300    {  /*lint --e{715}*/
301       assert(result != NULL);
302       *result = SCIP_DIDNOTRUN;
303       return SCIP_OKAY;
304    }
305 
306    /** propagation conflict resolving method of constraint handler
307     *
308     *  @see SCIP_DECL_CONSRESPROP(x) in @ref type_cons.h
309     */
SCIP_DECL_CONSRESPROP(scip_resprop)310    virtual SCIP_DECL_CONSRESPROP(scip_resprop)
311    {  /*lint --e{715}*/
312       assert(result != NULL);
313       *result = SCIP_DIDNOTFIND;
314       return SCIP_OKAY;
315    }
316 
317    /** variable rounding lock method of constraint handler
318     *
319     *  @see SCIP_DECL_CONSLOCK(x) in @ref type_cons.h
320     */
321    virtual SCIP_DECL_CONSLOCK(scip_lock) = 0;
322 
323    /** constraint activation notification method of constraint handler
324     *
325     *  @see SCIP_DECL_CONSACTIVE(x) in @ref type_cons.h
326     */
SCIP_DECL_CONSACTIVE(scip_active)327    virtual SCIP_DECL_CONSACTIVE(scip_active)
328    {  /*lint --e{715}*/
329       return SCIP_OKAY;
330    }
331 
332    /** constraint deactivation notification method of constraint handler
333     *
334     *  @see SCIP_DECL_CONSDEACTIVE(x) in @ref type_cons.h
335     */
SCIP_DECL_CONSDEACTIVE(scip_deactive)336    virtual SCIP_DECL_CONSDEACTIVE(scip_deactive)
337    {  /*lint --e{715}*/
338       return SCIP_OKAY;
339    }
340 
341    /** constraint enabling notification method of constraint handler
342     *
343     *  @see SCIP_DECL_CONSENABLE(x) in @ref type_cons.h
344     */
SCIP_DECL_CONSENABLE(scip_enable)345    virtual SCIP_DECL_CONSENABLE(scip_enable)
346    {  /*lint --e{715}*/
347       return SCIP_OKAY;
348    }
349 
350    /** constraint disabling notification method of constraint handler
351     *
352     *  @see SCIP_DECL_CONSDISABLE(x) in @ref type_cons.h
353     */
SCIP_DECL_CONSDISABLE(scip_disable)354    virtual SCIP_DECL_CONSDISABLE(scip_disable)
355    {  /*lint --e{715}*/
356       return SCIP_OKAY;
357    }
358 
359    /** variable deletion method of constraint handler
360     *
361     *  @see SCIP_DECL_CONSDELVARS(x) in @ref type_cons.h
362     */
SCIP_DECL_CONSDELVARS(scip_delvars)363    virtual SCIP_DECL_CONSDELVARS(scip_delvars)
364    {  /*lint --e{715}*/
365       return SCIP_OKAY;
366    }
367 
368    /** constraint display method of constraint handler
369     *
370     *  @see SCIP_DECL_CONSPRINT(x) in @ref type_cons.h
371     */
SCIP_DECL_CONSPRINT(scip_print)372    virtual SCIP_DECL_CONSPRINT(scip_print)
373    {  /*lint --e{715}*/
374       if ( file == NULL )
375 	 fprintf(stdout, "constraint handler <%s> does not support printing constraints\n", SCIPconshdlrGetName(conshdlr));
376       else
377 	 fprintf(file, "constraint handler <%s> does not support printing constraints\n", SCIPconshdlrGetName(conshdlr));
378       return SCIP_OKAY;
379    }
380 
381    /** constraint copying method of constraint handler
382     *
383     *  @see SCIP_DECL_CONSCOPY(x) in @ref type_cons.h
384     */
SCIP_DECL_CONSCOPY(scip_copy)385    virtual SCIP_DECL_CONSCOPY(scip_copy)
386    {  /*lint --e{715}*/
387       *valid = FALSE;
388       return SCIP_OKAY;
389    }
390 
391    /** constraint parsing method of constraint handler
392     *
393     *  @see SCIP_DECL_CONSPARSE(x) in @ref type_cons.h
394     */
SCIP_DECL_CONSPARSE(scip_parse)395    virtual SCIP_DECL_CONSPARSE(scip_parse)
396    {  /*lint --e{715}*/
397       return SCIP_OKAY;
398    }
399 
400    /** constraint method of constraint handler which returns the variables (if possible)
401     *
402     *  @see SCIP_DECL_CONSGETVARS(x) in @ref type_cons.h
403     */
SCIP_DECL_CONSGETVARS(scip_getvars)404    virtual SCIP_DECL_CONSGETVARS(scip_getvars)
405    {  /*lint --e{715}*/
406 
407       (*success) = FALSE;
408 
409       return SCIP_OKAY;
410    }
411 
412    /** constraint method of constraint handler which returns the number of variables (if possible)
413     *
414     *  @see SCIP_DECL_CONSGETNVARS(x) in @ref type_cons.h
415     */
SCIP_DECL_CONSGETNVARS(scip_getnvars)416    virtual SCIP_DECL_CONSGETNVARS(scip_getnvars)
417    {  /*lint --e{715}*/
418 
419       (*nvars) = 0;
420       (*success) = FALSE;
421 
422       return SCIP_OKAY;
423    }
424 
425    /** constraint handler method to suggest dive bound changes during the generic diving algorithm
426     *
427     *  @see SCIP_DECL_CONSGETDIVEBDCHGS(x) in @ref type_cons.h
428     */
SCIP_DECL_CONSGETDIVEBDCHGS(scip_getdivebdchgs)429    virtual SCIP_DECL_CONSGETDIVEBDCHGS(scip_getdivebdchgs)
430    {  /*lint --e{715}*/
431 
432       (*success) = FALSE;
433 
434       return SCIP_OKAY;
435    }
436 };
437 
438 } /* namespace scip */
439 
440 
441 
442 /** creates the constraint handler for the given constraint handler object and includes it in SCIP
443  *
444  *  The method should be called in one of the following ways:
445  *
446  *   1. The user is resposible of deleting the object:
447  *       SCIP_CALL( SCIPcreate(&scip) );
448  *       ...
449  *       MyConshdlr* myconshdlr = new MyConshdlr(...);
450  *       SCIP_CALL( SCIPincludeObjConshdlr(scip, &myconshdlr, FALSE) );
451  *       ...
452  *       SCIP_CALL( SCIPfree(&scip) );
453  *       delete myconshdlr;    // delete conshdlr AFTER SCIPfree() !
454  *
455  *   2. The object pointer is passed to SCIP and deleted by SCIP in the SCIPfree() call:
456  *       SCIP_CALL( SCIPcreate(&scip) );
457  *       ...
458  *       SCIP_CALL( SCIPincludeObjConshdlr(scip, new MyConshdlr(...), TRUE) );
459  *       ...
460  *       SCIP_CALL( SCIPfree(&scip) );  // destructor of MyConshdlr is called here
461  */
462 SCIP_EXPORT
463 SCIP_RETCODE SCIPincludeObjConshdlr(
464    SCIP*                 scip,               /**< SCIP data structure */
465    scip::ObjConshdlr*    objconshdlr,        /**< constraint handler object */
466    SCIP_Bool             deleteobject        /**< should the constraint handler object be deleted when conshdlr is freed? */
467    );
468 
469 /** returns the conshdlr object of the given name, or 0 if not existing */
470 SCIP_EXPORT
471 scip::ObjConshdlr* SCIPfindObjConshdlr(
472    SCIP*                 scip,               /**< SCIP data structure */
473    const char*           name                /**< name of constraint handler */
474    );
475 
476 /** returns the conshdlr object for the given constraint handler */
477 SCIP_EXPORT
478 scip::ObjConshdlr* SCIPgetObjConshdlr(
479    SCIP*                 scip,               /**< SCIP data structure */
480    SCIP_CONSHDLR*        conshdlr            /**< constraint handler */
481    );
482 
483 #endif
484