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  	
(2) Event example_assign: Example 1: Assigning: "branchrule" = return value from "SCIPfindBranchrule(scip, name)".
Also see events: [returned_null][example_checked][example_checked][example_checked][example_checked][example_checked][var_assigned][dereference]
266  	   branchrule = SCIPfindBranchrule(scip, name);
(3) Event example_checked: Example 1 (cont.): "branchrule" has its value checked in "branchrule == NULL".
Also see events: [returned_null][example_assign][example_checked][example_checked][example_checked][example_checked][var_assigned][dereference]
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