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 scip_relax.c
17 * @ingroup OTHER_CFILES
18 * @brief public methods for relaxator plugins
19 * @author Tobias Achterberg
20 * @author Timo Berthold
21 * @author Gerald Gamrath
22 * @author Leona Gottwald
23 * @author Stefan Heinz
24 * @author Gregor Hendel
25 * @author Thorsten Koch
26 * @author Alexander Martin
27 * @author Marc Pfetsch
28 * @author Michael Winkler
29 * @author Kati Wolter
30 *
31 * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
32 */
33
34 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35
36 #include "scip/debug.h"
37 #include "scip/pub_message.h"
38 #include "scip/relax.h"
39 #include "scip/scip_relax.h"
40 #include "scip/set.h"
41 #include "scip/struct_mem.h"
42 #include "scip/struct_scip.h"
43 #include "scip/struct_set.h"
44
45 /** creates a relaxation handler and includes it in SCIP
46 *
47 * @note method has all relaxation handler callbacks as arguments and is thus changed every time a new
48 * callback is added
49 * in future releases; consider using SCIPincludeRelaxBasic() and setter functions
50 * if you seek for a method which is less likely to change in future releases
51 */
SCIPincludeRelax(SCIP * scip,const char * name,const char * desc,int priority,int freq,SCIP_DECL_RELAXCOPY ((* relaxcopy)),SCIP_DECL_RELAXFREE ((* relaxfree)),SCIP_DECL_RELAXINIT ((* relaxinit)),SCIP_DECL_RELAXEXIT ((* relaxexit)),SCIP_DECL_RELAXINITSOL ((* relaxinitsol)),SCIP_DECL_RELAXEXITSOL ((* relaxexitsol)),SCIP_DECL_RELAXEXEC ((* relaxexec)),SCIP_RELAXDATA * relaxdata)52 SCIP_RETCODE SCIPincludeRelax(
53 SCIP* scip, /**< SCIP data structure */
54 const char* name, /**< name of relaxation handler */
55 const char* desc, /**< description of relaxation handler */
56 int priority, /**< priority of the relaxation handler (negative: after LP, non-negative: before LP) */
57 int freq, /**< frequency for calling relaxation handler */
58 SCIP_DECL_RELAXCOPY ((*relaxcopy)), /**< copy method of relaxation handler or NULL if you don't want to copy your plugin into sub-SCIPs */
59 SCIP_DECL_RELAXFREE ((*relaxfree)), /**< destructor of relaxation handler */
60 SCIP_DECL_RELAXINIT ((*relaxinit)), /**< initialize relaxation handler */
61 SCIP_DECL_RELAXEXIT ((*relaxexit)), /**< deinitialize relaxation handler */
62 SCIP_DECL_RELAXINITSOL((*relaxinitsol)), /**< solving process initialization method of relaxation handler */
63 SCIP_DECL_RELAXEXITSOL((*relaxexitsol)), /**< solving process deinitialization method of relaxation handler */
64 SCIP_DECL_RELAXEXEC ((*relaxexec)), /**< execution method of relaxation handler */
65 SCIP_RELAXDATA* relaxdata /**< relaxation handler data */
66 )
67 {
68 SCIP_RELAX* relax;
69
70 SCIP_CALL( SCIPcheckStage(scip, "SCIPincludeRelax", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
71
72 /* check whether relaxation handler is already present */
73 if( SCIPfindRelax(scip, name) != NULL )
74 {
75 SCIPerrorMessage("relaxation handler <%s> already included.\n", name);
76 return SCIP_INVALIDDATA;
77 }
78
79 SCIP_CALL( SCIPrelaxCreate(&relax, scip->set, scip->messagehdlr, scip->mem->setmem,
80 name, desc, priority, freq, relaxcopy,
81 relaxfree, relaxinit, relaxexit, relaxinitsol, relaxexitsol, relaxexec, relaxdata) );
82 SCIP_CALL( SCIPsetIncludeRelax(scip->set, relax) );
83
84 return SCIP_OKAY;
85 }
86
87 /** creates a relaxation handler and includes it in SCIP. All non fundamental
88 * (or optional) callbacks as, e.g., init and exit callbacks, will be set to NULL.
89 * Optional callbacks can be set via specific setter functions, see SCIPsetRelaxInit(), SCIPsetRelaxExit(),
90 * SCIPsetRelaxCopy(), SCIPsetRelaxFree(), SCIPsetRelaxInitsol(), and SCIPsetRelaxExitsol()
91 *
92 * @note if you want to set all callbacks with a single method call, consider using SCIPincludeRelax() instead
93 */
SCIPincludeRelaxBasic(SCIP * scip,SCIP_RELAX ** relaxptr,const char * name,const char * desc,int priority,int freq,SCIP_DECL_RELAXEXEC ((* relaxexec)),SCIP_RELAXDATA * relaxdata)94 SCIP_RETCODE SCIPincludeRelaxBasic(
95 SCIP* scip, /**< SCIP data structure */
96 SCIP_RELAX** relaxptr, /**< reference to relaxation pointer, or NULL */
97 const char* name, /**< name of relaxation handler */
98 const char* desc, /**< description of relaxation handler */
99 int priority, /**< priority of the relaxation handler (negative: after LP, non-negative: before LP) */
100 int freq, /**< frequency for calling relaxation handler */
101 SCIP_DECL_RELAXEXEC ((*relaxexec)), /**< execution method of relaxation handler */
102 SCIP_RELAXDATA* relaxdata /**< relaxation handler data */
103 )
104 {
105 SCIP_RELAX* relax;
106
107 SCIP_CALL( SCIPcheckStage(scip, "SCIPincludeRelaxBasic", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
108
109 /* check whether relaxation handler is already present */
110 if( SCIPfindRelax(scip, name) != NULL )
111 {
112 SCIPerrorMessage("relaxation handler <%s> already included.\n", name);
113 return SCIP_INVALIDDATA;
114 }
115
116 SCIP_CALL( SCIPrelaxCreate(&relax, scip->set, scip->messagehdlr, scip->mem->setmem,
117 name, desc, priority, freq,
118 NULL, NULL, NULL, NULL, NULL, NULL, relaxexec, relaxdata) );
119 SCIP_CALL( SCIPsetIncludeRelax(scip->set, relax) );
120
121 if( relaxptr != NULL )
122 *relaxptr = relax;
123
124 return SCIP_OKAY;
125 }
126
127 /** sets copy method of relaxation handler */
SCIPsetRelaxCopy(SCIP * scip,SCIP_RELAX * relax,SCIP_DECL_RELAXCOPY ((* relaxcopy)))128 SCIP_RETCODE SCIPsetRelaxCopy(
129 SCIP* scip, /**< SCIP data structure */
130 SCIP_RELAX* relax, /**< relaxation handler */
131 SCIP_DECL_RELAXCOPY ((*relaxcopy)) /**< copy method of relaxation handler or NULL if you don't want to copy your plugin into sub-SCIPs */
132 )
133 {
134 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxCopy", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
135
136 assert(relax != NULL);
137
138 SCIPrelaxSetCopy(relax, relaxcopy);
139
140 return SCIP_OKAY;
141 }
142
143 /** sets destructor method of relaxation handler */
SCIPsetRelaxFree(SCIP * scip,SCIP_RELAX * relax,SCIP_DECL_RELAXFREE ((* relaxfree)))144 SCIP_RETCODE SCIPsetRelaxFree(
145 SCIP* scip, /**< SCIP data structure */
146 SCIP_RELAX* relax, /**< relaxation handler */
147 SCIP_DECL_RELAXFREE ((*relaxfree)) /**< destructor of relaxation handler */
148 )
149 {
150 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxFree", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
151
152 assert(relax != NULL);
153
154 SCIPrelaxSetFree(relax, relaxfree);
155
156 return SCIP_OKAY;
157 }
158
159 /** sets initialization method of relaxation handler */
SCIPsetRelaxInit(SCIP * scip,SCIP_RELAX * relax,SCIP_DECL_RELAXINIT ((* relaxinit)))160 SCIP_RETCODE SCIPsetRelaxInit(
161 SCIP* scip, /**< SCIP data structure */
162 SCIP_RELAX* relax, /**< relaxation handler */
163 SCIP_DECL_RELAXINIT ((*relaxinit)) /**< initialize relaxation handler */
164 )
165 {
166 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxInit", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
167
168 assert(relax != NULL);
169
170 SCIPrelaxSetInit(relax, relaxinit);
171
172 return SCIP_OKAY;
173 }
174
175 /** sets deinitialization method of relaxation handler */
SCIPsetRelaxExit(SCIP * scip,SCIP_RELAX * relax,SCIP_DECL_RELAXEXIT ((* relaxexit)))176 SCIP_RETCODE SCIPsetRelaxExit(
177 SCIP* scip, /**< SCIP data structure */
178 SCIP_RELAX* relax, /**< relaxation handler */
179 SCIP_DECL_RELAXEXIT ((*relaxexit)) /**< deinitialize relaxation handler */
180 )
181 {
182 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxExit", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
183
184 assert(relax != NULL);
185
186 SCIPrelaxSetExit(relax, relaxexit);
187
188 return SCIP_OKAY;
189 }
190
191 /** sets solving process initialization method of relaxation handler */
SCIPsetRelaxInitsol(SCIP * scip,SCIP_RELAX * relax,SCIP_DECL_RELAXINITSOL ((* relaxinitsol)))192 SCIP_RETCODE SCIPsetRelaxInitsol(
193 SCIP* scip, /**< SCIP data structure */
194 SCIP_RELAX* relax, /**< relaxation handler */
195 SCIP_DECL_RELAXINITSOL((*relaxinitsol)) /**< solving process initialization method of relaxation handler */
196 )
197 {
198 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxInitsol", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
199
200 assert(relax != NULL);
201
202 SCIPrelaxSetInitsol(relax, relaxinitsol);
203
204 return SCIP_OKAY;
205 }
206
207 /** sets solving process deinitialization method of relaxation handler */
SCIPsetRelaxExitsol(SCIP * scip,SCIP_RELAX * relax,SCIP_DECL_RELAXEXITSOL ((* relaxexitsol)))208 SCIP_RETCODE SCIPsetRelaxExitsol(
209 SCIP* scip, /**< SCIP data structure */
210 SCIP_RELAX* relax, /**< relaxation handler */
211 SCIP_DECL_RELAXEXITSOL((*relaxexitsol)) /**< solving process deinitialization method of relaxation handler */
212 )
213 {
214 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetRelaxExitsol", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
215
216 assert(relax != NULL);
217
218 SCIPrelaxSetExitsol(relax, relaxexitsol);
219
220 return SCIP_OKAY;
221 }
222
223
224 /** returns the relaxation handler of the given name, or NULL if not existing */
SCIPfindRelax(SCIP * scip,const char * name)225 SCIP_RELAX* SCIPfindRelax(
226 SCIP* scip, /**< SCIP data structure */
227 const char* name /**< name of relaxation handler */
228 )
229 {
230 assert(scip != NULL);
231 assert(scip->set != NULL);
232 assert(name != NULL);
233
234 return SCIPsetFindRelax(scip->set, name);
235 }
236
237 /** returns the array of currently available relaxation handlers */
SCIPgetRelaxs(SCIP * scip)238 SCIP_RELAX** SCIPgetRelaxs(
239 SCIP* scip /**< SCIP data structure */
240 )
241 {
242 assert(scip != NULL);
243 assert(scip->set != NULL);
244
245 SCIPsetSortRelaxs(scip->set);
246
247 return scip->set->relaxs;
248 }
249
250 /** returns the number of currently available relaxation handlers */
SCIPgetNRelaxs(SCIP * scip)251 int SCIPgetNRelaxs(
252 SCIP* scip /**< SCIP data structure */
253 )
254 {
255 assert(scip != NULL);
256 assert(scip->set != NULL);
257
258 return scip->set->nrelaxs;
259 }
260
261 /** sets the priority of a relaxation handler */
SCIPsetRelaxPriority(SCIP * scip,SCIP_RELAX * relax,int priority)262 SCIP_RETCODE SCIPsetRelaxPriority(
263 SCIP* scip, /**< SCIP data structure */
264 SCIP_RELAX* relax, /**< relaxation handler */
265 int priority /**< new priority of the relaxation handler */
266 )
267 {
268 assert(scip != NULL);
269 assert(scip->set != NULL);
270
271 SCIPrelaxSetPriority(relax, scip->set, priority);
272
273 return SCIP_OKAY;
274 }
275