Scippy

SCIP

Solving Constraint Integer Programs

branch_nodereopt.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2015 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 email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file branch_nodereopt.c
17  * @brief branching rule to reconstruct the search tree
18  * @author Jakob Witzig
19  */
20 
21 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
22 #include <assert.h>
23 #include <string.h>
24 
25 #include "scip/branch_nodereopt.h"
26 #include "scip/branch_relpscost.h"
27 #include "scip/cons_logicor.h"
28 #include "scip/scip.h"
29 #include "scip/tree.h"
30 #include "scip/pub_reopt.h"
31 
32 #define BRANCHRULE_NAME "nodereopt"
33 #define BRANCHRULE_DESC "branching rule for node reoptimization"
34 #define BRANCHRULE_PRIORITY -9000000
35 #define BRANCHRULE_MAXDEPTH -1
36 #define BRANCHRULE_MAXBOUNDDIST 1.0
37 
38 /*
39  * Data structures
40  */
41 
42 
43 /** Execute the branching of nodes with additional constraints. */
44 static
46  SCIP* scip, /**< SCIP data structure */
47  SCIP_RESULT* result /**< pointer to store the result */
48 )
49 {
50  SCIP_REOPTNODE* reoptnode;
51  SCIP_NODE* curnode;
52  SCIP_REOPTTYPE reopttype;
53  SCIP_Bool localrestart;
54  unsigned int* childids;
55  unsigned int curid;
56  int naddedconss;
57  int nchilds;
58  int childnodessize;
59  int ncreatednodes;
60  int c;
61 
62 
63  assert(scip != NULL );
64  assert(SCIPisReoptEnabled(scip));
65 
66  curnode = SCIPgetCurrentNode(scip);
67  assert(curnode != NULL);
68 
69  curid = SCIPnodeGetReoptID(curnode);
70  assert(curid >= 1 || SCIPgetRootNode(scip) == curnode);
71 
72  /* calculate local similarity and delete the induced subtree if the similarity is to low */
73  localrestart = FALSE;
74  SCIP_CALL( SCIPcheckReoptRestart(scip, curnode, &localrestart) );
75 
76  ncreatednodes = 0;
77 
78  if( localrestart )
79  {
80  *result = SCIP_DIDNOTRUN;
81  goto TERMINATE;
82  }
83 
84  SCIPdebugMessage("current node is %lld, ID %u:\n", SCIPnodeGetNumber(curnode), curid);
85 
86  /* get the corresponding node of the reoptimization tree */
87  reoptnode = SCIPgetReoptnode(scip, curid);
88  assert(reoptnode != NULL);
89  reopttype = (SCIP_REOPTTYPE)SCIPreoptnodeGetType(reoptnode);
90 
91 
92  /* The current node is equal to the root and dual reductions were performed. Since the root has a special role
93  * within the reoptimiziation we have to split the root node into several nodes and move all stored child nodes to
94  * the one representing the root node including all dual reductions as before.
95  *
96  * @note If the type is infsubtree, there cannot exist a child node and the method SCIPapplyReopt adds a global valid
97  * constraint only.
98  */
99  if( curid == 0 )
100  {
101  if( reopttype == SCIP_REOPTTYPE_STRBRANCHED || reopttype == SCIP_REOPTTYPE_INFSUBTREE )
102  {
103  int ncreatedchilds;
104 
105  /* apply the reoptimization at the root node */
106  SCIP_CALL( SCIPsplitReoptRoot(scip, &ncreatedchilds, &naddedconss) );
107 
108  if( reopttype == SCIP_REOPTTYPE_INFSUBTREE )
109  {
110  assert(ncreatedchilds == 0);
111  assert(naddedconss == 1);
112 
113  /* there is nothing to do */
114  *result = SCIP_DIDNOTRUN;
115 
116  goto TERMINATE;
117  }
118 
119  assert(reopttype == SCIP_REOPTTYPE_STRBRANCHED);
120  assert(ncreatedchilds >= 2);
121 
122  ncreatednodes += ncreatedchilds;
123 
124  /* We decrease the counter by one because after splitting the root node and moving all children to the node
125  * representing the original root with all fixings (caused by dual reductions), we continue reactivating the
126  * original children nodes of the root. Thus, the node containing all the fixings can be replaced by the children
127  * nodes
128  */
129  --ncreatednodes;
130  }
131 
132  goto REVIVE;
133  }
134 
135  /* if we reach this part of the code the current has to be different to the root node */
136  assert(curid >= 1);
137 
138  REVIVE:
139 
140  /* get the IDs of all child nodes */
141  childnodessize = SCIPreoptnodeGetNChildren(reoptnode);
142  SCIP_CALL( SCIPallocBufferArray(scip, &childids, childnodessize) );
143  SCIP_CALL( SCIPgetReoptChildIDs(scip, curnode, childids, childnodessize, &nchilds) );
144 
145  if( childnodessize < nchilds )
146  {
147  childnodessize = SCIPreoptnodeGetNChildren(reoptnode);
148  SCIP_CALL( SCIPreallocBufferArray(scip, &childids, childnodessize) );
149  SCIP_CALL( SCIPgetReoptChildIDs(scip, curnode, childids, childnodessize, &nchilds) );
150  }
151  assert(nchilds <= childnodessize);
152 
153  naddedconss = 0;
154 
155  for(c = 0; c < nchilds; c++)
156  {
157  SCIP_NODE** childnodes;
158  SCIP_Bool success;
159  unsigned int childid;
160  int ncreatedchilds;
161 
162  childid = childids[c];
163  assert(childid >= 1);
164 
165  SCIPdebugMessage("process child at ID %u\n", childid);
166 
167  reoptnode = SCIPgetReoptnode(scip, childid);
168  assert(reoptnode != NULL);
169 
170  reopttype = (SCIP_REOPTTYPE)SCIPreoptnodeGetType(reoptnode);
171  ncreatedchilds = 0;
172 
173  /* check whether node need to be split */
174  if( reopttype == SCIP_REOPTTYPE_STRBRANCHED || reopttype == SCIP_REOPTTYPE_INFSUBTREE )
175  {
176  /* by default we assume the node get split into two node (because using a constraint to split the node is
177  * the default case
178  */
179  childnodessize = 2;
180  }
181  else
182  {
183  /* we only need to reconstruct the node */
184  childnodessize = 1;
185  }
186 
187  /* allocate buffer */
188  SCIP_CALL( SCIPallocBufferArray(scip, &childnodes, childnodessize) );
189 
190  /* apply the reoptimization */
191  SCIP_CALL( SCIPapplyReopt(scip, reoptnode, childid, SCIPnodeGetEstimate(curnode), childnodes, &ncreatedchilds,
192  &naddedconss, childnodessize, &success) );
193 
194  if( !success )
195  {
196  assert(ncreatedchilds > childnodessize);
197 
198  /* reallocate buffer memory */
199  childnodessize = ncreatedchilds+1;
200  SCIP_CALL( SCIPreallocBufferArray(scip, &childnodes, childnodessize) );
201 
202  /* apply the reoptimization */
203  SCIP_CALL( SCIPapplyReopt(scip, reoptnode, childid, SCIPnodeGetEstimate(curnode), childnodes, &ncreatedchilds,
204  &naddedconss, childnodessize, &success) );
205  }
206 
207  assert(success);
208 
209  /* free buffer memory */
210  SCIPfreeBufferArray(scip, &childnodes);
211 
212  ncreatednodes += ncreatedchilds;
213  }
214 
215  if( ncreatednodes == 0 )
216  *result = SCIP_DIDNOTRUN;
217  else
218  *result = SCIP_BRANCHED;
219 
220  /* free the buffer memory */
221  SCIPfreeBufferArray(scip, &childids);
222 
223  TERMINATE:
224 
225  SCIPdebugMessage("**** finish reoptimizing %d child nodes of node %lld ****\n", ncreatednodes, SCIPnodeGetNumber(curnode));
226 
227  return SCIP_OKAY;
228 }
229 
230 /*
231  * Callback methods of branching rule
232  */
233 
234 /** branching execution method for fractional LP solutions */
235 static
236 SCIP_DECL_BRANCHEXECLP(branchExeclpnodereopt)
237 {/*lint --e{715}*/
238  assert(branchrule != NULL );
239  assert(*result != SCIP_BRANCHED);
240 
241  *result = SCIP_DIDNOTRUN;
242 
243  if( SCIPisReoptEnabled(scip) && SCIPreoptimizeNode(scip, SCIPgetCurrentNode(scip)) )
244  {
245  SCIP_VAR** branchcands;
246  SCIP_Real* branchcandssol;
247  SCIP_Real* branchcandsfrac;
248  int nbranchcands;
249 
250  SCIP_Bool sbinit;
251  SCIP_Real objsimrootlp;
252 
253  SCIP_CALL( SCIPgetBoolParam(scip, "reoptimization/strongbranchinginit", &sbinit) );
254  SCIP_CALL( SCIPgetRealParam(scip, "reoptimization/objsimrootLP", &objsimrootlp) );
255 
256  if( sbinit && SCIPgetCurrentNode(scip) == SCIPgetRootNode(scip)
257  && SCIPgetReoptSimilarity(scip, SCIPgetNReoptRuns(scip), SCIPgetNReoptRuns(scip)) <= objsimrootlp ) /* check objsimrootlp */
258  {
259  /* get branching candidates */
260  SCIP_CALL( SCIPgetLPBranchCands(scip, &branchcands, &branchcandssol, &branchcandsfrac, NULL, &nbranchcands, NULL) );
261 
262  /* run strong branching initialization */
263  if( nbranchcands > 0 )
264  {
265  SCIP_CALL( SCIPexecRelpscostBranching(scip, TRUE, branchcands, branchcandssol, branchcandsfrac, nbranchcands, FALSE, result) );
266  assert(*result == SCIP_DIDNOTRUN || *result == SCIP_CUTOFF || *result == SCIP_REDUCEDDOM);
267  }
268  }
269 
270  if( *result != SCIP_CUTOFF && *result != SCIP_REDUCEDDOM)
271  {
272  assert((SCIPnodeGetReoptID(SCIPgetCurrentNode(scip)) == 0 && SCIPnodeGetDepth(SCIPgetCurrentNode(scip)) == 0 )
273  || 1 <= SCIPnodeGetReoptID(SCIPgetCurrentNode(scip)));
274 
275  SCIP_CALL( Exec(scip, result) );
276  }
277  }
278 
279  return SCIP_OKAY;
280 }
281 
282 /** branching execution method for external candidates */
283 static SCIP_DECL_BRANCHEXECEXT(branchExecextnodereopt)
284 {/*lint --e{715}*/
285  assert(branchrule != NULL );
286  assert(*result != SCIP_BRANCHED);
287 
288  *result = SCIP_DIDNOTRUN;
289 
290  if ( SCIPisReoptEnabled(scip) && SCIPreoptimizeNode(scip, SCIPgetCurrentNode(scip)) )
291  {
292  assert((SCIPnodeGetReoptID(SCIPgetCurrentNode(scip)) == 0 && SCIPnodeGetDepth(SCIPgetCurrentNode(scip)) == 0 )
293  || 1 <= SCIPnodeGetReoptID(SCIPgetCurrentNode(scip)));
294 
295  SCIP_CALL( Exec(scip, result) );
296  }
297 
298  return SCIP_OKAY;
299 }
300 
301 /** branching execution method for not completely fixed pseudo solutions */
302 static SCIP_DECL_BRANCHEXECPS(branchExecpsnodereopt)
303 {/*lint --e{715}*/
304  assert(branchrule != NULL );
305  assert(*result != SCIP_BRANCHED);
306 
307  *result = SCIP_DIDNOTRUN;
308 
309  if( SCIPisReoptEnabled(scip) && SCIPreoptimizeNode(scip, SCIPgetCurrentNode(scip)) )
310  {
311  assert((SCIPnodeGetReoptID(SCIPgetCurrentNode(scip)) == 0 && SCIPnodeGetDepth(SCIPgetCurrentNode(scip)) == 0 )
312  || 1 <= SCIPnodeGetReoptID(SCIPgetCurrentNode(scip)));
313 
314  SCIP_CALL( Exec(scip, result) );
315  }
316 
317  return SCIP_OKAY;
318 }
319 
320 /*
321  * branching rule specific interface methods
322  */
323 
324 /** creates the nodereopt branching rule and includes it in SCIP */
326  SCIP* scip /**< SCIP data structure */
327 )
328 {
329  SCIP_BRANCHRULE* branchrule;
330  SCIP_BRANCHRULEDATA* branchruledata;
331 
332  assert(scip != NULL );
333 
334  /* no branching rule data */
335  branchruledata = NULL;
336 
337  /* include nodereopt branching rule */
340 
341  assert(branchrule != NULL );
342 
343  /* set non fundamental callbacks via setter functions */
344  SCIP_CALL(SCIPsetBranchruleExecLp(scip, branchrule, branchExeclpnodereopt));
345  SCIP_CALL(SCIPsetBranchruleExecExt(scip, branchrule, branchExecextnodereopt));
346  SCIP_CALL(SCIPsetBranchruleExecPs(scip, branchrule, branchExecpsnodereopt));
347 
348  return SCIP_OKAY;
349 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:51
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
Definition: scip.c:32735
reliable pseudo costs branching rule
SCIP_RETCODE SCIPgetReoptChildIDs(SCIP *scip, SCIP_NODE *node, unsigned int *ids, int idssize, int *nids)
Definition: scip.c:15042
unsigned int SCIPnodeGetReoptID(SCIP_NODE *node)
Definition: tree.c:7087
internal methods for branch and bound tree
static SCIP_RETCODE Exec(SCIP *scip, SCIP_RESULT *result)
#define BRANCHRULE_MAXDEPTH
SCIP_REOPTNODE * SCIPgetReoptnode(SCIP *scip, unsigned int id)
Definition: scip.c:15127
#define NULL
Definition: lpi_spx.cpp:130
struct SCIP_BranchruleData SCIP_BRANCHRULEDATA
Definition: type_branch.h:43
int SCIPnodeGetDepth(SCIP_NODE *node)
Definition: tree.c:7026
SCIP_RETCODE SCIPsplitReoptRoot(SCIP *scip, int *ncreatedchilds, int *naddedconss)
Definition: scip.c:15728
#define FALSE
Definition: def.h:53
#define TRUE
Definition: def.h:52
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_RETCODE SCIPexecRelpscostBranching(SCIP *scip, SCIP_Bool allowaddcons, SCIP_VAR **branchcands, SCIP_Real *branchcandssol, SCIP_Real *branchcandsfrac, int nbranchcands, SCIP_Bool executebranching, SCIP_RESULT *result)
#define BRANCHRULE_DESC
public methods for reoptimization
#define SCIPdebugMessage
Definition: pub_message.h:77
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:20414
nodereopt branching rule
SCIP_RETCODE SCIPsetBranchruleExecPs(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHEXECPS((*branchexecps)))
Definition: scip.c:8389
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip.h:20418
SCIP_Longint SCIPnodeGetNumber(SCIP_NODE *node)
Definition: tree.c:7016
SCIP_RETCODE SCIPsetBranchruleExecLp(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHEXECLP((*branchexeclp)))
Definition: scip.c:8357
SCIP_RETCODE SCIPincludeBranchruleBasic(SCIP *scip, SCIP_BRANCHRULE **branchruleptr, const char *name, const char *desc, int priority, int maxdepth, SCIP_Real maxbounddist, SCIP_BRANCHRULEDATA *branchruledata)
Definition: scip.c:8222
SCIP_NODE * SCIPgetRootNode(SCIP *scip)
Definition: scip.c:36408
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:20426
SCIP_RETCODE SCIPcheckReoptRestart(SCIP *scip, SCIP_NODE *node, SCIP_Bool *restart)
Definition: scip.c:15627
Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
enum SCIP_ReoptType SCIP_REOPTTYPE
Definition: type_reopt.h:56
#define SCIP_CALL(x)
Definition: def.h:263
int SCIPgetNReoptRuns(SCIP *scip)
Definition: scip.c:36955
int SCIPreoptnodeGetNChildren(SCIP_REOPTNODE *reoptnode)
Definition: reopt.c:4716
#define SCIP_Bool
Definition: def.h:50
SCIP_RETCODE SCIPsetBranchruleExecExt(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHEXECEXT((*branchexecext)))
Definition: scip.c:8373
static SCIP_DECL_BRANCHEXECPS(branchExecpsnodereopt)
#define BRANCHRULE_PRIORITY
#define BRANCHRULE_MAXBOUNDDIST
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition: scip.c:36389
SCIP_Real SCIPnodeGetEstimate(SCIP_NODE *node)
Definition: tree.c:7046
static SCIP_DECL_BRANCHEXECEXT(branchExecextnodereopt)
SCIP_RETCODE SCIPapplyReopt(SCIP *scip, SCIP_REOPTNODE *reoptnode, unsigned int id, SCIP_Real estimate, SCIP_NODE **childnodes, int *ncreatedchilds, int *naddedconss, int childnodessize, SCIP_Bool *success)
Definition: scip.c:15347
#define SCIP_Real
Definition: def.h:124
#define BRANCHRULE_NAME
SCIP_Real SCIPgetReoptSimilarity(SCIP *scip, int run1, int run2)
Definition: scip.c:15646
static SCIP_DECL_BRANCHEXECLP(branchExeclpnodereopt)
SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
Definition: scip.c:3766
SCIP_RETCODE SCIPincludeBranchruleNodereopt(SCIP *scip)
SCIP_REOPTTYPE SCIPreoptnodeGetType(SCIP_REOPTNODE *reoptnode)
Definition: reopt.c:4736
SCIP_Bool SCIPreoptimizeNode(SCIP *scip, SCIP_NODE *node)
Definition: scip.c:15663
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip.c:3709
SCIP_Bool SCIPisReoptEnabled(SCIP *scip)
Definition: scip.c:15567
SCIP callable library.