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 objbranchrule.cpp
17 * @brief C++ wrapper for branching rules
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 "objbranchrule.h"
26
27
28
29
30 /*
31 * Data structures
32 */
33
34 /** branching rule data */
35 struct SCIP_BranchruleData
36 {
37 scip::ObjBranchrule* objbranchrule; /**< branching rule object */
38 SCIP_Bool deleteobject; /**< should the branching rule object be deleted when branching rule is freed? */
39 };
40
41
42
43
44 /*
45 * Callback methods of branching rule
46 */
47
48 extern "C"
49 {
50
51 /** copy method for branchrule plugins (called when SCIP copies plugins) */
52 static
53 SCIP_DECL_BRANCHCOPY(branchCopyObj)
54 { /*lint --e{715}*/
55 SCIP_BRANCHRULEDATA* branchruledata;
56
57 assert(scip != NULL);
58
59 branchruledata = SCIPbranchruleGetData(branchrule);
60 assert(branchruledata != NULL);
61 assert(branchruledata->objbranchrule != NULL);
62 assert(branchruledata->objbranchrule->scip_ != scip);
63
64 if( branchruledata->objbranchrule->iscloneable() )
65 {
66 scip::ObjBranchrule* newobjbranchrule;
67 newobjbranchrule = dynamic_cast<scip::ObjBranchrule*> (branchruledata->objbranchrule->clone(scip));
68
69 /* call include method of branchrule object */
70 SCIP_CALL( SCIPincludeObjBranchrule(scip, newobjbranchrule, TRUE) );
71 }
72
73 return SCIP_OKAY;
74 }
75
76 /** destructor of branching rule to free user data (called when SCIP is exiting) */
77 static
78 SCIP_DECL_BRANCHFREE(branchFreeObj)
79 { /*lint --e{715}*/
80 SCIP_BRANCHRULEDATA* branchruledata;
81
82 branchruledata = SCIPbranchruleGetData(branchrule);
83 assert(branchruledata != NULL);
84 assert(branchruledata->objbranchrule != NULL);
85 assert(branchruledata->objbranchrule->scip_ == scip);
86
87 /* call virtual method of branchrule object */
88 SCIP_CALL( branchruledata->objbranchrule->scip_free(scip, branchrule) );
89
90 /* free branchrule object */
91 if( branchruledata->deleteobject )
92 delete branchruledata->objbranchrule;
93
94 /* free branchrule data */
95 delete branchruledata;
96 SCIPbranchruleSetData(branchrule, NULL); /*lint !e64*/
97
98 return SCIP_OKAY;
99 }
100
101
102 /** initialization method of branching rule (called after problem was transformed) */
103 static
104 SCIP_DECL_BRANCHINIT(branchInitObj)
105 { /*lint --e{715}*/
106 SCIP_BRANCHRULEDATA* branchruledata;
107
108 branchruledata = SCIPbranchruleGetData(branchrule);
109 assert(branchruledata != NULL);
110 assert(branchruledata->objbranchrule != NULL);
111 assert(branchruledata->objbranchrule->scip_ == scip);
112
113 /* call virtual method of branchrule object */
114 SCIP_CALL( branchruledata->objbranchrule->scip_init(scip, branchrule) );
115
116 return SCIP_OKAY;
117 }
118
119
120 /** deinitialization method of branching rule (called before transformed problem is freed) */
121 static
122 SCIP_DECL_BRANCHEXIT(branchExitObj)
123 { /*lint --e{715}*/
124 SCIP_BRANCHRULEDATA* branchruledata;
125
126 branchruledata = SCIPbranchruleGetData(branchrule);
127 assert(branchruledata != NULL);
128 assert(branchruledata->objbranchrule != NULL);
129
130 /* call virtual method of branchrule object */
131 SCIP_CALL( branchruledata->objbranchrule->scip_exit(scip, branchrule) );
132
133 return SCIP_OKAY;
134 }
135
136
137 /** solving process initialization method of branching rule (called when branch and bound process is about to begin) */
138 static
139 SCIP_DECL_BRANCHINITSOL(branchInitsolObj)
140 { /*lint --e{715}*/
141 SCIP_BRANCHRULEDATA* branchruledata;
142
143 branchruledata = SCIPbranchruleGetData(branchrule);
144 assert(branchruledata != NULL);
145 assert(branchruledata->objbranchrule != NULL);
146
147 /* call virtual method of branchrule object */
148 SCIP_CALL( branchruledata->objbranchrule->scip_initsol(scip, branchrule) );
149
150 return SCIP_OKAY;
151 }
152
153
154 /** solving process deinitialization method of branching rule (called before branch and bound process data is freed) */
155 static
156 SCIP_DECL_BRANCHEXITSOL(branchExitsolObj)
157 { /*lint --e{715}*/
158 SCIP_BRANCHRULEDATA* branchruledata;
159
160 branchruledata = SCIPbranchruleGetData(branchrule);
161 assert(branchruledata != NULL);
162 assert(branchruledata->objbranchrule != NULL);
163
164 /* call virtual method of branchrule object */
165 SCIP_CALL( branchruledata->objbranchrule->scip_exitsol(scip, branchrule) );
166
167 return SCIP_OKAY;
168 }
169
170
171 /** branching execution method for fractional LP solutions */
172 static
173 SCIP_DECL_BRANCHEXECLP(branchExeclpObj)
174 { /*lint --e{715}*/
175 SCIP_BRANCHRULEDATA* branchruledata;
176
177 branchruledata = SCIPbranchruleGetData(branchrule);
178 assert(branchruledata != NULL);
179 assert(branchruledata->objbranchrule != NULL);
180
181 /* call virtual method of branchrule object */
182 SCIP_CALL( branchruledata->objbranchrule->scip_execlp(scip, branchrule, allowaddcons, result) );
183
184 return SCIP_OKAY;
185 }
186
187
188 /** branching execution method for external candidates */
189 static
190 SCIP_DECL_BRANCHEXECEXT(branchExecextObj)
191 { /*lint --e{715}*/
192 SCIP_BRANCHRULEDATA* branchruledata;
193
194 branchruledata = SCIPbranchruleGetData(branchrule);
195 assert(branchruledata != NULL);
196 assert(branchruledata->objbranchrule != NULL);
197
198 /* call virtual method of branchrule object */
199 SCIP_CALL( branchruledata->objbranchrule->scip_execext(scip, branchrule, allowaddcons, result) );
200
201 return SCIP_OKAY;
202 }
203
204
205 /** branching execution method for not completely fixed pseudo solutions */
206 static
207 SCIP_DECL_BRANCHEXECPS(branchExecpsObj)
208 { /*lint --e{715}*/
209 SCIP_BRANCHRULEDATA* branchruledata;
210
211 branchruledata = SCIPbranchruleGetData(branchrule);
212 assert(branchruledata != NULL);
213 assert(branchruledata->objbranchrule != NULL);
214
215 /* call virtual method of branchrule object */
216 SCIP_CALL( branchruledata->objbranchrule->scip_execps(scip, branchrule, allowaddcons, result) );
217
218 return SCIP_OKAY;
219 }
220 }
221
222
223
224 /*
225 * branching rule specific interface methods
226 */
227
228 /** creates the branching rule for the given branching rule object and includes it in SCIP */
229 SCIP_RETCODE SCIPincludeObjBranchrule(
230 SCIP* scip, /**< SCIP data structure */
231 scip::ObjBranchrule* objbranchrule, /**< branching rule object */
232 SCIP_Bool deleteobject /**< should the branching rule object be deleted when branching rule is freed? */
233 )
234 {
235 SCIP_BRANCHRULEDATA* branchruledata;
236
237 assert(scip != NULL);
238 assert(objbranchrule != NULL);
239
240 /* create branching rule data */
241 branchruledata = new SCIP_BRANCHRULEDATA;
242 branchruledata->objbranchrule = objbranchrule;
243 branchruledata->deleteobject = deleteobject;
244
245 /* include branching rule */
246 SCIP_CALL( SCIPincludeBranchrule(scip, objbranchrule->scip_name_, objbranchrule->scip_desc_,
247 objbranchrule->scip_priority_, objbranchrule->scip_maxdepth_, objbranchrule->scip_maxbounddist_,
248 branchCopyObj,
249 branchFreeObj, branchInitObj, branchExitObj, branchInitsolObj, branchExitsolObj,
250 branchExeclpObj, branchExecextObj, branchExecpsObj,
251 branchruledata) ); /*lint !e429*/
252
253 return SCIP_OKAY; /*lint !e429*/
254 }
255
256
257 /** returns the branchrule object of the given name, or 0 if not existing */
258 scip::ObjBranchrule* SCIPfindObjBranchrule(
259 SCIP* scip, /**< SCIP data structure */
260 const char* name /**< name of branching rule */
261 )
262 {
263 SCIP_BRANCHRULE* branchrule;
264 SCIP_BRANCHRULEDATA* branchruledata;
265
266 branchrule = SCIPfindBranchrule(scip, name);
267 if( branchrule == NULL )
268 return 0;
269
270 branchruledata = SCIPbranchruleGetData(branchrule);
271 assert(branchruledata != NULL);
272
273 return branchruledata->objbranchrule;
274 }
275
276 /** returns the branchrule object for the given branching rule */
277 scip::ObjBranchrule* SCIPgetObjBranchrule(
278 SCIP* scip, /**< SCIP data structure */
279 SCIP_BRANCHRULE* branchrule /**< branching rule */
280 )
281 {
282 SCIP_BRANCHRULEDATA* branchruledata;
283
284 assert(scip != NULL);
285 branchruledata = SCIPbranchruleGetData(branchrule);
286 assert(branchruledata != NULL);
287
288 return branchruledata->objbranchrule;
289 }
290