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