SCIP Doxygen Documentation
Loading...
Searching...
No Matches
branch_random.c
Go to the documentation of this file.
1
2/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
3/* */
4/* This file is part of the program and library */
5/* SCIP --- Solving Constraint Integer Programs */
6/* */
7/* Copyright (c) 2002-2026 Zuse Institute Berlin (ZIB) */
8/* */
9/* Licensed under the Apache License, Version 2.0 (the "License"); */
10/* you may not use this file except in compliance with the License. */
11/* You may obtain a copy of the License at */
12/* */
13/* http://www.apache.org/licenses/LICENSE-2.0 */
14/* */
15/* Unless required by applicable law or agreed to in writing, software */
16/* distributed under the License is distributed on an "AS IS" BASIS, */
17/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
18/* See the License for the specific language governing permissions and */
19/* limitations under the License. */
20/* */
21/* You should have received a copy of the Apache-2.0 license */
22/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
23/* */
24/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
25
26/**@file branch_random.c
27 * @ingroup DEFPLUGINS_BRANCH
28 * @brief random variable branching rule
29 * @author Tobias Achterberg
30 * @author Stefan Vigerske
31 */
32
33/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
34
35#include "scip/branch_random.h"
36#include "scip/pub_branch.h"
37#include "scip/pub_message.h"
38#include "scip/pub_misc.h"
39#include "scip/pub_var.h"
40#include "scip/scip_branch.h"
41#include "scip/scip_message.h"
42#include "scip/scip_mem.h"
43#include "scip/scip_numerics.h"
44#include "scip/scip_param.h"
46#include "scip/scip_tree.h"
47
48
49#define BRANCHRULE_NAME "random"
50#define BRANCHRULE_DESC "random variable branching"
51#define BRANCHRULE_PRIORITY -100000
52#define BRANCHRULE_MAXDEPTH -1
53#define BRANCHRULE_MAXBOUNDDIST 1.0
54
55#define DEFAULT_INITSEED 41 /**< initial random seed */
56
57/** branching rule data */
58struct SCIP_BranchruleData
59{
60 SCIP_RANDNUMGEN* randnumgen; /**< random number generator */
61 int initseed; /**< initial random seed value */
62};
63
64/*
65 * Local methods
66 */
67
68/** selects a random active variable from a given list of variables */
69static
71 SCIP* scip, /**< SCIP data structure */
72 SCIP_BRANCHRULEDATA* branchruledata, /**< branchrule data */
73 SCIP_VAR** cands, /**< array of branching candidates */
74 SCIP_Real* candssol, /**< relaxation solution values of branching candidates, or NULL */
75 int ncands, /**< number of branching candidates */
76 SCIP_VAR** bestcand, /**< buffer to store pointer to best candidate */
77 SCIP_Real* bestcandsol /**< buffer to store solution value of best candidate */
78 )
79{
80 int idx;
81 int firstidx;
82
83 assert(scip != NULL);
84 assert(cands != NULL);
85 assert(ncands > 0);
87 assert(bestcandsol != NULL);
88
89 idx = SCIPrandomGetInt(branchruledata->randnumgen, 0, ncands-1);
90 assert(idx >= 0);
91
92 /* handle case where cands[idx] is fixed by selecting next idx with unfixed var
93 * this may happen if we are inside a multi-aggregation */
94 firstidx = idx;
95 while( SCIPisEQ(scip, SCIPvarGetLbLocal(cands[idx]), SCIPvarGetUbLocal(cands[idx])) )
96 {
97 ++idx;
98 if( idx == ncands )
99 idx = 0;
100 if( idx == firstidx )
101 {
102 /* odd: all variables seem to be fixed */
103 SCIPdebugMsg(scip, "Warning: all branching candidates seem to be fixed\n");
104 return;
105 }
106 }
107
108 /* a branching variable candidate should either be an active problem variable or a multi-aggregated variable */
111
113 {
114 /* for a multi-aggregated variable, we call the getRandomVariable function recursively with all variables in the multi-aggregation */
115 SCIP_VAR* cand;
116
117 cand = SCIPvarGetProbvar(cands[idx]);
118
120 bestcand, bestcandsol);
121 return;
122 }
123
124 assert(idx >= 0 && idx < ncands);
125
126 *bestcand = cands[idx];
127 assert(*bestcand != NULL);
128
129 if( candssol != NULL )
130 *bestcandsol = candssol[idx];
131}
132
133/*
134 * Callback methods
135 */
136
137/** copy method for branchrule plugins (called when SCIP copies plugins) */
138static
139SCIP_DECL_BRANCHCOPY(branchCopyRandom)
140{ /*lint --e{715}*/
141 assert(scip != NULL);
142 assert(branchrule != NULL);
143
145
146 /* call inclusion method of branchrule */
148
149 return SCIP_OKAY;
150}
151
152/** destructor of branching rule to free user data (called when SCIP is exiting) */
153/**! [SnippetBranchFreeRandom] */
154static
155SCIP_DECL_BRANCHFREE(branchFreeRandom)
156{ /*lint --e{715}*/
157 SCIP_BRANCHRULEDATA* branchruledata;
158
159 /* get branching rule data */
160 branchruledata = SCIPbranchruleGetData(branchrule);
161 assert(branchruledata != NULL);
162
163 /* free branching rule data */
164 SCIPfreeBlockMemory(scip, &branchruledata);
165 SCIPbranchruleSetData(branchrule, NULL);
166
167 return SCIP_OKAY;
168}
169/**! [SnippetBranchFreeRandom] */
170
171
172/** initialization method of branching rule (called after problem was transformed) */
173static
174SCIP_DECL_BRANCHINIT(branchInitRandom)
175{ /*lint --e{715}*/
176 SCIP_BRANCHRULEDATA* branchruledata;
177
178 branchruledata = SCIPbranchruleGetData(branchrule);
179 assert(branchruledata != NULL);
180 assert(branchruledata->initseed >= 0);
181
182 /* create a random number generator */
183 SCIP_CALL( SCIPcreateRandom(scip, &branchruledata->randnumgen,
184 (unsigned int)branchruledata->initseed, TRUE) );
185
186 return SCIP_OKAY;
187}
188
189/** deinitialization method of branching rule */
190static
191SCIP_DECL_BRANCHEXIT(branchExitRandom)
192{ /*lint --e{715}*/
193 SCIP_BRANCHRULEDATA* branchruledata;
194
195 /* get branching rule data */
196 branchruledata = SCIPbranchruleGetData(branchrule);
197 assert(branchruledata != NULL);
198
199 /* free random number generator */
200 SCIPfreeRandom(scip, &branchruledata->randnumgen);
201
202 return SCIP_OKAY;
203}
204
205/** branching execution method for fractional LP solutions */
206static
207SCIP_DECL_BRANCHEXECLP(branchExeclpRandom)
208{ /*lint --e{715}*/
209 SCIP_BRANCHRULEDATA* branchruledata;
211 int nlpcands;
212 int bestcand;
213
214 assert(branchrule != NULL);
215 assert(scip != NULL);
216 assert(result != NULL);
217
219
220 SCIPdebugMsg(scip, "Execlp method of random branching in depth %d\n", SCIPgetDepth(scip));
221
222 branchruledata = SCIPbranchruleGetData(branchrule);
223 assert(branchruledata != NULL);
224
225 /* get branching candidates */
227 assert(nlpcands > 0);
228
229 /* get random branching candidate */
230 bestcand = SCIPrandomGetInt(branchruledata->randnumgen, 0, nlpcands-1);
231 assert(bestcand >= 0);
232
233 SCIPdebugMsg(scip, " -> %d candidates, selected candidate %d: variable <%s>\n",
235
236 /* perform the branching */
239
240 return SCIP_OKAY;
241}
242
243
244/** branching execution method for external candidates */
245static
246SCIP_DECL_BRANCHEXECEXT(branchExecextRandom)
247{ /*lint --e{715}*/
248 SCIP_BRANCHRULEDATA* branchruledata;
249 SCIP_VAR** externcands;
250 SCIP_Real* externcandssol;
251 int nprioexterncands;
253 SCIP_Real bestcandsol;
254 SCIP_Real brpoint;
255 SCIP_NODE* downchild;
256 SCIP_NODE* eqchild;
257 SCIP_NODE* upchild;
258
259 assert(branchrule != NULL);
260 assert(scip != NULL);
261 assert(result != NULL);
262
264
265 SCIPdebugMsg(scip, "Execrel method of random branching\n");
266
267 branchruledata = SCIPbranchruleGetData(branchrule);
268 assert(branchruledata != NULL);
269
270 bestcand = NULL;
271 bestcandsol = 0.0;
272
273 /* get branching candidates */
274 SCIP_CALL( SCIPgetExternBranchCands(scip, &externcands, &externcandssol, NULL, NULL, &nprioexterncands, NULL, NULL, NULL) );
275 assert(nprioexterncands > 0);
276
277 /* get random branching candidate
278 *
279 * since variables can occur several times in the list of candidates, variables that have been added more often have
280 * a higher probability to be chosen for branching
281 */
282 getRandomVariable(scip, branchruledata, externcands, externcandssol, nprioexterncands, &bestcand, &bestcandsol);
283
284 if( bestcand == NULL )
285 {
286 SCIPerrorMessage("branchExecrelRandom failed to select a branching variable from %d candidates\n", nprioexterncands);
288 return SCIP_OKAY;
289 }
290
291 brpoint = SCIPgetBranchingPoint(scip, bestcand, bestcandsol);
292
293 SCIPdebugMsg(scip, " -> %d candidates, selected variable <%s> with solution value %g, branching point=%g\n",
294 nprioexterncands, SCIPvarGetName(bestcand), bestcandsol, brpoint);
295
296 SCIP_CALL( SCIPbranchVarVal(scip, bestcand, brpoint, &downchild, &eqchild, &upchild) );
297
298 if( downchild != NULL || eqchild != NULL || upchild != NULL )
299 {
301 }
302 else
303 {
304 /* if there are no children, then variable should have been fixed by SCIPbranchVarVal */
307 }
308
309 return SCIP_OKAY;
310}
311
312/** branching execution method for not completely fixed pseudo solutions */
313static
314SCIP_DECL_BRANCHEXECPS(branchExecpsRandom)
315{ /*lint --e{715}*/
316 SCIP_BRANCHRULEDATA* branchruledata;
318 int npseudocands;
319 int bestcand;
320
321 assert(branchrule != NULL);
322 assert(scip != NULL);
323 assert(result != NULL);
324
326
327 SCIPdebugMsg(scip, "Execps method of random branching\n");
328
329 branchruledata = SCIPbranchruleGetData(branchrule);
330 assert(branchruledata != NULL);
331
332 /* get branching candidates */
334 assert(npseudocands > 0);
335
336 /* get random branching candidate */
337 bestcand = SCIPrandomGetInt(branchruledata->randnumgen, 0, npseudocands-1);
338 assert(bestcand >= 0);
339
340 SCIPdebugMsg(scip, " -> %d candidates, selected candidate %d: variable <%s>\n",
342
343 /* perform the branching */
346
347 return SCIP_OKAY;
348}
349
350
351/*
352 * branching specific interface methods
353 */
354
355/** creates the random branching rule and includes it in SCIP */
357 SCIP* scip /**< SCIP data structure */
358 )
359{
360 SCIP_BRANCHRULEDATA* branchruledata;
361 SCIP_BRANCHRULE* branchrule;
362
363 /* create random branching rule data */
364 SCIP_CALL( SCIPallocBlockMemory(scip, &branchruledata) );
365
366 /* include allfullstrong branching rule */
369
370 assert(branchrule != NULL);
371
372 /* set non-fundamental callbacks via specific setter functions*/
373 SCIP_CALL( SCIPsetBranchruleCopy(scip, branchrule, branchCopyRandom) );
374 SCIP_CALL( SCIPsetBranchruleFree(scip, branchrule, branchFreeRandom) );
375 SCIP_CALL( SCIPsetBranchruleInit(scip, branchrule, branchInitRandom) );
376 SCIP_CALL( SCIPsetBranchruleExit(scip, branchrule, branchExitRandom) );
377 SCIP_CALL( SCIPsetBranchruleExecLp(scip, branchrule, branchExeclpRandom) );
378 SCIP_CALL( SCIPsetBranchruleExecExt(scip, branchrule, branchExecextRandom) );
379 SCIP_CALL( SCIPsetBranchruleExecPs(scip, branchrule, branchExecpsRandom) );
380
381 SCIP_CALL( SCIPaddIntParam(scip, "branching/" BRANCHRULE_NAME "/seed", "initial random seed value",
382 &branchruledata->initseed, FALSE, DEFAULT_INITSEED, 0, INT_MAX, NULL, NULL) );
383
384 return SCIP_OKAY;
385}
#define BRANCHRULE_DESC
#define BRANCHRULE_PRIORITY
#define BRANCHRULE_NAME
#define BRANCHRULE_MAXDEPTH
#define BRANCHRULE_MAXBOUNDDIST
#define DEFAULT_INITSEED
static void getRandomVariable(SCIP *scip, SCIP_BRANCHRULEDATA *branchruledata, SCIP_VAR **cands, SCIP_Real *candssol, int ncands, SCIP_VAR **bestcand, SCIP_Real *bestcandsol)
random variable branching rule
#define NULL
Definition def.h:257
#define SCIP_STRINGEQ(name, reference, retcode)
Definition def.h:454
#define SCIP_Real
Definition def.h:165
#define TRUE
Definition def.h:102
#define FALSE
Definition def.h:103
#define SCIP_CALL(x)
Definition def.h:364
SCIP_RETCODE SCIPincludeBranchruleRandom(SCIP *scip)
#define SCIPdebugMsg
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:83
SCIP_RETCODE SCIPsetBranchruleInit(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
SCIP_RETCODE SCIPsetBranchruleExit(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
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_BRANCHRULEDATA * SCIPbranchruleGetData(SCIP_BRANCHRULE *branchrule)
Definition branch.c:1886
SCIP_RETCODE SCIPsetBranchruleExecExt(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
SCIP_RETCODE SCIPsetBranchruleCopy(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
SCIP_RETCODE SCIPsetBranchruleExecLp(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
void SCIPbranchruleSetData(SCIP_BRANCHRULE *branchrule, SCIP_BRANCHRULEDATA *branchruledata)
Definition branch.c:1896
SCIP_RETCODE SCIPsetBranchruleFree(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
SCIP_RETCODE SCIPsetBranchruleExecPs(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
SCIP_RETCODE SCIPgetExternBranchCands(SCIP *scip, SCIP_VAR ***externcands, SCIP_Real **externcandssol, SCIP_Real **externcandsscore, int *nexterncands, int *nprioexterncands, int *nprioexternbins, int *nprioexternints, int *nprioexternimpls)
SCIP_Real SCIPgetBranchingPoint(SCIP *scip, SCIP_VAR *var, SCIP_Real suggestion)
SCIP_RETCODE SCIPbranchVarVal(SCIP *scip, SCIP_VAR *var, SCIP_Real val, SCIP_NODE **downchild, SCIP_NODE **eqchild, SCIP_NODE **upchild)
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
SCIP_RETCODE SCIPbranchVar(SCIP *scip, SCIP_VAR *var, SCIP_NODE **downchild, SCIP_NODE **eqchild, SCIP_NODE **upchild)
SCIP_RETCODE SCIPgetPseudoBranchCands(SCIP *scip, SCIP_VAR ***pseudocands, int *npseudocands, int *npriopseudocands)
#define SCIPfreeBlockMemory(scip, ptr)
Definition scip_mem.h:108
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
int SCIPgetDepth(SCIP *scip)
Definition scip_tree.c:672
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition var.c:23674
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition var.c:23418
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition var.c:24300
SCIP_VAR * SCIPvarGetProbvar(SCIP_VAR *var)
Definition var.c:17595
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:23299
SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
Definition var.c:23838
int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
Definition var.c:23826
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition var.c:24266
int SCIPrandomGetInt(SCIP_RANDNUMGEN *randnumgen, int minrandval, int maxrandval)
Definition misc.c:10223
return SCIP_OKAY
SCIPfreeRandom(scip, &heurdata->randnumgen)
SCIP_VAR ** pseudocands
SCIPcreateRandom(scip, &heurdata->randnumgen, DEFAULT_RANDSEED, TRUE))
int nlpcands
SCIP_VAR ** lpcands
assert(minobj< SCIPgetCutoffbound(scip))
int bestcand
public methods for branching rules
public methods for message output
#define SCIPerrorMessage
Definition pub_message.h:64
public data structures and miscellaneous methods
public methods for problem variables
public methods for branching rule plugins and branching
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for random numbers
public methods for the branch-and-bound tree
#define SCIP_DECL_BRANCHEXECPS(x)
#define SCIP_DECL_BRANCHEXECLP(x)
#define SCIP_DECL_BRANCHEXECEXT(x)
#define SCIP_DECL_BRANCHINIT(x)
Definition type_branch.h:83
#define SCIP_DECL_BRANCHCOPY(x)
Definition type_branch.h:67
#define SCIP_DECL_BRANCHEXIT(x)
Definition type_branch.h:91
#define SCIP_DECL_BRANCHFREE(x)
Definition type_branch.h:75
struct SCIP_Branchrule SCIP_BRANCHRULE
Definition type_branch.h:56
struct SCIP_BranchruleData SCIP_BRANCHRULEDATA
Definition type_branch.h:57
struct SCIP_RandNumGen SCIP_RANDNUMGEN
Definition type_misc.h:127
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ SCIP_REDUCEDDOM
Definition type_result.h:51
@ SCIP_BRANCHED
Definition type_result.h:54
@ 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
@ SCIP_VARSTATUS_MULTAGGR
Definition type_var.h:56