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_pricer.c
17 * @ingroup OTHER_CFILES
18 * @brief public methods for variable pricer 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/pricer.h"
38 #include "scip/pub_message.h"
39 #include "scip/scip_pricer.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 variable pricer and includes it in SCIP
46 * To use the variable pricer for solving a problem, it first has to be activated with a call to SCIPactivatePricer().
47 * This should be done during the problem creation stage.
48 *
49 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
50 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
51 *
52 * @pre This method can be called if SCIP is in one of the following stages:
53 * - \ref SCIP_STAGE_INIT
54 * - \ref SCIP_STAGE_PROBLEM
55 *
56 * @note method has all pricer callbacks as arguments and is thus changed every time a new callback is added
57 * in future releases; consider using SCIPincludePricerBasic() and setter functions
58 * if you seek for a method which is less likely to change in future releases
59 */
SCIPincludePricer(SCIP * scip,const char * name,const char * desc,int priority,SCIP_Bool delay,SCIP_DECL_PRICERCOPY ((* pricercopy)),SCIP_DECL_PRICERFREE ((* pricerfree)),SCIP_DECL_PRICERINIT ((* pricerinit)),SCIP_DECL_PRICEREXIT ((* pricerexit)),SCIP_DECL_PRICERINITSOL ((* pricerinitsol)),SCIP_DECL_PRICEREXITSOL ((* pricerexitsol)),SCIP_DECL_PRICERREDCOST ((* pricerredcost)),SCIP_DECL_PRICERFARKAS ((* pricerfarkas)),SCIP_PRICERDATA * pricerdata)60 SCIP_RETCODE SCIPincludePricer(
61 SCIP* scip, /**< SCIP data structure */
62 const char* name, /**< name of variable pricer */
63 const char* desc, /**< description of variable pricer */
64 int priority, /**< priority of the variable pricer */
65 SCIP_Bool delay, /**< should the pricer be delayed until no other pricers or already existing
66 * problem variables with negative reduced costs are found?
67 * if this is set to FALSE it may happen that the pricer produces columns
68 * that already exist in the problem (which are also priced in by the
69 * default problem variable pricing in the same round) */
70 SCIP_DECL_PRICERCOPY ((*pricercopy)), /**< copy method of variable pricer or NULL if you don't want to copy your plugin into sub-SCIPs */
71 SCIP_DECL_PRICERFREE ((*pricerfree)), /**< destructor of variable pricer */
72 SCIP_DECL_PRICERINIT ((*pricerinit)), /**< initialize variable pricer */
73 SCIP_DECL_PRICEREXIT ((*pricerexit)), /**< deinitialize variable pricer */
74 SCIP_DECL_PRICERINITSOL((*pricerinitsol)),/**< solving process initialization method of variable pricer */
75 SCIP_DECL_PRICEREXITSOL((*pricerexitsol)),/**< solving process deinitialization method of variable pricer */
76 SCIP_DECL_PRICERREDCOST((*pricerredcost)),/**< reduced cost pricing method of variable pricer for feasible LPs */
77 SCIP_DECL_PRICERFARKAS((*pricerfarkas)), /**< Farkas pricing method of variable pricer for infeasible LPs */
78 SCIP_PRICERDATA* pricerdata /**< variable pricer data */
79 )
80 {
81 SCIP_PRICER* pricer;
82
83 SCIP_CALL( SCIPcheckStage(scip, "SCIPincludePricer", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
84
85 /* check whether pricer is already present */
86 if( SCIPfindPricer(scip, name) != NULL )
87 {
88 SCIPerrorMessage("pricer <%s> already included.\n", name);
89 return SCIP_INVALIDDATA;
90 }
91
92 SCIP_CALL( SCIPpricerCreate(&pricer, scip->set, scip->messagehdlr, scip->mem->setmem,
93 name, desc, priority, delay,
94 pricercopy,
95 pricerfree, pricerinit, pricerexit, pricerinitsol, pricerexitsol, pricerredcost, pricerfarkas, pricerdata) );
96 SCIP_CALL( SCIPsetIncludePricer(scip->set, pricer) );
97
98 return SCIP_OKAY;
99 }
100
101 /** creates a variable pricer and includes it in SCIP with all non-fundamental callbacks set to NULL;
102 * if needed, these can be added afterwards via setter functions SCIPsetPricerCopy(), SCIPsetPricerFree(),
103 * SCIPsetPricerInity(), SCIPsetPricerExit(), SCIPsetPricerInitsol(), SCIPsetPricerExitsol(),
104 * SCIPsetPricerFarkas();
105 *
106 * To use the variable pricer for solving a problem, it first has to be activated with a call to SCIPactivatePricer().
107 * This should be done during the problem creation stage.
108 *
109 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
110 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
111 *
112 * @pre This method can be called if SCIP is in one of the following stages:
113 * - \ref SCIP_STAGE_INIT
114 * - \ref SCIP_STAGE_PROBLEM
115 *
116 * @note if you want to set all callbacks with a single method call, consider using SCIPincludePricer() instead
117 */
SCIPincludePricerBasic(SCIP * scip,SCIP_PRICER ** pricerptr,const char * name,const char * desc,int priority,SCIP_Bool delay,SCIP_DECL_PRICERREDCOST ((* pricerredcost)),SCIP_DECL_PRICERFARKAS ((* pricerfarkas)),SCIP_PRICERDATA * pricerdata)118 SCIP_RETCODE SCIPincludePricerBasic(
119 SCIP* scip, /**< SCIP data structure */
120 SCIP_PRICER** pricerptr, /**< reference to a pricer, or NULL */
121 const char* name, /**< name of variable pricer */
122 const char* desc, /**< description of variable pricer */
123 int priority, /**< priority of the variable pricer */
124 SCIP_Bool delay, /**< should the pricer be delayed until no other pricers or already existing
125 * problem variables with negative reduced costs are found?
126 * if this is set to FALSE it may happen that the pricer produces columns
127 * that already exist in the problem (which are also priced in by the
128 * default problem variable pricing in the same round) */
129 SCIP_DECL_PRICERREDCOST((*pricerredcost)),/**< reduced cost pricing method of variable pricer for feasible LPs */
130 SCIP_DECL_PRICERFARKAS((*pricerfarkas)), /**< Farkas pricing method of variable pricer for infeasible LPs */
131 SCIP_PRICERDATA* pricerdata /**< variable pricer data */
132 )
133 {
134 SCIP_PRICER* pricer;
135
136 SCIP_CALL( SCIPcheckStage(scip, "SCIPincludePricerBasic", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
137
138 /* check whether pricer is already present */
139 if( SCIPfindPricer(scip, name) != NULL )
140 {
141 SCIPerrorMessage("pricer <%s> already included.\n", name);
142 return SCIP_INVALIDDATA;
143 }
144
145 SCIP_CALL( SCIPpricerCreate(&pricer, scip->set, scip->messagehdlr, scip->mem->setmem,
146 name, desc, priority, delay,
147 NULL,
148 NULL, NULL, NULL, NULL, NULL, pricerredcost, pricerfarkas, pricerdata) );
149 SCIP_CALL( SCIPsetIncludePricer(scip->set, pricer) );
150
151 if( pricerptr != NULL )
152 *pricerptr = pricer;
153
154 return SCIP_OKAY;
155 }
156
157 /** sets copy method of pricer
158 *
159 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
160 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
161 *
162 * @pre This method can be called if SCIP is in one of the following stages:
163 * - \ref SCIP_STAGE_INIT
164 * - \ref SCIP_STAGE_PROBLEM
165 */
SCIPsetPricerCopy(SCIP * scip,SCIP_PRICER * pricer,SCIP_DECL_PRICERCOPY ((* pricercopy)))166 SCIP_RETCODE SCIPsetPricerCopy(
167 SCIP* scip, /**< SCIP data structure */
168 SCIP_PRICER* pricer, /**< pricer */
169 SCIP_DECL_PRICERCOPY ((*pricercopy)) /**< copy method of pricer or NULL if you don't want to copy your plugin into sub-SCIPs */
170 )
171 {
172 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetPricerCopy", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
173
174 assert(pricer != NULL);
175
176 SCIPpricerSetCopy(pricer, pricercopy);
177
178 return SCIP_OKAY;
179 }
180
181 /** sets destructor method of pricer
182 *
183 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
184 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
185 *
186 * @pre This method can be called if SCIP is in one of the following stages:
187 * - \ref SCIP_STAGE_INIT
188 * - \ref SCIP_STAGE_PROBLEM
189 */
SCIPsetPricerFree(SCIP * scip,SCIP_PRICER * pricer,SCIP_DECL_PRICERFREE ((* pricerfree)))190 SCIP_RETCODE SCIPsetPricerFree(
191 SCIP* scip, /**< SCIP data structure */
192 SCIP_PRICER* pricer, /**< pricer */
193 SCIP_DECL_PRICERFREE ((*pricerfree)) /**< destructor of pricer */
194 )
195 {
196 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetPricerFree", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
197
198 assert(pricer != NULL);
199
200 SCIPpricerSetFree(pricer, pricerfree);
201
202 return SCIP_OKAY;
203 }
204
205 /** sets initialization method of pricer
206 *
207 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
208 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
209 *
210 * @pre This method can be called if SCIP is in one of the following stages:
211 * - \ref SCIP_STAGE_INIT
212 * - \ref SCIP_STAGE_PROBLEM
213 */
SCIPsetPricerInit(SCIP * scip,SCIP_PRICER * pricer,SCIP_DECL_PRICERINIT ((* pricerinit)))214 SCIP_RETCODE SCIPsetPricerInit(
215 SCIP* scip, /**< SCIP data structure */
216 SCIP_PRICER* pricer, /**< pricer */
217 SCIP_DECL_PRICERINIT ((*pricerinit)) /**< initialize pricer */
218 )
219 {
220 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetPricerInit", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
221
222 assert(pricer != NULL);
223
224 SCIPpricerSetInit(pricer, pricerinit);
225
226 return SCIP_OKAY;
227 }
228
229 /** sets deinitialization method of pricer
230 *
231 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
232 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
233 *
234 * @pre This method can be called if SCIP is in one of the following stages:
235 * - \ref SCIP_STAGE_INIT
236 * - \ref SCIP_STAGE_PROBLEM
237 */
SCIPsetPricerExit(SCIP * scip,SCIP_PRICER * pricer,SCIP_DECL_PRICEREXIT ((* pricerexit)))238 SCIP_RETCODE SCIPsetPricerExit(
239 SCIP* scip, /**< SCIP data structure */
240 SCIP_PRICER* pricer, /**< pricer */
241 SCIP_DECL_PRICEREXIT ((*pricerexit)) /**< deinitialize pricer */
242 )
243 {
244 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetPricerExit", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
245
246 assert(pricer != NULL);
247
248 SCIPpricerSetExit(pricer, pricerexit);
249
250 return SCIP_OKAY;
251 }
252
253 /** sets solving process initialization method of pricer
254 *
255 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
256 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
257 *
258 * @pre This method can be called if SCIP is in one of the following stages:
259 * - \ref SCIP_STAGE_INIT
260 * - \ref SCIP_STAGE_PROBLEM
261 */
SCIPsetPricerInitsol(SCIP * scip,SCIP_PRICER * pricer,SCIP_DECL_PRICERINITSOL ((* pricerinitsol)))262 SCIP_RETCODE SCIPsetPricerInitsol(
263 SCIP* scip, /**< SCIP data structure */
264 SCIP_PRICER* pricer, /**< pricer */
265 SCIP_DECL_PRICERINITSOL ((*pricerinitsol))/**< solving process initialization method of pricer */
266 )
267 {
268 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetPricerInitsol", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
269
270 assert(pricer != NULL);
271
272 SCIPpricerSetInitsol(pricer, pricerinitsol);
273
274 return SCIP_OKAY;
275 }
276
277 /** sets solving process deinitialization method of pricer
278 *
279 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
280 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
281 *
282 * @pre This method can be called if SCIP is in one of the following stages:
283 * - \ref SCIP_STAGE_INIT
284 * - \ref SCIP_STAGE_PROBLEM
285 */
SCIPsetPricerExitsol(SCIP * scip,SCIP_PRICER * pricer,SCIP_DECL_PRICEREXITSOL ((* pricerexitsol)))286 SCIP_RETCODE SCIPsetPricerExitsol(
287 SCIP* scip, /**< SCIP data structure */
288 SCIP_PRICER* pricer, /**< pricer */
289 SCIP_DECL_PRICEREXITSOL((*pricerexitsol)) /**< solving process deinitialization method of pricer */
290 )
291 {
292 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetPricerExitsol", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
293
294 assert(pricer != NULL);
295
296 SCIPpricerSetExitsol(pricer, pricerexitsol);
297
298 return SCIP_OKAY;
299 }
300
301 /** returns the variable pricer of the given name, or NULL if not existing */
SCIPfindPricer(SCIP * scip,const char * name)302 SCIP_PRICER* SCIPfindPricer(
303 SCIP* scip, /**< SCIP data structure */
304 const char* name /**< name of variable pricer */
305 )
306 {
307 assert(scip != NULL);
308 assert(scip->set != NULL);
309 assert(name != NULL);
310
311 return SCIPsetFindPricer(scip->set, name);
312 }
313
314 /** returns the array of currently available variable pricers; active pricers are in the first slots of the array */
SCIPgetPricers(SCIP * scip)315 SCIP_PRICER** SCIPgetPricers(
316 SCIP* scip /**< SCIP data structure */
317 )
318 {
319 assert(scip != NULL);
320 assert(scip->set != NULL);
321
322 SCIPsetSortPricers(scip->set);
323
324 return scip->set->pricers;
325 }
326
327 /** returns the number of currently available variable pricers */
SCIPgetNPricers(SCIP * scip)328 int SCIPgetNPricers(
329 SCIP* scip /**< SCIP data structure */
330 )
331 {
332 assert(scip != NULL);
333 assert(scip->set != NULL);
334
335 return scip->set->npricers;
336 }
337
338 /** returns the number of currently active variable pricers, that are used in the LP solving loop */
SCIPgetNActivePricers(SCIP * scip)339 int SCIPgetNActivePricers(
340 SCIP* scip /**< SCIP data structure */
341 )
342 {
343 assert(scip != NULL);
344 assert(scip->set != NULL);
345
346 return scip->set->nactivepricers;
347 }
348
349 /** sets the priority priority of a variable pricer */
SCIPsetPricerPriority(SCIP * scip,SCIP_PRICER * pricer,int priority)350 SCIP_RETCODE SCIPsetPricerPriority(
351 SCIP* scip, /**< SCIP data structure */
352 SCIP_PRICER* pricer, /**< variable pricer */
353 int priority /**< new priority of the variable pricer */
354 )
355 {
356 assert(scip != NULL);
357 assert(scip->set != NULL);
358
359 SCIPpricerSetPriority(pricer, scip->set, priority);
360
361 return SCIP_OKAY;
362 }
363
364 /** activates pricer to be used for the current problem
365 * This method should be called during the problem creation stage for all pricers that are necessary to solve
366 * the problem model.
367 * The pricers are automatically deactivated when the problem is freed.
368 *
369 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
370 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
371 *
372 * @pre This method can be called if SCIP is in one of the following stages:
373 * - \ref SCIP_STAGE_PROBLEM
374 */
SCIPactivatePricer(SCIP * scip,SCIP_PRICER * pricer)375 SCIP_RETCODE SCIPactivatePricer(
376 SCIP* scip, /**< SCIP data structure */
377 SCIP_PRICER* pricer /**< variable pricer */
378 )
379 {
380 SCIP_CALL( SCIPcheckStage(scip, "SCIPactivatePricer", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
381
382 SCIP_CALL( SCIPpricerActivate(pricer, scip->set) );
383
384 return SCIP_OKAY;
385 }
386
387 /** deactivates pricer
388 *
389 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
390 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
391 *
392 * @pre This method can be called if SCIP is in one of the following stages:
393 * - \ref SCIP_STAGE_PROBLEM
394 * - \ref SCIP_STAGE_SOLVING
395 * - \ref SCIP_STAGE_EXITSOLVE
396 */
SCIPdeactivatePricer(SCIP * scip,SCIP_PRICER * pricer)397 SCIP_RETCODE SCIPdeactivatePricer(
398 SCIP* scip, /**< SCIP data structure */
399 SCIP_PRICER* pricer /**< variable pricer */
400 )
401 {
402 SCIP_CALL( SCIPcheckStage(scip, "SCIPdeactivatePricer", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE) );
403
404 SCIP_CALL( SCIPpricerDeactivate(pricer, scip->set) );
405
406 return SCIP_OKAY;
407 }
408