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   pricer.c
17  * @ingroup OTHER_CFILES
18  * @brief  methods for variable pricers
19  * @author Tobias Achterberg
20  * @author Timo Berthold
21  */
22 
23 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
24 
25 #include <assert.h>
26 #include <string.h>
27 
28 #include "scip/def.h"
29 #include "scip/set.h"
30 #include "scip/clock.h"
31 #include "scip/paramset.h"
32 #include "scip/lp.h"
33 #include "scip/prob.h"
34 #include "scip/pricestore.h"
35 #include "scip/scip.h"
36 #include "scip/pricer.h"
37 #include "scip/pub_message.h"
38 #include "scip/pub_misc.h"
39 
40 #include "scip/struct_pricer.h"
41 
42 
43 
44 /** compares two pricers w. r. to their activity and their priority */
SCIP_DECL_SORTPTRCOMP(SCIPpricerComp)45 SCIP_DECL_SORTPTRCOMP(SCIPpricerComp)
46 {  /*lint --e{715}*/
47    if( ((SCIP_PRICER*)elem1)->active != ((SCIP_PRICER*)elem2)->active )
48       return ((SCIP_PRICER*)elem1)->active ? -1 : +1;
49    else
50       return ((SCIP_PRICER*)elem2)->priority - ((SCIP_PRICER*)elem1)->priority;
51 }
52 
53 /** comparison method for sorting pricers w.r.t. to their name */
SCIP_DECL_SORTPTRCOMP(SCIPpricerCompName)54 SCIP_DECL_SORTPTRCOMP(SCIPpricerCompName)
55 {
56    if( ((SCIP_PRICER*)elem1)->active != ((SCIP_PRICER*)elem2)->active )
57       return ((SCIP_PRICER*)elem1)->active ? -1 : +1;
58    else
59       return strcmp(SCIPpricerGetName((SCIP_PRICER*)elem1), SCIPpricerGetName((SCIP_PRICER*)elem2));
60 }
61 
62 /** method to call, when the priority of a pricer was changed */
63 static
SCIP_DECL_PARAMCHGD(paramChgdPricerPriority)64 SCIP_DECL_PARAMCHGD(paramChgdPricerPriority)
65 {  /*lint --e{715}*/
66    SCIP_PARAMDATA* paramdata;
67 
68    paramdata = SCIPparamGetData(param);
69    assert(paramdata != NULL);
70 
71    /* use SCIPsetPricerPriority() to mark the pricers unsorted */
72    SCIP_CALL( SCIPsetPricerPriority(scip, (SCIP_PRICER*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/
73 
74    return SCIP_OKAY;
75 }
76 
77 /** copies the given pricer to a new scip */
SCIPpricerCopyInclude(SCIP_PRICER * pricer,SCIP_SET * set,SCIP_Bool * valid)78 SCIP_RETCODE SCIPpricerCopyInclude(
79    SCIP_PRICER*          pricer,             /**< pricer */
80    SCIP_SET*             set,                /**< SCIP_SET of SCIP to copy to */
81    SCIP_Bool*            valid               /**< was the copying process valid? */
82    )
83 {
84    assert(pricer != NULL);
85    assert(set != NULL);
86    assert(valid != NULL);
87    assert(set->scip != NULL);
88 
89    if( pricer->pricercopy != NULL )
90    {
91       SCIPsetDebugMsg(set, "including pricer %s in subscip %p\n", SCIPpricerGetName(pricer), (void*)set->scip);
92       SCIP_CALL( pricer->pricercopy(set->scip, pricer, valid) );
93    }
94    return SCIP_OKAY;
95 }
96 
97 /** internal method creating a variable pricer */
98 static
doPricerCreate(SCIP_PRICER ** pricer,SCIP_SET * set,SCIP_MESSAGEHDLR * messagehdlr,BMS_BLKMEM * blkmem,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)99 SCIP_RETCODE doPricerCreate(
100    SCIP_PRICER**         pricer,             /**< pointer to variable pricer data structure */
101    SCIP_SET*             set,                /**< global SCIP settings */
102    SCIP_MESSAGEHDLR*     messagehdlr,        /**< message handler */
103    BMS_BLKMEM*           blkmem,             /**< block memory for parameter settings */
104    const char*           name,               /**< name of variable pricer */
105    const char*           desc,               /**< description of variable pricer */
106    int                   priority,           /**< priority of the variable pricer */
107    SCIP_Bool             delay,              /**< should the pricer be delayed until no other pricers or already existing
108                                               *   problem variables with negative reduced costs are found */
109    SCIP_DECL_PRICERCOPY  ((*pricercopy)),    /**< copy method of pricer or NULL if you don't want to copy your plugin into sub-SCIPs */
110    SCIP_DECL_PRICERFREE  ((*pricerfree)),    /**< destructor of variable pricer */
111    SCIP_DECL_PRICERINIT  ((*pricerinit)),    /**< initialize variable pricer */
112    SCIP_DECL_PRICEREXIT  ((*pricerexit)),    /**< deinitialize variable pricer */
113    SCIP_DECL_PRICERINITSOL((*pricerinitsol)),/**< solving process initialization method of variable pricer */
114    SCIP_DECL_PRICEREXITSOL((*pricerexitsol)),/**< solving process deinitialization method of variable pricer */
115    SCIP_DECL_PRICERREDCOST((*pricerredcost)),/**< reduced cost pricing method of variable pricer for feasible LPs */
116    SCIP_DECL_PRICERFARKAS((*pricerfarkas)),  /**< Farkas pricing method of variable pricer for infeasible LPs */
117    SCIP_PRICERDATA*      pricerdata          /**< variable pricer data */
118    )
119 {
120    char paramname[SCIP_MAXSTRLEN];
121    char paramdesc[SCIP_MAXSTRLEN];
122 
123    assert(pricer != NULL);
124    assert(name != NULL);
125    assert(desc != NULL);
126    assert(pricerredcost != NULL);
127 
128    SCIP_ALLOC( BMSallocMemory(pricer) );
129    BMSclearMemory(*pricer);
130 
131    SCIP_ALLOC( BMSduplicateMemoryArray(&(*pricer)->name, name, strlen(name)+1) );
132    SCIP_ALLOC( BMSduplicateMemoryArray(&(*pricer)->desc, desc, strlen(desc)+1) );
133    (*pricer)->priority = priority;
134    (*pricer)->pricercopy = pricercopy;
135    (*pricer)->pricerfree = pricerfree;
136    (*pricer)->pricerinit = pricerinit;
137    (*pricer)->pricerexit = pricerexit;
138    (*pricer)->pricerinitsol = pricerinitsol;
139    (*pricer)->pricerexitsol = pricerexitsol;
140    (*pricer)->pricerredcost = pricerredcost;
141    (*pricer)->pricerfarkas = pricerfarkas;
142    (*pricer)->pricerdata = pricerdata;
143    SCIP_CALL( SCIPclockCreate(&(*pricer)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
144    SCIP_CALL( SCIPclockCreate(&(*pricer)->pricerclock, SCIP_CLOCKTYPE_DEFAULT) );
145    (*pricer)->ncalls = 0;
146    (*pricer)->nvarsfound = 0;
147    (*pricer)->delay = delay;
148    (*pricer)->active = FALSE;
149    (*pricer)->initialized = FALSE;
150 
151    /* add parameters */
152    (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "pricers/%s/priority", name);
153    (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of pricer <%s>", name);
154    SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
155                   &(*pricer)->priority, FALSE, priority, INT_MIN/4, INT_MAX/4,
156                   paramChgdPricerPriority, (SCIP_PARAMDATA*)(*pricer)) ); /*lint !e740*/
157 
158    return SCIP_OKAY;
159 }
160 
161 /** creates a variable pricer
162  *  To use the variable pricer for solving a problem, it first has to be activated with a call to SCIPactivatePricer().
163  */
SCIPpricerCreate(SCIP_PRICER ** pricer,SCIP_SET * set,SCIP_MESSAGEHDLR * messagehdlr,BMS_BLKMEM * blkmem,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)164 SCIP_RETCODE SCIPpricerCreate(
165    SCIP_PRICER**         pricer,             /**< pointer to variable pricer data structure */
166    SCIP_SET*             set,                /**< global SCIP settings */
167    SCIP_MESSAGEHDLR*     messagehdlr,        /**< message handler */
168    BMS_BLKMEM*           blkmem,             /**< block memory for parameter settings */
169    const char*           name,               /**< name of variable pricer */
170    const char*           desc,               /**< description of variable pricer */
171    int                   priority,           /**< priority of the variable pricer */
172    SCIP_Bool             delay,              /**< should the pricer be delayed until no other pricers or already existing
173                                               *   problem variables with negative reduced costs are found */
174    SCIP_DECL_PRICERCOPY  ((*pricercopy)),    /**< copy method of pricer or NULL if you don't want to copy your plugin into sub-SCIPs */
175    SCIP_DECL_PRICERFREE  ((*pricerfree)),    /**< destructor of variable pricer */
176    SCIP_DECL_PRICERINIT  ((*pricerinit)),    /**< initialize variable pricer */
177    SCIP_DECL_PRICEREXIT  ((*pricerexit)),    /**< deinitialize variable pricer */
178    SCIP_DECL_PRICERINITSOL((*pricerinitsol)),/**< solving process initialization method of variable pricer */
179    SCIP_DECL_PRICEREXITSOL((*pricerexitsol)),/**< solving process deinitialization method of variable pricer */
180    SCIP_DECL_PRICERREDCOST((*pricerredcost)),/**< reduced cost pricing method of variable pricer for feasible LPs */
181    SCIP_DECL_PRICERFARKAS((*pricerfarkas)),  /**< Farkas pricing method of variable pricer for infeasible LPs */
182    SCIP_PRICERDATA*      pricerdata          /**< variable pricer data */
183    )
184 {
185    assert(pricer != NULL);
186    assert(name != NULL);
187    assert(desc != NULL);
188    assert(pricerredcost != NULL);
189 
190    SCIP_CALL_FINALLY( doPricerCreate(pricer, set, messagehdlr, blkmem, name, desc, priority, delay, pricercopy,
191       pricerfree, pricerinit, pricerexit, pricerinitsol, pricerexitsol, pricerredcost, pricerfarkas, pricerdata),
192       (void) SCIPpricerFree(pricer ,set) );
193 
194    return SCIP_OKAY;
195 }
196 
197 /** calls destructor and frees memory of variable pricer */
SCIPpricerFree(SCIP_PRICER ** pricer,SCIP_SET * set)198 SCIP_RETCODE SCIPpricerFree(
199    SCIP_PRICER**         pricer,             /**< pointer to variable pricer data structure */
200    SCIP_SET*             set                 /**< global SCIP settings */
201    )
202 {
203    assert(pricer != NULL);
204    if( *pricer == NULL )
205       return SCIP_OKAY;
206    assert(!(*pricer)->initialized);
207    assert(set != NULL);
208 
209    /* call destructor of variable pricer */
210    if( (*pricer)->pricerfree != NULL )
211    {
212       SCIP_CALL( (*pricer)->pricerfree(set->scip, *pricer) );
213    }
214 
215    SCIPclockFree(&(*pricer)->pricerclock);
216    SCIPclockFree(&(*pricer)->setuptime);
217    BMSfreeMemoryArrayNull(&(*pricer)->name);
218    BMSfreeMemoryArrayNull(&(*pricer)->desc);
219    BMSfreeMemory(pricer);
220 
221    return SCIP_OKAY;
222 }
223 
224 /** initializes variable pricer */
SCIPpricerInit(SCIP_PRICER * pricer,SCIP_SET * set)225 SCIP_RETCODE SCIPpricerInit(
226    SCIP_PRICER*          pricer,             /**< variable pricer */
227    SCIP_SET*             set                 /**< global SCIP settings */
228    )
229 {
230    assert(pricer != NULL);
231    assert(pricer->active);
232    assert(set != NULL);
233 
234    if( pricer->initialized )
235    {
236       SCIPerrorMessage("variable pricer <%s> already initialized\n", pricer->name);
237       return SCIP_INVALIDCALL;
238    }
239 
240    if( set->misc_resetstat )
241    {
242       SCIPclockReset(pricer->setuptime);
243       SCIPclockReset(pricer->pricerclock);
244 
245       pricer->ncalls = 0;
246       pricer->nvarsfound = 0;
247    }
248 
249    if( pricer->pricerinit != NULL )
250    {
251       /* start timing */
252       SCIPclockStart(pricer->setuptime, set);
253 
254       SCIP_CALL( pricer->pricerinit(set->scip, pricer) );
255 
256       /* stop timing */
257       SCIPclockStop(pricer->setuptime, set);
258    }
259    pricer->initialized = TRUE;
260 
261    return SCIP_OKAY;
262 }
263 
264 /** calls exit method of variable pricer */
SCIPpricerExit(SCIP_PRICER * pricer,SCIP_SET * set)265 SCIP_RETCODE SCIPpricerExit(
266    SCIP_PRICER*          pricer,             /**< variable pricer */
267    SCIP_SET*             set                 /**< global SCIP settings */
268    )
269 {
270    assert(pricer != NULL);
271    assert(pricer->active);
272    assert(set != NULL);
273 
274    if( !pricer->initialized )
275    {
276       SCIPerrorMessage("variable pricer <%s> not initialized\n", pricer->name);
277       return SCIP_INVALIDCALL;
278    }
279 
280    if( pricer->pricerexit != NULL )
281    {
282       /* start timing */
283       SCIPclockStart(pricer->setuptime, set);
284 
285       SCIP_CALL( pricer->pricerexit(set->scip, pricer) );
286 
287       /* stop timing */
288       SCIPclockStop(pricer->setuptime, set);
289    }
290    pricer->initialized = FALSE;
291 
292    return SCIP_OKAY;
293 }
294 
295 /** informs variable pricer that the branch and bound process is being started */
SCIPpricerInitsol(SCIP_PRICER * pricer,SCIP_SET * set)296 SCIP_RETCODE SCIPpricerInitsol(
297    SCIP_PRICER*          pricer,             /**< variable pricer */
298    SCIP_SET*             set                 /**< global SCIP settings */
299    )
300 {
301    assert(pricer != NULL);
302    assert(set != NULL);
303 
304    /* call solving process initialization method of variable pricer */
305    if( pricer->pricerinitsol != NULL )
306    {
307       /* start timing */
308       SCIPclockStart(pricer->setuptime, set);
309 
310       SCIP_CALL( pricer->pricerinitsol(set->scip, pricer) );
311 
312       /* stop timing */
313       SCIPclockStop(pricer->setuptime, set);
314    }
315 
316    return SCIP_OKAY;
317 }
318 
319 /** informs variable pricer that the branch and bound process data is being freed */
SCIPpricerExitsol(SCIP_PRICER * pricer,SCIP_SET * set)320 SCIP_RETCODE SCIPpricerExitsol(
321    SCIP_PRICER*          pricer,             /**< variable pricer */
322    SCIP_SET*             set                 /**< global SCIP settings */
323    )
324 {
325    assert(pricer != NULL);
326    assert(set != NULL);
327 
328    /* call solving process deinitialization method of variable pricer */
329    if( pricer->pricerexitsol != NULL )
330    {
331       /* start timing */
332       SCIPclockStart(pricer->setuptime, set);
333 
334       SCIP_CALL( pricer->pricerexitsol(set->scip, pricer) );
335 
336       /* stop timing */
337       SCIPclockStop(pricer->setuptime, set);
338    }
339 
340    return SCIP_OKAY;
341 }
342 
343 /** activates pricer such that it is called in LP solving loop */
SCIPpricerActivate(SCIP_PRICER * pricer,SCIP_SET * set)344 SCIP_RETCODE SCIPpricerActivate(
345    SCIP_PRICER*          pricer,             /**< variable pricer */
346    SCIP_SET*             set                 /**< global SCIP settings */
347    )
348 {
349    assert(pricer != NULL);
350    assert(set != NULL);
351    assert(set->stage == SCIP_STAGE_PROBLEM);
352 
353    if( !pricer->active )
354    {
355       pricer->active = TRUE;
356       set->nactivepricers++;
357       set->pricerssorted = FALSE;
358    }
359 
360    return SCIP_OKAY;
361 }
362 
363 /** deactivates pricer such that it is no longer called in LP solving loop */
SCIPpricerDeactivate(SCIP_PRICER * pricer,SCIP_SET * set)364 SCIP_RETCODE SCIPpricerDeactivate(
365    SCIP_PRICER*          pricer,             /**< variable pricer */
366    SCIP_SET*             set                 /**< global SCIP settings */
367    )
368 {
369    assert(pricer != NULL);
370    assert(set != NULL);
371 
372    if( pricer->active )
373    {
374       pricer->active = FALSE;
375       set->nactivepricers--;
376       set->pricerssorted = FALSE;
377    }
378 
379    return SCIP_OKAY;
380 }
381 
382 /** calls reduced cost pricing method of variable pricer */
SCIPpricerRedcost(SCIP_PRICER * pricer,SCIP_SET * set,SCIP_PROB * prob,SCIP_Real * lowerbound,SCIP_Bool * stopearly,SCIP_RESULT * result)383 SCIP_RETCODE SCIPpricerRedcost(
384    SCIP_PRICER*          pricer,             /**< variable pricer */
385    SCIP_SET*             set,                /**< global SCIP settings */
386    SCIP_PROB*            prob,               /**< transformed problem */
387    SCIP_Real*            lowerbound,         /**< local lower bound computed by the pricer */
388    SCIP_Bool*            stopearly,          /**< should pricing be stopped, although new variables were added? */
389    SCIP_RESULT*          result              /**< result of the pricing process */
390    )
391 {
392    int oldnvars;
393 
394    assert(pricer != NULL);
395    assert(pricer->active);
396    assert(pricer->pricerredcost != NULL);
397    assert(set != NULL);
398    assert(prob != NULL);
399    assert(lowerbound != NULL);
400    assert(result != NULL);
401 
402    SCIPsetDebugMsg(set, "executing reduced cost pricing of variable pricer <%s>\n", pricer->name);
403 
404    oldnvars = prob->nvars;
405 
406    /* start timing */
407    SCIPclockStart(pricer->pricerclock, set);
408 
409    /* call external method */
410    SCIP_CALL( pricer->pricerredcost(set->scip, pricer, lowerbound, stopearly, result) );
411 
412    /* stop timing */
413    SCIPclockStop(pricer->pricerclock, set);
414 
415    /* evaluate result */
416    pricer->ncalls++;
417    pricer->nvarsfound += prob->nvars - oldnvars;
418 
419    return SCIP_OKAY;
420 }
421 
422 /** calls Farkas pricing method of variable pricer */
SCIPpricerFarkas(SCIP_PRICER * pricer,SCIP_SET * set,SCIP_PROB * prob,SCIP_RESULT * result)423 SCIP_RETCODE SCIPpricerFarkas(
424    SCIP_PRICER*          pricer,             /**< variable pricer */
425    SCIP_SET*             set,                /**< global SCIP settings */
426    SCIP_PROB*            prob,               /**< transformed problem */
427    SCIP_RESULT*          result              /**< result of the pricing process */
428    )
429 {
430    int oldnvars;
431 
432    assert(pricer != NULL);
433    assert(pricer->active);
434    assert(set != NULL);
435    assert(prob != NULL);
436 
437    /* check, if pricer implemented a Farkas pricing algorithm */
438    if( pricer->pricerfarkas == NULL )
439       return SCIP_OKAY;
440 
441    SCIPsetDebugMsg(set, "executing Farkas pricing of variable pricer <%s>\n", pricer->name);
442 
443    oldnvars = prob->nvars;
444 
445    /* start timing */
446    SCIPclockStart(pricer->pricerclock, set);
447 
448    /* call external method */
449    SCIP_CALL( pricer->pricerfarkas(set->scip, pricer, result) );
450 
451    /* stop timing */
452    SCIPclockStop(pricer->pricerclock, set);
453 
454    /* evaluate result */
455    pricer->ncalls++;
456    pricer->nvarsfound += prob->nvars - oldnvars;
457 
458    return SCIP_OKAY;
459 }
460 
461 /** depending on the LP's solution status, calls reduced cost or Farkas pricing method of variable pricer */
SCIPpricerExec(SCIP_PRICER * pricer,SCIP_SET * set,SCIP_PROB * prob,SCIP_LP * lp,SCIP_PRICESTORE * pricestore,SCIP_Real * lowerbound,SCIP_Bool * stopearly,SCIP_RESULT * result)462 SCIP_RETCODE SCIPpricerExec(
463    SCIP_PRICER*          pricer,             /**< variable pricer */
464    SCIP_SET*             set,                /**< global SCIP settings */
465    SCIP_PROB*            prob,               /**< transformed problem */
466    SCIP_LP*              lp,                 /**< LP data */
467    SCIP_PRICESTORE*      pricestore,         /**< pricing storage */
468    SCIP_Real*            lowerbound,         /**< local lower bound computed by the pricer */
469    SCIP_Bool*            stopearly,          /**< should pricing be stopped, although new variables were added? */
470    SCIP_RESULT*          result              /**< result of the pricing process */
471    )
472 {
473    assert(pricer != NULL);
474    assert(lowerbound != NULL);
475    assert(stopearly != NULL);
476    assert(result != NULL);
477 
478    /* set lowerbound, stopearly, and result pointer */
479    *lowerbound = - SCIPsetInfinity(set);
480    *stopearly = FALSE;
481    *result = SCIP_SUCCESS;
482 
483    /* check if pricer should be delayed */
484    if( pricer->delay && SCIPpricestoreGetNVars(pricestore) > 0 )
485       return SCIP_OKAY;
486 
487    if( SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_INFEASIBLE )
488    {
489       SCIP_CALL( SCIPpricerFarkas(pricer, set, prob, result) );
490    }
491    else
492    {
493       *result = SCIP_DIDNOTRUN;
494       SCIP_CALL( SCIPpricerRedcost(pricer, set, prob, lowerbound, stopearly, result) );
495    }
496 
497    return SCIP_OKAY;
498 }
499 
500 /** gets user data of variable pricer */
SCIPpricerGetData(SCIP_PRICER * pricer)501 SCIP_PRICERDATA* SCIPpricerGetData(
502    SCIP_PRICER*          pricer              /**< variable pricer */
503    )
504 {
505    assert(pricer != NULL);
506 
507    return pricer->pricerdata;
508 }
509 
510 /** sets user data of variable pricer; user has to free old data in advance! */
SCIPpricerSetData(SCIP_PRICER * pricer,SCIP_PRICERDATA * pricerdata)511 void SCIPpricerSetData(
512    SCIP_PRICER*          pricer,             /**< variable pricer */
513    SCIP_PRICERDATA*      pricerdata          /**< new variable pricer user data */
514    )
515 {
516    assert(pricer != NULL);
517 
518    pricer->pricerdata = pricerdata;
519 }
520 
521 /** sets copy callback of pricer */
SCIPpricerSetCopy(SCIP_PRICER * pricer,SCIP_DECL_PRICERCOPY ((* pricercopy)))522 void SCIPpricerSetCopy(
523    SCIP_PRICER*          pricer,             /**< variable pricer */
524    SCIP_DECL_PRICERCOPY  ((*pricercopy))     /**< copy callback of pricer */
525    )
526 {
527    assert(pricer != NULL);
528 
529    pricer->pricercopy = pricercopy;
530 }
531 
532 /** sets destructor callback of pricer */
SCIPpricerSetFree(SCIP_PRICER * pricer,SCIP_DECL_PRICERFREE ((* pricerfree)))533 void SCIPpricerSetFree(
534    SCIP_PRICER*          pricer,             /**< pricer */
535    SCIP_DECL_PRICERFREE  ((*pricerfree))     /**< destructor of pricer */
536    )
537 {
538    assert(pricer != NULL);
539 
540    pricer->pricerfree = pricerfree;
541 }
542 
543 /** sets initialization callback of pricer */
SCIPpricerSetInit(SCIP_PRICER * pricer,SCIP_DECL_PRICERINIT ((* pricerinit)))544 void SCIPpricerSetInit(
545    SCIP_PRICER*          pricer,             /**< pricer */
546    SCIP_DECL_PRICERINIT ((*pricerinit))     /**< initialize pricer */
547    )
548 {
549    assert(pricer != NULL);
550 
551    pricer->pricerinit = pricerinit;
552 }
553 
554 /** sets deinitialization callback of pricer */
SCIPpricerSetExit(SCIP_PRICER * pricer,SCIP_DECL_PRICEREXIT ((* pricerexit)))555 void SCIPpricerSetExit(
556    SCIP_PRICER*          pricer,             /**< pricer */
557    SCIP_DECL_PRICEREXIT ((*pricerexit))     /**< deinitialize pricer */
558    )
559 {
560    assert(pricer != NULL);
561 
562    pricer->pricerexit = pricerexit;
563 }
564 
565 /** sets solving process initialization callback of pricer */
SCIPpricerSetInitsol(SCIP_PRICER * pricer,SCIP_DECL_PRICERINITSOL ((* pricerinitsol)))566 void SCIPpricerSetInitsol(
567    SCIP_PRICER*          pricer,             /**< pricer */
568    SCIP_DECL_PRICERINITSOL ((*pricerinitsol))/**< solving process initialization callback of pricer */
569    )
570 {
571    assert(pricer != NULL);
572 
573    pricer->pricerinitsol = pricerinitsol;
574 }
575 
576 /** sets solving process deinitialization callback of pricer */
SCIPpricerSetExitsol(SCIP_PRICER * pricer,SCIP_DECL_PRICEREXITSOL ((* pricerexitsol)))577 void SCIPpricerSetExitsol(
578    SCIP_PRICER*          pricer,             /**< pricer */
579    SCIP_DECL_PRICEREXITSOL ((*pricerexitsol))/**< solving process deinitialization callback of pricer */
580    )
581 {
582    assert(pricer != NULL);
583 
584    pricer->pricerexitsol = pricerexitsol;
585 }
586 
587 /** gets name of variable pricer */
SCIPpricerGetName(SCIP_PRICER * pricer)588 const char* SCIPpricerGetName(
589    SCIP_PRICER*          pricer              /**< variable pricer */
590    )
591 {
592    assert(pricer != NULL);
593 
594    return pricer->name;
595 }
596 
597 /** gets description of variable pricer */
SCIPpricerGetDesc(SCIP_PRICER * pricer)598 const char* SCIPpricerGetDesc(
599    SCIP_PRICER*          pricer              /**< variable pricer */
600    )
601 {
602    assert(pricer != NULL);
603 
604    return pricer->desc;
605 }
606 
607 /** gets priority of variable pricer */
SCIPpricerGetPriority(SCIP_PRICER * pricer)608 int SCIPpricerGetPriority(
609    SCIP_PRICER*          pricer              /**< variable pricer */
610    )
611 {
612    assert(pricer != NULL);
613 
614    return pricer->priority;
615 }
616 
617 /** sets priority of variable pricer */
SCIPpricerSetPriority(SCIP_PRICER * pricer,SCIP_SET * set,int priority)618 void SCIPpricerSetPriority(
619    SCIP_PRICER*          pricer,             /**< variable pricer */
620    SCIP_SET*             set,                /**< global SCIP settings */
621    int                   priority            /**< new priority of the variable pricer */
622    )
623 {
624    assert(pricer != NULL);
625    assert(set != NULL);
626 
627    pricer->priority = priority;
628    set->pricerssorted = FALSE;
629 }
630 
631 /** gets the number of times, the pricer was called and tried to find a variable with negative reduced costs */
SCIPpricerGetNCalls(SCIP_PRICER * pricer)632 int SCIPpricerGetNCalls(
633    SCIP_PRICER*          pricer              /**< variable pricer */
634    )
635 {
636    assert(pricer != NULL);
637 
638    return pricer->ncalls;
639 }
640 
641 /** gets the number of variables with negative reduced costs found by this pricer */
SCIPpricerGetNVarsFound(SCIP_PRICER * pricer)642 int SCIPpricerGetNVarsFound(
643    SCIP_PRICER*          pricer              /**< variable pricer */
644    )
645 {
646    assert(pricer != NULL);
647 
648    return pricer->nvarsfound;
649 }
650 
651 /** gets time in seconds used in this pricer for setting up for next stages */
SCIPpricerGetSetupTime(SCIP_PRICER * pricer)652 SCIP_Real SCIPpricerGetSetupTime(
653    SCIP_PRICER*          pricer              /**< variable pricer */
654    )
655 {
656    assert(pricer != NULL);
657 
658    return SCIPclockGetTime(pricer->setuptime);
659 }
660 
661 /** gets time in seconds used in this pricer */
SCIPpricerGetTime(SCIP_PRICER * pricer)662 SCIP_Real SCIPpricerGetTime(
663    SCIP_PRICER*          pricer              /**< variable pricer */
664    )
665 {
666    assert(pricer != NULL);
667 
668    return SCIPclockGetTime(pricer->pricerclock);
669 }
670 
671 /** enables or disables all clocks of \p pricer, depending on the value of the flag */
SCIPpricerEnableOrDisableClocks(SCIP_PRICER * pricer,SCIP_Bool enable)672 void SCIPpricerEnableOrDisableClocks(
673    SCIP_PRICER*          pricer,             /**< the pricer for which all clocks should be enabled or disabled */
674    SCIP_Bool             enable              /**< should the clocks of the pricer be enabled? */
675    )
676 {
677    assert(pricer != NULL);
678 
679    SCIPclockEnableOrDisable(pricer->setuptime, enable);
680    SCIPclockEnableOrDisable(pricer->pricerclock, enable);
681 }
682 
683 /** returns whether the given pricer is in use in the current problem */
SCIPpricerIsActive(SCIP_PRICER * pricer)684 SCIP_Bool SCIPpricerIsActive(
685    SCIP_PRICER*          pricer              /**< variable pricer */
686    )
687 {
688    assert(pricer != NULL);
689 
690    return pricer->active;
691 }
692 
693 /** returns whether the pricer should be delayed until no other pricer finds a new variable */
SCIPpricerIsDelayed(SCIP_PRICER * pricer)694 SCIP_Bool SCIPpricerIsDelayed(
695    SCIP_PRICER*          pricer              /**< variable pricer */
696    )
697 {
698    assert(pricer != NULL);
699 
700    return pricer->delay;
701 }
702 
703 /** is variable pricer initialized? */
SCIPpricerIsInitialized(SCIP_PRICER * pricer)704 SCIP_Bool SCIPpricerIsInitialized(
705    SCIP_PRICER*          pricer              /**< variable pricer */
706    )
707 {
708    assert(pricer != NULL);
709 
710    return pricer->initialized;
711 }
712 
713 
714