SCIP Doxygen Documentation
Loading...
Searching...
No Matches
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-2026 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 branch_nodereopt.c
26 * @ingroup DEFPLUGINS_BRANCH
27 * @brief branching rule to reconstruct the search tree
28 * @author Jakob Witzig
29 */
30
31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
32
35#include "scip/scip.h"
36#include "scip/tree.h"
37#include "scip/pub_reopt.h"
38
39#define BRANCHRULE_NAME "nodereopt"
40#define BRANCHRULE_DESC "branching rule for node reoptimization"
41#define BRANCHRULE_PRIORITY -9000000
42#define BRANCHRULE_MAXDEPTH -1
43#define BRANCHRULE_MAXBOUNDDIST 1.0
44
45/*
46 * Data structures
47 */
48
49
50/** execute the branching of nodes with additional constraints */
51static
53 SCIP* scip, /**< SCIP data structure */
54 SCIP_RESULT* result /**< pointer to store the result */
55 )
56{
57 SCIP_REOPTNODE* reoptnode;
58 SCIP_NODE* curnode;
59 SCIP_REOPTTYPE reopttype;
60 SCIP_Bool localrestart;
61 unsigned int* childids;
62 unsigned int curid;
63 int naddedconss;
64 int nchilds;
65 int childnodessize;
66 int ncreatednodes;
67 int c;
68
69 assert(scip != NULL );
71
72 curnode = SCIPgetCurrentNode(scip);
73 assert(curnode != NULL);
74
75 curid = SCIPnodeGetReoptID(curnode);
76 assert(curid >= 1 || SCIPgetRootNode(scip) == curnode);
77
78 /* calculate local similarity and delete the induced subtree if the similarity is to low */
79 localrestart = FALSE;
80 SCIP_CALL( SCIPcheckReoptRestart(scip, curnode, &localrestart) );
81
82 ncreatednodes = 0;
83
84 if( localrestart )
85 {
87 goto TERMINATE;
88 }
89
90 SCIPdebugMsg(scip, "current node is %lld, ID %u:\n", SCIPnodeGetNumber(curnode), curid);
91
92 /* get the corresponding node of the reoptimization tree */
93 reoptnode = SCIPgetReoptnode(scip, curid);
94 assert(reoptnode != NULL);
95 reopttype = (SCIP_REOPTTYPE)SCIPreoptnodeGetType(reoptnode);
96
97 /* The current node is equal to the root and dual reductions were performed. Since the root has a special role
98 * within the reoptimiziation we have to split the root node into several nodes and move all stored child nodes to
99 * the one representing the root node including all dual reductions as before.
100 *
101 * @note If the type is infsubtree, there cannot exist a child node and the method SCIPapplyReopt adds a global valid
102 * constraint only.
103 */
104 if( curid == 0 )
105 {
106 if( reopttype == SCIP_REOPTTYPE_STRBRANCHED || reopttype == SCIP_REOPTTYPE_INFSUBTREE )
107 {
108 int ncreatedchilds;
109
110 /* apply the reoptimization at the root node */
111 SCIP_CALL( SCIPsplitReoptRoot(scip, &ncreatedchilds, &naddedconss) );
112
113 if( reopttype == SCIP_REOPTTYPE_INFSUBTREE )
114 {
115 assert(ncreatedchilds == 0);
116 assert(naddedconss == 1);
117
118 /* there is nothing to do */
120
121 goto TERMINATE;
122 }
123
125 assert(ncreatedchilds >= 2);
126
127 ncreatednodes += ncreatedchilds;
128
129 /* We decrease the counter by one because after splitting the root node and moving all children to the node
130 * representing the original root with all fixings (caused by dual reductions), we continue reactivating the
131 * original children nodes of the root. Thus, the node containing all the fixings can be replaced by the children
132 * nodes
133 */
134 --ncreatednodes;
135 }
136
137 goto REVIVE;
138 }
139
140 /* if we reach this part of the code the current has to be different to the root node */
141 assert(curid >= 1);
142
143 REVIVE:
144
145 /* get the IDs of all child nodes */
146 childnodessize = SCIPreoptnodeGetNChildren(reoptnode);
147 SCIP_CALL( SCIPallocBufferArray(scip, &childids, childnodessize) );
148 SCIP_CALL( SCIPgetReoptChildIDs(scip, curnode, childids, childnodessize, &nchilds) );
149
150 if( childnodessize < nchilds )
151 {
152 childnodessize = SCIPreoptnodeGetNChildren(reoptnode);
153 SCIP_CALL( SCIPreallocBufferArray(scip, &childids, childnodessize) );
154 SCIP_CALL( SCIPgetReoptChildIDs(scip, curnode, childids, childnodessize, &nchilds) );
155 }
156 assert(nchilds <= childnodessize);
157
158 naddedconss = 0;
159
160 for(c = 0; c < nchilds; c++)
161 {
162 SCIP_NODE** childnodes;
163 SCIP_Bool success;
164 unsigned int childid;
165 int ncreatedchilds;
166
167 childid = childids[c];
168 assert(childid >= 1);
169
170 SCIPdebugMsg(scip, "process child at ID %u\n", childid);
171
172 reoptnode = SCIPgetReoptnode(scip, childid);
173 assert(reoptnode != NULL);
174
175 reopttype = (SCIP_REOPTTYPE)SCIPreoptnodeGetType(reoptnode);
176 ncreatedchilds = 0;
177
178 /* check whether node need to be split */
179 if( reopttype == SCIP_REOPTTYPE_STRBRANCHED || reopttype == SCIP_REOPTTYPE_INFSUBTREE )
180 {
181 /* by default we assume the node get split into two node (because using a constraint to split the node is
182 * the default case */
183 childnodessize = 2;
184 }
185 else
186 {
187 /* we only need to reconstruct the node */
188 childnodessize = 1;
189 }
190
191 /* allocate buffer */
192 SCIP_CALL( SCIPallocBufferArray(scip, &childnodes, childnodessize) );
193
194 /* apply the reoptimization */
195 SCIP_CALL( SCIPapplyReopt(scip, reoptnode, childid, SCIPnodeGetEstimate(curnode), childnodes, &ncreatedchilds,
196 &naddedconss, childnodessize, &success) );
197
198 if( !success )
199 {
200 assert(ncreatedchilds > childnodessize);
201
202 /* reallocate buffer memory */
203 childnodessize = ncreatedchilds+1;
204 SCIP_CALL( SCIPreallocBufferArray(scip, &childnodes, childnodessize) );
205
206 /* apply the reoptimization */
207 SCIP_CALL( SCIPapplyReopt(scip, reoptnode, childid, SCIPnodeGetEstimate(curnode), childnodes, &ncreatedchilds,
208 &naddedconss, childnodessize, &success) );
209 }
210
211 assert(success);
212
213 /* free buffer memory */
214 SCIPfreeBufferArray(scip, &childnodes);
215
216 ncreatednodes += ncreatedchilds;
217 }
218
219 if( ncreatednodes == 0 )
221 else
223
224 /* free the buffer memory */
225 SCIPfreeBufferArray(scip, &childids);
226
227 TERMINATE:
228
229 SCIPdebugMsg(scip, "**** finish reoptimizing %d child nodes of node %lld ****\n", ncreatednodes, SCIPnodeGetNumber(curnode));
230
231 return SCIP_OKAY;
232}
233
234/*
235 * Callback methods of branching rule
236 */
237
238/** copy method for branchrule plugins (called when SCIP copies plugins) */
239static
240SCIP_DECL_BRANCHCOPY(branchCopyNodereopt)
241{ /*lint --e{715}*/
242 assert(scip != NULL);
243 assert(branchrule != NULL);
244
246
247 /* call inclusion method of branchrule */
249
250 return SCIP_OKAY;
251}
252
253/** branching execution method for fractional LP solutions */
254static
255SCIP_DECL_BRANCHEXECLP(branchExeclpNodereopt)
256{/*lint --e{715}*/
257 assert(branchrule != NULL );
259
261
263 {
264 SCIP_VAR** branchcands;
265 SCIP_Real* branchcandssol;
266 SCIP_Real* branchcandsfrac;
267 SCIP_Real objsimrootlp;
268 SCIP_Bool sbinit;
269 int nbranchcands;
270
272
273 SCIP_CALL( SCIPgetBoolParam(scip, "reoptimization/strongbranchinginit", &sbinit) );
274 SCIP_CALL( SCIPgetRealParam(scip, "reoptimization/objsimrootLP", &objsimrootlp) );
275
277 && SCIPgetReoptSimilarity(scip, SCIPgetNReoptRuns(scip)-1, SCIPgetNReoptRuns(scip)) <= objsimrootlp ) /* check objsimrootlp */
278 {
279 /* get branching candidates */
280 SCIP_CALL( SCIPgetLPBranchCands(scip, &branchcands, &branchcandssol, &branchcandsfrac, NULL, &nbranchcands, NULL) );
281
282 /* run strong branching initialization */
283 if( nbranchcands > 0 )
284 {
285 SCIP_CALL( SCIPexecRelpscostBranching(scip, branchcands, branchcandssol, branchcandsfrac, nbranchcands, FALSE, result) );
287 }
288 }
289
291 {
294
296 }
297 }
298
299 return SCIP_OKAY;
300}
301
302/** branching execution method for external candidates */
303static SCIP_DECL_BRANCHEXECEXT(branchExecextNodereopt)
304{/*lint --e{715}*/
305 assert(branchrule != NULL );
307
309
311 {
314
316 }
317
318 return SCIP_OKAY;
319}
320
321/** branching execution method for not completely fixed pseudo solutions */
322static SCIP_DECL_BRANCHEXECPS(branchExecpsNodereopt)
323{/*lint --e{715}*/
324 assert(branchrule != NULL );
326
328
330 {
333
335 }
336
337 return SCIP_OKAY;
338}
339
340/*
341 * branching rule specific interface methods
342 */
343
344/** creates the nodereopt branching rule and includes it in SCIP */
346 SCIP* scip /**< SCIP data structure */
347 )
348{
349 SCIP_BRANCHRULE* branchrule;
350
351 assert(scip != NULL );
352
353 /* include nodereopt branching rule */
356
357 assert(branchrule != NULL );
358
359 /* set non fundamental callbacks via setter functions */
360 SCIP_CALL( SCIPsetBranchruleCopy(scip, branchrule, branchCopyNodereopt) );
361 SCIP_CALL( SCIPsetBranchruleExecLp(scip, branchrule, branchExeclpNodereopt) );
362 SCIP_CALL( SCIPsetBranchruleExecExt(scip, branchrule, branchExecextNodereopt) );
363 SCIP_CALL( SCIPsetBranchruleExecPs(scip, branchrule, branchExecpsNodereopt) );
364
365 return SCIP_OKAY;
366}
#define BRANCHRULE_DESC
#define BRANCHRULE_PRIORITY
#define BRANCHRULE_NAME
#define BRANCHRULE_MAXDEPTH
#define BRANCHRULE_MAXBOUNDDIST
static SCIP_RETCODE Exec(SCIP *scip, SCIP_RESULT *result)
nodereopt branching rule
reliable pseudo costs branching rule
#define NULL
Definition def.h:257
#define SCIP_Bool
Definition def.h:100
#define SCIP_STRINGEQ(name, reference, retcode)
Definition def.h:454
#define SCIP_Real
Definition def.h:165
#define FALSE
Definition def.h:103
#define SCIP_CALL(x)
Definition def.h:364
SCIP_RETCODE SCIPexecRelpscostBranching(SCIP *scip, SCIP_VAR **branchcands, SCIP_Real *branchcandssol, SCIP_Real *branchcandsfrac, int nbranchcands, SCIP_Bool executebranching, SCIP_RESULT *result)
SCIP_RETCODE SCIPincludeBranchruleNodereopt(SCIP *scip)
#define SCIPdebugMsg
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition scip_param.c:250
SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
Definition scip_param.c:307
SCIP_RETCODE SCIPincludeBranchruleBasic(SCIP *scip, SCIP_BRANCHRULE **branchruleptr, const char *name, const char *desc, int priority, int maxdepth, SCIP_Real maxbounddist, SCIP_BRANCHRULEDATA *branchruledata)
const char * SCIPbranchruleGetName(SCIP_BRANCHRULE *branchrule)
Definition branch.c:2018
SCIP_RETCODE SCIPsetBranchruleExecExt(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
SCIP_RETCODE SCIPsetBranchruleCopy(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
SCIP_RETCODE SCIPsetBranchruleExecLp(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
SCIP_RETCODE SCIPsetBranchruleExecPs(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
#define SCIPallocBufferArray(scip, ptr, num)
Definition scip_mem.h:124
#define SCIPreallocBufferArray(scip, ptr, num)
Definition scip_mem.h:128
#define SCIPfreeBufferArray(scip, ptr)
Definition scip_mem.h:136
SCIP_Longint SCIPnodeGetNumber(SCIP_NODE *node)
Definition tree.c:8513
SCIP_Real SCIPnodeGetEstimate(SCIP_NODE *node)
Definition tree.c:8553
int SCIPnodeGetDepth(SCIP_NODE *node)
Definition tree.c:8523
unsigned int SCIPnodeGetReoptID(SCIP_NODE *node)
Definition tree.c:8594
SCIP_REOPTNODE * SCIPgetReoptnode(SCIP *scip, unsigned int id)
Definition scip_reopt.c:154
SCIP_Bool SCIPreoptimizeNode(SCIP *scip, SCIP_NODE *node)
Definition scip_reopt.c:424
SCIP_RETCODE SCIPcheckReoptRestart(SCIP *scip, SCIP_NODE *node, SCIP_Bool *restart)
SCIP_RETCODE SCIPgetReoptChildIDs(SCIP *scip, SCIP_NODE *node, unsigned int *ids, int idssize, int *nids)
Definition scip_reopt.c:69
SCIP_Bool SCIPisReoptEnabled(SCIP *scip)
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_reopt.c:382
SCIP_Real SCIPgetReoptSimilarity(SCIP *scip, int run1, int run2)
Definition scip_reopt.c:407
SCIP_RETCODE SCIPsplitReoptRoot(SCIP *scip, int *ncreatedchilds, int *naddedconss)
Definition scip_reopt.c:489
int SCIPgetNReoptRuns(SCIP *scip)
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition scip_tree.c:91
SCIP_NODE * SCIPgetRootNode(SCIP *scip)
Definition scip_tree.c:110
return SCIP_OKAY
int c
assert(minobj< SCIPgetCutoffbound(scip))
public methods for reoptimization
SCIP_REOPTTYPE SCIPreoptnodeGetType(SCIP_REOPTNODE *reoptnode)
Definition reopt.c:5838
int SCIPreoptnodeGetNChildren(SCIP_REOPTNODE *reoptnode)
Definition reopt.c:5818
SCIP callable library.
internal methods for branch and bound tree
#define SCIP_DECL_BRANCHEXECPS(x)
#define SCIP_DECL_BRANCHEXECLP(x)
#define SCIP_DECL_BRANCHEXECEXT(x)
#define SCIP_DECL_BRANCHCOPY(x)
Definition type_branch.h:67
struct SCIP_Branchrule SCIP_BRANCHRULE
Definition type_branch.h:56
@ SCIP_REOPTTYPE_INFSUBTREE
Definition type_reopt.h:60
@ SCIP_REOPTTYPE_STRBRANCHED
Definition type_reopt.h:61
enum SCIP_ReoptType SCIP_REOPTTYPE
Definition type_reopt.h:67
struct SCIP_ReoptNode SCIP_REOPTNODE
Definition type_reopt.h:47
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ SCIP_CUTOFF
Definition type_result.h:48
@ SCIP_REDUCEDDOM
Definition type_result.h:51
@ SCIP_CONSADDED
Definition type_result.h:52
@ SCIP_BRANCHED
Definition type_result.h:54
enum SCIP_Result SCIP_RESULT
Definition type_result.h:61
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
struct SCIP_Node SCIP_NODE
Definition type_tree.h:63
struct SCIP_Var SCIP_VAR
Definition type_var.h:166