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 objsepa.cpp
17 * @brief C++ wrapper for cut separators
18 * @author Tobias Achterberg
19 */
20
21 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
22
23 #include <cassert>
24
25 #include "objsepa.h"
26
27
28
29
30 /*
31 * Data structures
32 */
33
34 /** cut separator data */
35 struct SCIP_SepaData
36 {
37 scip::ObjSepa* objsepa; /**< cut separator object */
38 SCIP_Bool deleteobject; /**< should the cut separator object be deleted when cut separator is freed? */
39 };
40
41
42
43 /*
44 * Callback methods of cut separator
45 */
46
47 extern "C"
48 {
49
50 /** copy method for separator plugins (called when SCIP copies plugins) */
51 static
SCIP_DECL_SEPACOPY(sepaCopyObj)52 SCIP_DECL_SEPACOPY(sepaCopyObj)
53 { /*lint --e{715}*/
54 SCIP_SEPADATA* sepadata;
55
56 assert(scip != NULL);
57
58 sepadata = SCIPsepaGetData(sepa);
59 assert(sepadata != NULL);
60 assert(sepadata->objsepa != NULL);
61 assert(sepadata->objsepa->scip_ != scip);
62
63 if( sepadata->objsepa->iscloneable() )
64 {
65 scip::ObjSepa* newobjsepa;
66 newobjsepa = dynamic_cast<scip::ObjSepa*> (sepadata->objsepa->clone(scip));
67
68 /* call include method of separator object */
69 SCIP_CALL( SCIPincludeObjSepa(scip, newobjsepa, TRUE) );
70 }
71
72 return SCIP_OKAY;
73 }
74
75 /** destructor of cut separator to free user data (called when SCIP is exiting) */
76 static
SCIP_DECL_SEPAFREE(sepaFreeObj)77 SCIP_DECL_SEPAFREE(sepaFreeObj)
78 { /*lint --e{715}*/
79 SCIP_SEPADATA* sepadata;
80
81 sepadata = SCIPsepaGetData(sepa);
82 assert(sepadata != NULL);
83 assert(sepadata->objsepa != NULL);
84 assert(sepadata->objsepa->scip_ == scip);
85
86 /* call virtual method of sepa object */
87 SCIP_CALL( sepadata->objsepa->scip_free(scip, sepa) );
88
89 /* free sepa object */
90 if( sepadata->deleteobject )
91 delete sepadata->objsepa;
92
93 /* free sepa data */
94 delete sepadata;
95 SCIPsepaSetData(sepa, NULL); /*lint !e64*/
96
97 return SCIP_OKAY;
98 }
99
100
101 /** initialization method of cut separator (called after problem was transformed) */
102 static
SCIP_DECL_SEPAINIT(sepaInitObj)103 SCIP_DECL_SEPAINIT(sepaInitObj)
104 { /*lint --e{715}*/
105 SCIP_SEPADATA* sepadata;
106
107 sepadata = SCIPsepaGetData(sepa);
108 assert(sepadata != NULL);
109 assert(sepadata->objsepa != NULL);
110 assert(sepadata->objsepa->scip_ == scip);
111
112 /* call virtual method of sepa object */
113 SCIP_CALL( sepadata->objsepa->scip_init(scip, sepa) );
114
115 return SCIP_OKAY;
116 }
117
118
119 /** deinitialization method of cut separator (called before transformed problem is freed) */
120 static
SCIP_DECL_SEPAEXIT(sepaExitObj)121 SCIP_DECL_SEPAEXIT(sepaExitObj)
122 { /*lint --e{715}*/
123 SCIP_SEPADATA* sepadata;
124
125 sepadata = SCIPsepaGetData(sepa);
126 assert(sepadata != NULL);
127 assert(sepadata->objsepa != NULL);
128
129 /* call virtual method of sepa object */
130 SCIP_CALL( sepadata->objsepa->scip_exit(scip, sepa) );
131
132 return SCIP_OKAY;
133 }
134
135
136 /** solving process initialization method of separator (called when branch and bound process is about to begin) */
137 static
SCIP_DECL_SEPAINITSOL(sepaInitsolObj)138 SCIP_DECL_SEPAINITSOL(sepaInitsolObj)
139 { /*lint --e{715}*/
140 SCIP_SEPADATA* sepadata;
141
142 sepadata = SCIPsepaGetData(sepa);
143 assert(sepadata != NULL);
144 assert(sepadata->objsepa != NULL);
145
146 /* call virtual method of sepa object */
147 SCIP_CALL( sepadata->objsepa->scip_initsol(scip, sepa) );
148
149 return SCIP_OKAY;
150 }
151
152
153 /** solving process deinitialization method of separator (called before branch and bound process data is freed) */
154 static
SCIP_DECL_SEPAEXITSOL(sepaExitsolObj)155 SCIP_DECL_SEPAEXITSOL(sepaExitsolObj)
156 { /*lint --e{715}*/
157 SCIP_SEPADATA* sepadata;
158
159 sepadata = SCIPsepaGetData(sepa);
160 assert(sepadata != NULL);
161 assert(sepadata->objsepa != NULL);
162
163 /* call virtual method of sepa object */
164 SCIP_CALL( sepadata->objsepa->scip_exitsol(scip, sepa) );
165
166 return SCIP_OKAY;
167 }
168
169
170 /** LP solution separation method of separator */
171 static
SCIP_DECL_SEPAEXECLP(sepaExeclpObj)172 SCIP_DECL_SEPAEXECLP(sepaExeclpObj)
173 { /*lint --e{715}*/
174 SCIP_SEPADATA* sepadata;
175
176 sepadata = SCIPsepaGetData(sepa);
177 assert(sepadata != NULL);
178 assert(sepadata->objsepa != NULL);
179
180 /* call virtual method of sepa object */
181 SCIP_CALL( sepadata->objsepa->scip_execlp(scip, sepa, result, allowlocal) );
182
183 return SCIP_OKAY;
184 }
185
186
187 /** arbitrary primal solution separation method of separator */
188 static
SCIP_DECL_SEPAEXECSOL(sepaExecsolObj)189 SCIP_DECL_SEPAEXECSOL(sepaExecsolObj)
190 { /*lint --e{715}*/
191 SCIP_SEPADATA* sepadata;
192
193 sepadata = SCIPsepaGetData(sepa);
194 assert(sepadata != NULL);
195 assert(sepadata->objsepa != NULL);
196
197 /* call virtual method of sepa object */
198 SCIP_CALL( sepadata->objsepa->scip_execsol(scip, sepa, sol, result, allowlocal) );
199
200 return SCIP_OKAY;
201 }
202 }
203
204
205
206 /*
207 * cut separator specific interface methods
208 */
209
210 /** creates the cut separator for the given cut separator object and includes it in SCIP */
SCIPincludeObjSepa(SCIP * scip,scip::ObjSepa * objsepa,SCIP_Bool deleteobject)211 SCIP_RETCODE SCIPincludeObjSepa(
212 SCIP* scip, /**< SCIP data structure */
213 scip::ObjSepa* objsepa, /**< cut separator object */
214 SCIP_Bool deleteobject /**< should the cut separator object be deleted when cut separator is freed? */
215 )
216 {
217 SCIP_SEPADATA* sepadata;
218
219 assert(scip != NULL);
220 assert(objsepa != NULL);
221
222 /* create cut separator data */
223 sepadata = new SCIP_SEPADATA;
224 sepadata->objsepa = objsepa;
225 sepadata->deleteobject = deleteobject;
226
227 /* include cut separator */
228 SCIP_CALL( SCIPincludeSepa(scip, objsepa->scip_name_, objsepa->scip_desc_, objsepa->scip_priority_,
229 objsepa->scip_freq_, objsepa->scip_maxbounddist_, objsepa->scip_usessubscip_, objsepa->scip_delay_,
230 sepaCopyObj, sepaFreeObj, sepaInitObj, sepaExitObj, sepaInitsolObj, sepaExitsolObj,
231 sepaExeclpObj, sepaExecsolObj,
232 sepadata) ); /*lint !e429*/
233
234 return SCIP_OKAY; /*lint !e429*/
235 }
236
237 /** returns the sepa object of the given name, or 0 if not existing */
SCIPfindObjSepa(SCIP * scip,const char * name)238 scip::ObjSepa* SCIPfindObjSepa(
239 SCIP* scip, /**< SCIP data structure */
240 const char* name /**< name of cut separator */
241 )
242 {
243 SCIP_SEPA* sepa;
244 SCIP_SEPADATA* sepadata;
245
246 sepa = SCIPfindSepa(scip, name);
247 if( sepa == NULL )
248 return 0;
249
250 sepadata = SCIPsepaGetData(sepa);
251 assert(sepadata != NULL);
252
253 return sepadata->objsepa;
254 }
255
256 /** returns the sepa object for the given cut separator */
SCIPgetObjSepa(SCIP * scip,SCIP_SEPA * sepa)257 scip::ObjSepa* SCIPgetObjSepa(
258 SCIP* scip, /**< SCIP data structure */
259 SCIP_SEPA* sepa /**< cut separator */
260 )
261 {
262 SCIP_SEPADATA* sepadata;
263
264 assert(scip != NULL);
265 sepadata = SCIPsepaGetData(sepa);
266 assert(sepadata != NULL);
267
268 return sepadata->objsepa;
269 }
270