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   cutsel.c
26   	 * @ingroup OTHER_CFILES
27   	 * @brief  methods for cut selectors
28   	 * @author Felipe Serrano
29   	 * @author Mark Turner
30   	 */
31   	
32   	/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
33   	
34   	#include <assert.h>
35   	
36   	#include "scip/set.h"
37   	#include "scip/clock.h"
38   	#include "scip/paramset.h"
39   	#include "scip/scip.h"
40   	#include "scip/cutsel.h"
41   	
42   	#include "scip/struct_cutsel.h"
43   	
44   	
45   	/** method to call, when the priority of a cut selector was changed */
46   	static
47   	SCIP_DECL_PARAMCHGD(paramChgdCutselPriority)
48   	{  /*lint --e{715}*/
49   	   SCIP_PARAMDATA* paramdata;
50   	
51   	   paramdata = SCIPparamGetData(param);
52   	   assert(paramdata != NULL);
53   	
54   	   /* use SCIPsetCutselPriority() to mark the cutsels unsorted */
55   	   SCIP_CALL( SCIPsetCutselPriority(scip, (SCIP_CUTSEL*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/
56   	
57   	   return SCIP_OKAY;
58   	}
59   	
60   	/** internal method for creating a cut selector */
61   	static
62   	SCIP_RETCODE doCutselCreate(
63   	   SCIP_CUTSEL**         cutsel,             /**< pointer to store cut selector */
64   	   SCIP_SET*             set,                /**< global SCIP settings */
65   	   SCIP_MESSAGEHDLR*     messagehdlr,        /**< message handler */
66   	   BMS_BLKMEM*           blkmem,             /**< block memory for parameter settings */
67   	   const char*           name,               /**< name of cut selector */
68   	   const char*           desc,               /**< description of cut selector */
69   	   int                   priority,           /**< priority of the cut selector */
70   	   SCIP_DECL_CUTSELCOPY ((*cutselcopy)),     /**< copy method of cut selector or NULL if you don't want to copy your plugin into sub-SCIPs */
71   	   SCIP_DECL_CUTSELFREE ((*cutselfree)),     /**< destructor of cut selector */
72   	   SCIP_DECL_CUTSELINIT ((*cutselinit)),     /**< initialize cut selector */
73   	   SCIP_DECL_CUTSELEXIT ((*cutselexit)),     /**< deinitialize cut selector */
74   	   SCIP_DECL_CUTSELINITSOL((*cutselinitsol)),/**< solving process initialization method of cut selector */
75   	   SCIP_DECL_CUTSELEXITSOL((*cutselexitsol)),/**< solving process deinitialization method of cut selector */
76   	   SCIP_DECL_CUTSELSELECT((*cutselselect)),  /**< cut selection method */
77   	   SCIP_CUTSELDATA*      cutseldata          /**< cut selector data */
78   	   )
79   	{
80   	   char paramname[SCIP_MAXSTRLEN];
81   	   char paramdesc[SCIP_MAXSTRLEN];
82   	
83   	   assert(cutsel != NULL);
84   	   assert(name != NULL);
85   	   assert(desc != NULL);
86   	   assert(cutselselect != NULL);
87   	
88   	   SCIP_ALLOC( BMSallocMemory(cutsel) );
89   	   BMSclearMemory(*cutsel);
90   	
91   	   SCIP_ALLOC( BMSduplicateMemoryArray(&(*cutsel)->name, name, strlen(name)+1) );
92   	   SCIP_ALLOC( BMSduplicateMemoryArray(&(*cutsel)->desc, desc, strlen(desc)+1) );
93   	   (*cutsel)->priority = priority;
94   	   (*cutsel)->cutselcopy = cutselcopy;
95   	   (*cutsel)->cutselfree = cutselfree;
96   	   (*cutsel)->cutselinit = cutselinit;
97   	   (*cutsel)->cutselexit = cutselexit;
98   	   (*cutsel)->cutselinitsol = cutselinitsol;
99   	   (*cutsel)->cutselexitsol = cutselexitsol;
100  	   (*cutsel)->cutselselect = cutselselect;
101  	   (*cutsel)->cutseldata = cutseldata;
102  	   (*cutsel)->ncalls = 0;
103  	   (*cutsel)->nrootcalls = 0;
104  	   (*cutsel)->nrootcutsselected = 0;
105  	   (*cutsel)->nrootcutsforced = 0;
106  	   (*cutsel)->nrootcutsfiltered = 0;
107  	   (*cutsel)->nlocalcutsselected = 0;
108  	   (*cutsel)->nlocalcutsforced = 0;
109  	   (*cutsel)->nlocalcutsfiltered = 0;
110  	   (*cutsel)->initialized = FALSE;
111  	
112  	   /* create clocks */
113  	   SCIP_CALL( SCIPclockCreate(&(*cutsel)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
114  	   SCIP_CALL( SCIPclockCreate(&(*cutsel)->cutseltime, SCIP_CLOCKTYPE_DEFAULT) );
115  	
116  	   /* add parameters */
117  	   (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "cutselection/%s/priority", name);
118  	   (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of cut selection rule <%s>", name);
119  	   SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
120  	         &(*cutsel)->priority, FALSE, priority, INT_MIN/4, INT_MAX/2,
121  	         paramChgdCutselPriority, (SCIP_PARAMDATA*)(*cutsel)) ); /*lint !e740*/
122  	
123  	   return SCIP_OKAY;
124  	}
125  	
126  	
127  	/** creates a cut selector */
128  	SCIP_RETCODE SCIPcutselCreate(
129  	   SCIP_CUTSEL**         cutsel,             /**< pointer to store cut selector */
130  	   SCIP_SET*             set,                /**< global SCIP settings */
131  	   SCIP_MESSAGEHDLR*     messagehdlr,        /**< message handler */
132  	   BMS_BLKMEM*           blkmem,             /**< block memory for parameter settings */
133  	   const char*           name,               /**< name of cut selector */
134  	   const char*           desc,               /**< description of cut selector */
135  	   int                   priority,           /**< priority of the cut selector in standard mode */
136  	   SCIP_DECL_CUTSELCOPY ((*cutselcopy)),     /**< copy method of cut selector or NULL if you don't want to copy your plugin into sub-SCIPs */
137  	   SCIP_DECL_CUTSELFREE ((*cutselfree)),     /**< destructor of cut selector */
138  	   SCIP_DECL_CUTSELINIT ((*cutselinit)),     /**< initialize cut selector */
139  	   SCIP_DECL_CUTSELEXIT ((*cutselexit)),     /**< deinitialize cut selector */
140  	   SCIP_DECL_CUTSELINITSOL((*cutselinitsol)),/**< solving process initialization method of cut selector */
141  	   SCIP_DECL_CUTSELEXITSOL((*cutselexitsol)),/**< solving process deinitialization method of cut selector */
142  	   SCIP_DECL_CUTSELSELECT((*cutselselect)),  /**< cut selection method */
143  	   SCIP_CUTSELDATA*      cutseldata          /**< cut selector data */
144  	   )
145  	{
146  	   assert(cutsel != NULL);
147  	   assert(name != NULL);
148  	   assert(desc != NULL);
149  	   assert(cutselselect != NULL);
150  	
151  	   SCIP_CALL_FINALLY( doCutselCreate(cutsel, set, messagehdlr, blkmem, name, desc, priority,
152  	         cutselcopy, cutselfree, cutselinit, cutselexit, cutselinitsol, cutselexitsol, cutselselect,
153  	         cutseldata), (void) SCIPcutselFree(cutsel, set) );
154  	
155  	   return SCIP_OKAY;
156  	}
157  	
158  	/** gets name of cut selector */
159  	const char* SCIPcutselGetName(
160  	   SCIP_CUTSEL*          cutsel              /**< cut selector */
161  	   )
162  	{
163  	   assert(cutsel != NULL);
164  	
165  	   return cutsel->name;
166  	}
167  	
168  	/** calls cut selectors to select cuts */
169  	SCIP_RETCODE SCIPcutselsSelect(
170  	   SCIP_SET*             set,                /**< global SCIP settings */
171  	   SCIP_ROW**            cuts,               /**< array with cuts to select from */
172  	   int                   ncuts,              /**< length of cuts */
173  	   int                   nforcedcuts,        /**< number of forced cuts at start of given array */
174  	   SCIP_Bool             root,               /**< are we at the root node? */
175  	   SCIP_Bool             initiallp,          /**< is the separation storage currently being filled with the initial LP rows? */
176  	   int                   maxnselectedcuts,   /**< maximum number of cuts to be selected */
177  	   int*                  nselectedcuts       /**< pointer to return number of selected cuts */
178  	   )
179  	{
180  	   int i;
181  	   SCIP_RESULT result = SCIP_DIDNOTFIND;
182  	
183  	   assert(nselectedcuts != NULL);
184  	
185  	   /* sort the cut selectors by priority */
186  	   SCIPsetSortCutsels(set);
187  	
188  	   /* Redefine maxnselectedcuts to be w.r.t the optional cuts. */
189  	   maxnselectedcuts -= nforcedcuts;
190  	   maxnselectedcuts = MIN(maxnselectedcuts, ncuts);
191  	
192  	   /* try all cut selectors until one succeeds */
193  	   *nselectedcuts = 0;
194  	   for( i = 0; i < set->ncutsels && result == SCIP_DIDNOTFIND; ++i )
195  	   {
196  	      SCIP_CUTSEL* cutsel;
197  	
198  	      cutsel = set->cutsels[i];
199  	
200  	      assert(cutsel != NULL);
201  	      assert(ncuts - nforcedcuts > 0);
202  	      assert(maxnselectedcuts > 0);
203  	
204  	      /* start timing */
205  	      SCIPclockStart(cutsel->cutseltime, set);
206  	
207  	      SCIP_CALL( cutsel->cutselselect(set->scip, cutsel, &(cuts[nforcedcuts]), ncuts - nforcedcuts, cuts, nforcedcuts,
208  	            root, maxnselectedcuts, nselectedcuts, &result) );
209  	
210  	      /* stop timing */
211  	      SCIPclockStop(cutsel->cutseltime, set);
212  	
213  	      assert(*nselectedcuts <= maxnselectedcuts);
214  	      assert(result == SCIP_SUCCESS || result == SCIP_DIDNOTFIND);
215  	      assert(result != SCIP_DIDNOTFIND || *nselectedcuts == 0);
216  	
217  	      ++cutsel->ncalls;
218  	      if( root )
219  	        ++cutsel->nrootcalls;
220  	
221  	      if( result != SCIP_DIDNOTFIND && !initiallp )
222  	      {
223  	         assert(0 <= ncuts);
224  	         assert(0 <= *nselectedcuts && *nselectedcuts <= ncuts);
225  	
226  	         if( root )
227  	         {
228  	            cutsel->nrootcutsselected += *nselectedcuts;
229  	            cutsel->nrootcutsforced += nforcedcuts;
230  	            cutsel->nrootcutsfiltered += ncuts - *nselectedcuts; /*lint !e776*/
231  	         }
232  	         else
233  	         {
234  	            cutsel->nlocalcutsselected += *nselectedcuts;
235  	            cutsel->nlocalcutsforced += nforcedcuts;
236  	            cutsel->nlocalcutsfiltered += ncuts - *nselectedcuts; /*lint !e776*/
237  	         }
238  	      }
239  	   }
240  	
241  	   return SCIP_OKAY;
242  	}
243  	
244  	/** gets description of cut selector */
245  	const char* SCIPcutselGetDesc(
246  	   SCIP_CUTSEL*          cutsel              /**< cut selector */
247  	   )
248  	{
249  	   assert(cutsel != NULL);
250  	
251  	   return cutsel->desc;
252  	}
253  	
254  	/** copies the given cut selector to a new scip */
255  	SCIP_RETCODE SCIPcutselCopyInclude(
256  	   SCIP_CUTSEL*          cutsel,             /**< cut selector */
257  	   SCIP_SET*             set                 /**< SCIP_SET of SCIP to copy to */
258  	   )
259  	{
260  	   assert(cutsel != NULL);
261  	   assert(set != NULL);
262  	   assert(set->scip != NULL);
263  	
264  	   if( cutsel->cutselcopy != NULL )
265  	   {
266  	      SCIPsetDebugMsg(set, "including cut selector %s in subscip %p\n", SCIPcutselGetName(cutsel), (void*)set->scip);
267  	      SCIP_CALL( cutsel->cutselcopy(set->scip, cutsel) );
268  	   }
269  	   return SCIP_OKAY;
270  	}
271  	
272  	/** frees memory of cut selector */
273  	SCIP_RETCODE SCIPcutselFree(
274  	   SCIP_CUTSEL**         cutsel,             /**< pointer to cut selector data structure */
275  	   SCIP_SET*             set                 /**< global SCIP settings */
276  	   )
277  	{
278  	   assert(cutsel != NULL);
279  	
280  	   if( *cutsel == NULL )
281  	      return SCIP_OKAY;
282  	
283  	   assert(!(*cutsel)->initialized);
284  	   assert(set != NULL);
285  	
286  	   /* call destructor of cut selector */
287  	   if( (*cutsel)->cutselfree != NULL )
288  	   {
289  	      SCIP_CALL( (*cutsel)->cutselfree(set->scip, *cutsel) );
290  	   }
291  	
292  	   /* free clocks */
293  	   SCIPclockFree(&(*cutsel)->cutseltime);
294  	   SCIPclockFree(&(*cutsel)->setuptime);
295  	
296  	   BMSfreeMemoryArrayNull(&(*cutsel)->name);
297  	   BMSfreeMemoryArrayNull(&(*cutsel)->desc);
298  	   BMSfreeMemory(cutsel);
299  	
300  	   return SCIP_OKAY;
301  	}
302  	
303  	/** initializes cut selector */
304  	SCIP_RETCODE SCIPcutselInit(
305  	   SCIP_CUTSEL*          cutsel,             /**< cut selector */
306  	   SCIP_SET*             set                 /**< global SCIP settings */
307  	   )
308  	{
309  	   assert(cutsel != NULL);
310  	   assert(set != NULL);
311  	
312  	   if( cutsel->initialized )
313  	   {
314  	      SCIPerrorMessage("cut selector <%s> already initialized", cutsel->name);
315  	      return SCIP_INVALIDCALL;
316  	   }
317  	
318  	   if( set->misc_resetstat )
319  	   {
320  	      SCIPclockReset(cutsel->setuptime);
321  	      SCIPclockReset(cutsel->cutseltime);
322  	   }
323  	
324  	   if( cutsel->cutselinit != NULL )
325  	   {
326  	      /* start timing */
327  	      SCIPclockStart(cutsel->setuptime, set);
328  	
329  	      SCIP_CALL( cutsel->cutselinit(set->scip, cutsel) );
330  	
331  	      /* stop timing */
332  	      SCIPclockStop(cutsel->setuptime, set);
333  	   }
334  	
335  	   cutsel->initialized = TRUE;
336  	
337  	   return SCIP_OKAY;
338  	}
339  	
340  	/** deinitializes cut selector */
341  	SCIP_RETCODE SCIPcutselExit(
342  	   SCIP_CUTSEL*          cutsel,             /**< cut selector */
343  	   SCIP_SET*             set                 /**< global SCIP settings */
344  	   )
345  	{
346  	   assert(cutsel != NULL);
347  	   assert(set != NULL);
348  	
349  	   if( !cutsel->initialized )
350  	   {
351  	      SCIPerrorMessage("cut selector <%s> not initialized", cutsel->name);
352  	      return SCIP_INVALIDCALL;
353  	   }
354  	
355  	   if( cutsel->cutselexit != NULL )
356  	   {
357  	      /* start timing */
358  	      SCIPclockStart(cutsel->setuptime, set);
359  	
360  	      SCIP_CALL( cutsel->cutselexit(set->scip, cutsel) );
361  	
362  	      /* stop timing */
363  	      SCIPclockStop(cutsel->setuptime, set);
364  	   }
365  	   cutsel->initialized = FALSE;
366  	
367  	   return SCIP_OKAY;
368  	}
369  	
370  	/** informs cut selector that the branch and bound process is being started */
371  	SCIP_RETCODE SCIPcutselInitsol(
372  	   SCIP_CUTSEL*          cutsel,             /**< cut selector */
373  	   SCIP_SET*             set                 /**< global SCIP settings */
374  	   )
375  	{
376  	   assert(cutsel != NULL);
377  	   assert(set != NULL);
378  	
379  	   /* call solving process initialization method of cut selector */
380  	   if( cutsel->cutselinitsol != NULL )
381  	   {
382  	      /* start timing */
383  	      SCIPclockStart(cutsel->setuptime, set);
384  	
385  	      SCIP_CALL( cutsel->cutselinitsol(set->scip, cutsel) );
386  	
387  	      /* stop timing */
388  	      SCIPclockStop(cutsel->setuptime, set);
389  	   }
390  	
391  	   return SCIP_OKAY;
392  	}
393  	
394  	/** informs cut selector that the branch and bound process is being started */
395  	SCIP_RETCODE SCIPcutselExitsol(
396  	   SCIP_CUTSEL*          cutsel,             /**< cut selector */
397  	   SCIP_SET*             set                 /**< global SCIP settings */
398  	   )
399  	{
400  	   assert(cutsel != NULL);
401  	   assert(set != NULL);
402  	
403  	   /* call solving process deinitialization method of cut selector */
404  	   if( cutsel->cutselexitsol != NULL )
405  	   {
406  	      /* start timing */
407  	      SCIPclockStart(cutsel->setuptime, set);
408  	
409  	      SCIP_CALL( cutsel->cutselexitsol(set->scip, cutsel) );
410  	
411  	      /* stop timing */
412  	      SCIPclockStop(cutsel->setuptime, set);
413  	   }
414  	
415  	   return SCIP_OKAY;
416  	}
417  	
418  	/** gets user data of cut selector */
419  	SCIP_CUTSELDATA* SCIPcutselGetData(
420  	   SCIP_CUTSEL*          cutsel              /**< cut selector */
421  	   )
422  	{
423  	   assert(cutsel != NULL);
424  	
425  	   return cutsel->cutseldata;
426  	}
427  	
428  	/** sets user data of cut selector; user has to free old data in advance! */
429  	void SCIPcutselSetData(
430  	   SCIP_CUTSEL*          cutsel,             /**< cut selector */
431  	   SCIP_CUTSELDATA*      cutseldata          /**< new cut selector user data */
432  	   )
433  	{
434  	   assert(cutsel != NULL);
435  	
436  	   cutsel->cutseldata = cutseldata;
437  	}
438  	
439  	/** gets priority of cut selector */
440  	int SCIPcutselGetPriority(
441  	   SCIP_CUTSEL*          cutsel              /**< cut selector */
442  	   )
443  	{
444  	   assert(cutsel != NULL);
445  	
446  	   return cutsel->priority;
447  	}
448  	
449  	/** enables or disables all clocks of @p cutsel, depending on the value of the flag */
450  	void SCIPcutselEnableOrDisableClocks(
451  	   SCIP_CUTSEL*          cutsel,             /**< the cut selector for which all clocks should be enabled or disabled */
452  	   SCIP_Bool             enable              /**< should the clocks of the cut selector be enabled? */
453  	   )
454  	{
455  	   assert(cutsel != NULL);
456  	
457  	   SCIPclockEnableOrDisable(cutsel->setuptime, enable);
458  	   SCIPclockEnableOrDisable(cutsel->cutseltime, enable);
459  	}
460  	
461  	
462  	/* new callback/method setter methods */
463  	
464  	/** sets copy method of cut selector */
465  	void SCIPcutselSetCopy(
466  	   SCIP_CUTSEL*          cutsel,             /**< cut selector */
467  	   SCIP_DECL_CUTSELCOPY  ((*cutselcopy))     /**< copy method of cut selector or NULL if you don't want to copy your plugin into sub-SCIPs */
468  	   )
469  	{
470  	   assert(cutsel != NULL);
471  	
472  	   cutsel->cutselcopy = cutselcopy;
473  	}
474  	
475  	/** sets destructor method of cut selector */
476  	void SCIPcutselSetFree(
477  	   SCIP_CUTSEL*          cutsel,             /**< cut selector */
478  	   SCIP_DECL_CUTSELFREE  ((*cutselfree))     /**< destructor of cut selector */
479  	   )
480  	{
481  	   assert(cutsel != NULL);
482  	
483  	   cutsel->cutselfree = cutselfree;
484  	}
485  	
486  	/** sets initialization method of cut selector */
487  	void SCIPcutselSetInit(
488  	   SCIP_CUTSEL*          cutsel,             /**< cut selector */
489  	   SCIP_DECL_CUTSELINIT  ((*cutselinit))     /**< initialize cut selector */
490  	   )
491  	{
492  	   assert(cutsel != NULL);
493  	
494  	   cutsel->cutselinit = cutselinit;
495  	}
496  	
497  	/** sets deinitialization method of cut selector */
498  	void SCIPcutselSetExit(
499  	   SCIP_CUTSEL*          cutsel,             /**< cut selector */
500  	   SCIP_DECL_CUTSELEXIT  ((*cutselexit))     /**< deinitialize cut selector */
501  	   )
502  	{
503  	   assert(cutsel != NULL);
504  	
505  	   cutsel->cutselexit = cutselexit;
506  	}
507  	
508  	/** sets solving process initialization method of cut selector */
509  	void SCIPcutselSetInitsol(
510  	   SCIP_CUTSEL*          cutsel,             /**< cut selector */
511  	   SCIP_DECL_CUTSELINITSOL ((*cutselinitsol))/**< solving process initialization method of cut selector */
512  	   )
513  	{
514  	   assert(cutsel != NULL);
515  	
516  	   cutsel->cutselinitsol = cutselinitsol;
517  	}
518  	
519  	/** sets solving process deinitialization method of cut selector */
520  	void SCIPcutselSetExitsol(
521  	   SCIP_CUTSEL*          cutsel,             /**< cut selector */
522  	   SCIP_DECL_CUTSELEXITSOL ((*cutselexitsol))/**< solving process deinitialization method of cut selector */
523  	   )
524  	{
525  	   assert(cutsel != NULL);
526  	
527  	   cutsel->cutselexitsol = cutselexitsol;
528  	}
529  	
530  	/** sets priority of cut selector */
531  	void SCIPcutselSetPriority(
532  	   SCIP_CUTSEL*          cutsel,             /**< cut selector */
533  	   SCIP_SET*             set,                /**< global SCIP settings */
534  	   int                   priority            /**< new priority of the cut selector */
535  	   )
536  	{
537  	   assert(cutsel != NULL);
538  	   assert(set != NULL);
539  	
540  	   cutsel->priority = priority;
541  	   set->cutselssorted = FALSE;
542  	}
543  	
544  	/** is cut selector initialized? */
545  	SCIP_Bool SCIPcutselIsInitialized(
546  	   SCIP_CUTSEL*          cutsel              /**< cut selector */
547  	   )
548  	{
549  	   assert(cutsel != NULL);
550  	
551  	   return cutsel->initialized;
552  	}
553  	
554  	/** gets time in seconds used in this cut selector for setting up for next stages */
555  	SCIP_Real SCIPcutselGetSetupTime(
556  	   SCIP_CUTSEL*          cutsel              /**< cut selector */
557  	   )
558  	{
559  	   assert(cutsel != NULL);
560  	
561  	   return SCIPclockGetTime(cutsel->setuptime);
562  	}
563  	
564  	/** gets time in seconds used in this cut selector */
565  	SCIP_Real SCIPcutselGetTime(
566  	   SCIP_CUTSEL*          cutsel              /**< cut selector */
567  	   )
568  	{
569  	   assert(cutsel != NULL);
570  	
571  	   return SCIPclockGetTime(cutsel->cutseltime);
572  	}
573  	
574  	/** get number of times the cutselector was called */
575  	SCIP_Longint SCIPcutselGetNCalls(
576  	   SCIP_CUTSEL*          cutsel              /**< cut selector */
577  	   )
578  	{
579  	  assert(cutsel != NULL);
580  	
581  	  return cutsel->ncalls;
582  	}
583  	
584  	/** get number of times the cutselector was called at the root */
585  	SCIP_Longint SCIPcutselGetNRootCalls(
586  	   SCIP_CUTSEL*          cutsel              /**< cut selector */
587  	   )
588  	{
589  	  assert(cutsel != NULL);
590  	
591  	  return cutsel->nrootcalls;
592  	}
593  	
594  	/** get total number of cuts that were selected at the root */
595  	SCIP_Longint SCIPcutselGetNRootCuts(
596  	   SCIP_CUTSEL*          cutsel              /**< cut selector */
597  	   )
598  	{
599  	   assert(cutsel != NULL);
600  	
601  	   return cutsel->nrootcutsselected;
602  	}
603  	
604  	/** get total number of forced cuts that were selected at the root */
605  	SCIP_Longint SCIPcutselGetNRootForcedCuts(
606  	   SCIP_CUTSEL*          cutsel              /**< cut selector */
607  	   )
608  	{
609  	   assert(cutsel != NULL);
610  	
611  	   return cutsel->nrootcutsforced;
612  	}
613  	
614  	/** get total number of root cuts that were filtered */
615  	SCIP_Longint SCIPcutselGetNRootCutsFiltered(
616  	   SCIP_CUTSEL*          cutsel              /**< cut selector */
617  	   )
618  	{
619  	   assert(cutsel != NULL);
620  	
621  	   return cutsel->nrootcutsfiltered;
622  	}
623  	
624  	/** get total number of local cuts that were selected */
625  	SCIP_Longint SCIPcutselGetNLocalCuts(
626  	   SCIP_CUTSEL*          cutsel              /**< cut selector */
627  	   )
628  	{
629  	   assert(cutsel != NULL);
630  	
631  	   return cutsel->nlocalcutsselected;
632  	}
633  	
634  	/** get total number of forced local cuts that were selected */
635  	SCIP_Longint SCIPcutselGetNLocalForcedCuts(
636  	   SCIP_CUTSEL*          cutsel              /**< cut selector */
637  	   )
638  	{
639  	   assert(cutsel != NULL);
640  	
641  	   return cutsel->nlocalcutsforced;
642  	}
643  	
644  	/** get total number of local cuts that were filtered */
645  	SCIP_Longint SCIPcutselGetNLocalCutsFiltered(
646  	   SCIP_CUTSEL*          cutsel              /**< cut selector */
647  	   )
648  	{
649  	   assert(cutsel != NULL);
650  	
651  	   return cutsel->nlocalcutsfiltered;
652  	}
653  	
654  	/** compares two cut selectors w. r. to their priority */
655  	SCIP_DECL_SORTPTRCOMP(SCIPcutselComp)
656  	{  /*lint --e{715}*/
657  	   return ((SCIP_CUTSEL*)elem2)->priority - ((SCIP_CUTSEL*)elem1)->priority;
658  	}
659