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   objcutsel.cpp
26   	 * @brief  C++ wrapper for cut selectors
27   	 * @author Felipe Serrano
28   	 * @author Mark Turner
29   	 */
30   	
31   	/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
32   	
33   	#include <cassert>
34   	
35   	#include "objcutsel.h"
36   	
37   	
38   	
39   	
40   	/*
41   	 * Data structures
42   	 */
43   	
44   	/** cut selector data */
45   	struct SCIP_CutselData
46   	{
47   	   scip::ObjCutsel*      objcutsel;          /**< cut selector object */
48   	   SCIP_Bool             deleteobject;       /**< should the cut selector object be deleted when cut selector is freed? */
49   	};
50   	
51   	
52   	
53   	
54   	/*
55   	 * Callback methods of cut selector
56   	 */
57   	
58   	extern "C"
59   	{
60   	
61   	/** copy method for cut selector plugins (called when SCIP copies plugins) */
62   	static
63   	SCIP_DECL_CUTSELCOPY(cutselCopyObj)
64   	{  /*lint --e{715}*/
65   	   SCIP_CUTSELDATA* cutseldata;
66   	
67   	   assert(scip != NULL);
68   	
69   	   cutseldata = SCIPcutselGetData(cutsel);
70   	   assert(cutseldata != NULL);
71   	   assert(cutseldata->objcutsel != NULL);
72   	   assert(cutseldata->objcutsel->scip_ != scip);
73   	
74   	   if( cutseldata->objcutsel->iscloneable() )
75   	   {
76   	      scip::ObjCutsel* newobjcutsel;
77   	      newobjcutsel = dynamic_cast<scip::ObjCutsel*> (cutseldata->objcutsel->clone(scip));
78   	
79   	      /* call include method of cut selector object */
80   	      SCIP_CALL( SCIPincludeObjCutsel(scip, newobjcutsel, TRUE) );
81   	   }
82   	
83   	   return SCIP_OKAY;
84   	}
85   	
86   	/** destructor of cut selector to free user data (called when SCIP is exiting) */
87   	static
88   	SCIP_DECL_CUTSELFREE(cutselFreeObj)
89   	{  /*lint --e{715}*/
90   	   SCIP_CUTSELDATA* cutseldata;
91   	
92   	   cutseldata = SCIPcutselGetData(cutsel);
93   	   assert(cutseldata != NULL);
94   	   assert(cutseldata->objcutsel != NULL);
95   	   assert(cutseldata->objcutsel->scip_ == scip);
96   	
97   	   /* call virtual method of cutsel object */
98   	   SCIP_CALL( cutseldata->objcutsel->scip_free(scip, cutsel) );
99   	
100  	   /* free cutsel object */
101  	   if( cutseldata->deleteobject )
102  	      delete cutseldata->objcutsel;
103  	
104  	   /* free cutsel data */
105  	   delete cutseldata;
106  	   SCIPcutselSetData(cutsel, NULL); /*lint !e64*/
107  	
108  	   return SCIP_OKAY;
109  	}
110  	
111  	
112  	/** initialization method of cut selector (called after problem was transformed) */
113  	static
114  	SCIP_DECL_CUTSELINIT(cutselInitObj)
115  	{  /*lint --e{715}*/
116  	   SCIP_CUTSELDATA* cutseldata;
117  	
118  	   cutseldata = SCIPcutselGetData(cutsel);
119  	   assert(cutseldata != NULL);
120  	   assert(cutseldata->objcutsel != NULL);
121  	   assert(cutseldata->objcutsel->scip_ == scip);
122  	
123  	   /* call virtual method of cutsel object */
124  	   SCIP_CALL( cutseldata->objcutsel->scip_init(scip, cutsel) );
125  	
126  	   return SCIP_OKAY;
127  	}
128  	
129  	
130  	/** deinitialization method of cut selector (called before transformed problem is freed) */
131  	static
132  	SCIP_DECL_CUTSELEXIT(cutselExitObj)
133  	{  /*lint --e{715}*/
134  	   SCIP_CUTSELDATA* cutseldata;
135  	
136  	   cutseldata = SCIPcutselGetData(cutsel);
137  	   assert(cutseldata != NULL);
138  	   assert(cutseldata->objcutsel != NULL);
139  	
140  	   /* call virtual method of cutsel object */
141  	   SCIP_CALL( cutseldata->objcutsel->scip_exit(scip, cutsel) );
142  	
143  	   return SCIP_OKAY;
144  	}
145  	
146  	
147  	/** solving process initialization method of cut selector (called when branch and bound process is about to begin) */
148  	static
149  	SCIP_DECL_CUTSELINITSOL(cutselInitsolObj)
150  	{  /*lint --e{715}*/
151  	   SCIP_CUTSELDATA* cutseldata;
152  	
153  	   cutseldata = SCIPcutselGetData(cutsel);
154  	   assert(cutseldata != NULL);
155  	   assert(cutseldata->objcutsel != NULL);
156  	
157  	   /* call virtual method of cutsel object */
158  	   SCIP_CALL( cutseldata->objcutsel->scip_initsol(scip, cutsel) );
159  	
160  	   return SCIP_OKAY;
161  	}
162  	
163  	
164  	/** solving process deinitialization method of cut selector (called before branch and bound process data is freed) */
165  	static
166  	SCIP_DECL_CUTSELEXITSOL(cutselExitsolObj)
167  	{  /*lint --e{715}*/
168  	   SCIP_CUTSELDATA* cutseldata;
169  	
170  	   cutseldata = SCIPcutselGetData(cutsel);
171  	   assert(cutseldata != NULL);
172  	   assert(cutseldata->objcutsel != NULL);
173  	
174  	   /* call virtual method of cutsel object */
175  	   SCIP_CALL( cutseldata->objcutsel->scip_exitsol(scip, cutsel) );
176  	
177  	   return SCIP_OKAY;
178  	}
179  	
180  	
181  	/** cut selection method of cut selector */
182  	static
183  	SCIP_DECL_CUTSELSELECT(cutselSelectObj)
184  	{  /*lint --e{715}*/
185  	   SCIP_CUTSELDATA* cutseldata;
186  	
187  	   cutseldata = SCIPcutselGetData(cutsel);
188  	   assert(cutseldata != NULL);
189  	   assert(cutseldata->objcutsel != NULL);
190  	
191  	   /* call virtual method of cutsel object */
192  	   SCIP_CALL( cutseldata->objcutsel->scip_select(scip, cutsel, cuts, ncuts, forcedcuts, nforcedcuts,
193  	      root, maxnselectedcuts, nselectedcuts, result) );
194  	
195  	   return SCIP_OKAY;
196  	}
197  	}
198  	
199  	
200  	
201  	/*
202  	 * cut selector specific interface methods
203  	 */
204  	
205  	/** creates the cut selector for the given cut selector object and includes it in SCIP */
206  	SCIP_RETCODE SCIPincludeObjCutsel(
207  	   SCIP*                 scip,               /**< SCIP data structure */
208  	   scip::ObjCutsel*      objcutsel,          /**< cut selector object */
209  	   SCIP_Bool             deleteobject        /**< should the cut selector object be deleted when cut selector is freed? */
210  	   )
211  	{
212  	   SCIP_CUTSELDATA* cutseldata;
213  	
214  	   assert(scip != NULL);
215  	   assert(objcutsel != NULL);
216  	
217  	   /* create cut selector data */
218  	   cutseldata = new SCIP_CUTSELDATA;
219  	   cutseldata->objcutsel = objcutsel;
220  	   cutseldata->deleteobject = deleteobject;
221  	
222  	   /* include cut selector */
223  	   SCIP_CALL( SCIPincludeCutsel(scip, objcutsel->scip_name_, objcutsel->scip_desc_,
224  	         objcutsel->scip_priority_,
225  	         cutselCopyObj,
226  	         cutselFreeObj, cutselInitObj, cutselExitObj,
227  	         cutselInitsolObj, cutselExitsolObj, cutselSelectObj,
228  	         cutseldata) ); /*lint !e429*/
229  	
230  	   return SCIP_OKAY; /*lint !e429*/
231  	}
232  	
233  	/** returns the cutsel object of the given name, or 0 if not existing */
234  	scip::ObjCutsel* SCIPfindObjCutsel(
235  	   SCIP*                 scip,               /**< SCIP data structure */
236  	   const char*           name                /**< name of cut selector */
237  	   )
238  	{
239  	   SCIP_CUTSEL* cutsel;
240  	   SCIP_CUTSELDATA* cutseldata;
241  	
242  	   cutsel = SCIPfindCutsel(scip, name);
243  	   if( cutsel == NULL )
244  	      return 0;
245  	
246  	   cutseldata = SCIPcutselGetData(cutsel);
247  	   assert(cutseldata != NULL);
248  	
249  	   return cutseldata->objcutsel;
250  	}
251  	
252  	/** returns the cutsel object for the given cut selector */
253  	scip::ObjCutsel* SCIPgetObjCutsel(
254  	   SCIP*                 scip,               /**< SCIP data structure */
255  	   SCIP_CUTSEL*          cutsel              /**< cut selector */
256  	   )
257  	{
258  	   SCIP_CUTSELDATA* cutseldata;
259  	
260  	   assert(scip != NULL);
261  	   cutseldata = SCIPcutselGetData(cutsel);
262  	   assert(cutseldata != NULL);
263  	
264  	   return cutseldata->objcutsel;
265  	}
266