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