Scippy

SCIP

Solving Constraint Integer Programs

branch_relpscost.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-2016 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_relpscost.c
17  * @brief reliable pseudo costs branching rule
18  * @author Tobias Achterberg
19  * @author Timo Berthold
20  * @author Gerald Gamrath
21  */
22 
23 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
24 
25 #include <assert.h>
26 #include <string.h>
27 
28 #include "scip/branch_relpscost.h"
29 #include "scip/cons_and.h"
30 
31 #define BRANCHRULE_NAME "relpscost"
32 #define BRANCHRULE_DESC "reliability branching on pseudo cost values"
33 #define BRANCHRULE_PRIORITY 10000
34 #define BRANCHRULE_MAXDEPTH -1
35 #define BRANCHRULE_MAXBOUNDDIST 1.0
36 
37 #define DEFAULT_CONFLICTWEIGHT 0.01 /**< weight in score calculations for conflict score */
38 #define DEFAULT_CONFLENGTHWEIGHT 0.0 /**< weight in score calculations for conflict length score*/
39 #define DEFAULT_INFERENCEWEIGHT 0.0001 /**< weight in score calculations for inference score */
40 #define DEFAULT_CUTOFFWEIGHT 0.0001 /**< weight in score calculations for cutoff score */
41 #define DEFAULT_PSCOSTWEIGHT 1.0 /**< weight in score calculations for pseudo cost score */
42 #define DEFAULT_NLSCOREWEIGHT 0.1 /**< weight in score calculations for nlcount score */
43 #define DEFAULT_MINRELIABLE 1.0 /**< minimal value for minimum pseudo cost size to regard pseudo cost value as reliable */
44 #define DEFAULT_MAXRELIABLE 5.0 /**< maximal value for minimum pseudo cost size to regard pseudo cost value as reliable */
45 #define DEFAULT_SBITERQUOT 0.5 /**< maximal fraction of strong branching LP iterations compared to normal iterations */
46 #define DEFAULT_SBITEROFS 100000 /**< additional number of allowed strong branching LP iterations */
47 #define DEFAULT_MAXLOOKAHEAD 9 /**< maximal number of further variables evaluated without better score */
48 #define DEFAULT_INITCAND 100 /**< maximal number of candidates initialized with strong branching per node */
49 #define DEFAULT_INITITER 0 /**< iteration limit for strong branching initialization of pseudo cost entries (0: auto) */
50 #define DEFAULT_MAXBDCHGS 5 /**< maximal number of bound tightenings before the node is reevaluated (-1: unlimited) */
51 #define DEFAULT_MAXPROPROUNDS -2 /**< maximum number of propagation rounds to be performed during strong branching
52  * before solving the LP (-1: no limit, -2: parameter settings) */
53 #define DEFAULT_PROBINGBOUNDS TRUE /**< should valid bounds be identified in a probing-like fashion during strong
54  * branching (only with propagation)? */
55 #define DEFAULT_USERELERRORFORRELIABILITY FALSE /**< should reliability be based on relative errors? */
56 #define DEFAULT_LOWERRORTOL 0.05 /**< lowest tolerance beneath which relative errors are reliable */
57 #define DEFAULT_HIGHERRORTOL 1.0 /**< highest tolerance beneath which relative errors are reliable */
58 #define DEFAULT_USEHYPTESTFORRELIABILITY FALSE /**< should the strong branching decision be based on a hypothesis test? */
59 #define DEFAULT_USEDYNAMICCONFIDENCE FALSE /**< should the confidence level be adjusted dynamically? */
60 #define DEFAULT_STORESEMIINITCOSTS FALSE /**< should strong branching result be considered for pseudo costs if the other direction was infeasible? */
61 #define DEFAULT_USESBLOCALINFO FALSE /**< should the scoring function use only local cutoff and inference information obtained for strong branching candidates? */
62 #define DEFAULT_CONFIDENCELEVEL 2 /**< The confidence level for statistical methods, between 0 (Min) and 4 (Max). */
63 #define DEFAULT_SKIPBADINITCANDS TRUE /**< should branching rule skip candidates that have a low probability to be
64  * better than the best strong-branching or pseudo-candidate? */
65 #define DEFAULT_STARTRANDSEED 12345 /**< start random seed for random number generation */
66 #define DEFAULT_RANDINITORDER FALSE /**< should candidates be initialized in randomized order? */
67 
68 /** branching rule data */
69 struct SCIP_BranchruleData
70 {
71  SCIP_Real conflictweight; /**< weight in score calculations for conflict score */
72  SCIP_Real conflengthweight; /**< weight in score calculations for conflict length score */
73  SCIP_Real inferenceweight; /**< weight in score calculations for inference score */
74  SCIP_Real cutoffweight; /**< weight in score calculations for cutoff score */
75  SCIP_Real pscostweight; /**< weight in score calculations for pseudo cost score */
76  SCIP_Real nlscoreweight; /**< weight in score calculations for nlcount score */
77  SCIP_Real minreliable; /**< minimal value for minimum pseudo cost size to regard pseudo cost value as reliable */
78  SCIP_Real maxreliable; /**< maximal value for minimum pseudo cost size to regard pseudo cost value as reliable */
79  SCIP_Real sbiterquot; /**< maximal fraction of strong branching LP iterations compared to normal iterations */
80  int sbiterofs; /**< additional number of allowed strong branching LP iterations */
81  int maxlookahead; /**< maximal number of further variables evaluated without better score */
82  int initcand; /**< maximal number of candidates initialized with strong branching per node */
83  int inititer; /**< iteration limit for strong branching initialization of pseudo cost entries (0: auto) */
84  int maxbdchgs; /**< maximal number of bound tightenings before the node is reevaluated (-1: unlimited) */
85  int maxproprounds; /**< maximum number of propagation rounds to be performed during strong branching
86  * before solving the LP (-1: no limit, -2: parameter settings) */
87  SCIP_Bool probingbounds; /**< should valid bounds be identified in a probing-like fashion during strong
88  * branching (only with propagation)? */
89  SCIP_Bool userelerrorforreliability; /**< should reliability be based on relative errors? */
90  SCIP_Real lowerrortol; /**< lowest tolerance beneath which relative errors are reliable */
91  SCIP_Real higherrortol; /**< highest tolerance beneath which relative errors are reliable */
92  SCIP_Bool usehyptestforreliability; /**< should the strong branching decision be based on a hypothesis test? */
93  SCIP_Bool usedynamicconfidence; /**< should the confidence level be adjusted dynamically? */
94  SCIP_Bool storesemiinitcosts; /**< should strong branching result be considered for pseudo costs if the other direction was infeasible? */
95  SCIP_Bool usesblocalinfo; /**< should the scoring function disregard cutoffs for variable if sb-lookahead was feasible ? */
96  SCIP_Bool skipbadinitcands; /**< should branching rule skip candidates that have a low probability to be
97  * better than the best strong-branching or pseudo-candidate? */
98  int confidencelevel; /**< The confidence level for statistical methods, between 0 (Min) and 4 (Max). */
99  int* nlcount; /**< array to store nonlinear count values */
100  int nlcountsize; /**< length of nlcount array */
101  int nlcountmax; /**< maximum entry in nlcount array or 1 if NULL */
102  SCIP_Bool randinitorder; /**< should init candidates be processed in a random order? */
103  unsigned int randseed; /**< random seed for random number generation */
104  int startrandseed; /**< start random seed for random number generation */
105 };
106 
107 /*
108  * local methods
109  */
110 
111 /** return probindex of variable or corresponding active variable (if negated or aggregated) or -1 (if
112  * multiaggregated)
113  */
114 static
116  SCIP* scip, /**< SCIP data structure */
117  SCIP_VAR* var, /**< binary variable */
118  int* probindex /**< buffer to store probindex */
119  )
120 {
121  assert(scip != NULL);
122  assert(var != NULL);
123  assert(SCIPvarIsBinary(var));
124  assert(probindex != NULL);
125 
126  *probindex = SCIPvarGetProbindex(var);
127 
128  /* if variable is not active, try to find active representative */
129  if( *probindex == -1 )
130  {
131  SCIP_VAR* repvar;
132  SCIP_Bool negated;
133 
134  SCIP_CALL( SCIPgetBinvarRepresentative(scip, var, &repvar, &negated) );
135  assert(repvar != NULL);
136  assert(SCIPvarGetStatus(repvar) != SCIP_VARSTATUS_FIXED);
137 
138  if( SCIPvarIsActive(repvar) )
139  *probindex = SCIPvarGetProbindex(repvar);
140  else if( SCIPvarIsNegated(repvar) )
141  *probindex = SCIPvarGetProbindex(SCIPvarGetNegationVar(repvar));
142  }
143 
144  return SCIP_OKAY;
145 }
146 
147 /** counts number of nonlinear constraints in which each variable appears */
148 static
150  SCIP* scip, /**< SCIP data structure */
151  int* nlcount, /**< pointer to array for storing count values */
152  int nlcountsize, /**< buffer for storing length of nlcount array */
153  int* nlcountmax /**< buffer for storing maximum value in nlcount array */
154  )
155 {
156  SCIP_CONSHDLR* andconshdlr;
157  SCIP_VAR** vars;
158  int nvars;
159  int i;
160 
161  assert(scip != NULL);
162  assert(nlcount != NULL);
163  assert(nlcountmax != NULL);
164 
165  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
166  assert(nlcountsize >= nvars);
167 
168  /* get nonlinearity for constraints in NLP */
169  if( SCIPisNLPConstructed(scip) )
170  {
171  assert(SCIPgetNNLPVars(scip) == nvars);
172  SCIP_CALL( SCIPgetNLPVarsNonlinearity(scip, nlcount) );
173  }
174  else
175  {
176  BMSclearMemoryArray(nlcount, nvars);
177  }
178 
179  /* increase counters for and constraints */
180  andconshdlr = SCIPfindConshdlr(scip, "and");
181  if( andconshdlr != NULL )
182  {
183  int c;
184 
185  for( c = 0; c < SCIPconshdlrGetNActiveConss(andconshdlr); c++ )
186  {
187  SCIP_CONS* andcons;
188  SCIP_VAR** andvars;
189  SCIP_VAR* andres;
190  int probindex;
191  int nandvars;
192  int v;
193 
194  /* get constraint and variables */
195  andcons = SCIPconshdlrGetConss(andconshdlr)[c];
196  nandvars = SCIPgetNVarsAnd(scip, andcons);
197  andvars = SCIPgetVarsAnd(scip, andcons);
198  andres = SCIPgetResultantAnd(scip, andcons);
199 
200  probindex = -1;
201  for( v = 0; v < nandvars; v++ )
202  {
203  /* don't rely on the and conshdlr removing fixed variables
204  * @todo fix the and conshdlr in that respect
205  */
206  if( SCIPvarGetStatus(andvars[v]) != SCIP_VARSTATUS_FIXED )
207  {
208  SCIP_CALL( binvarGetActiveProbindex(scip, andvars[v], &probindex) );
209  if( probindex >= 0 )
210  nlcount[probindex]++;
211  }
212  }
213 
214  SCIP_CALL( binvarGetActiveProbindex(scip, andres, &probindex) );
215  if( probindex >= 0 )
216  nlcount[probindex]++;
217  }
218  }
219 
220  /* compute maximum count value */
221  *nlcountmax = 1;
222  for( i = 0; i < nvars; i++ )
223  {
224  if( *nlcountmax < nlcount[i] )
225  *nlcountmax = nlcount[i];
226  }
227 
228  return SCIP_OKAY;
229 }
230 
231 static
233  SCIP* scip, /**< SCIP data structure */
234  SCIP_BRANCHRULEDATA* branchruledata /**< branching rule data */
235  )
236 {
237  int nvars;
238 
239  assert(scip != NULL);
240  assert(branchruledata != NULL);
241 
242  nvars = SCIPgetNVars(scip);
243 
244  /**@todo test whether we want to apply this als if problem has only and constraints */
245  /**@todo update changes in and constraints */
246  if( branchruledata->nlscoreweight > 0.0 ) /* && SCIPisNLPConstructed(scip) */
247  {
248  if( branchruledata->nlcount == NULL )
249  {
250  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &branchruledata->nlcount, nvars) );
251  branchruledata->nlcountsize = nvars;
252 
253  SCIP_CALL( countNonlinearities(scip, branchruledata->nlcount, branchruledata->nlcountsize, &branchruledata->nlcountmax) );
254  }
255  else if( branchruledata->nlcountsize < nvars )
256  {
257  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &branchruledata->nlcount, branchruledata->nlcountsize, nvars) );
258  /**@todo should we update nlcounts for new variables? */
259  BMSclearMemoryArray(&(branchruledata->nlcount[branchruledata->nlcountsize]), nvars - branchruledata->nlcountsize); /*lint !e866*/
260  branchruledata->nlcountsize = nvars;
261  }
262  assert(branchruledata->nlcount != NULL);
263  assert(branchruledata->nlcountsize == nvars);
264  assert(branchruledata->nlcountmax >= 1);
265  }
266  else
267  {
268  SCIPfreeBlockMemoryArrayNull(scip, &branchruledata->nlcount, branchruledata->nlcountsize);
269  branchruledata->nlcountsize = 0;
270  branchruledata->nlcountmax = 1;
271  }
272 
273  return SCIP_OKAY;
274 }
275 
276 
277 /** calculates nlscore value between 0 and 1 */
278 static
280  SCIP* scip, /**< SCIP data structure */
281  int* nlcount, /**< array to store count values */
282  int nlcountmax, /**< maximum value in nlcount array */
283  int probindex /**< index of branching candidate */
284  )
285 {
286  if( nlcountmax >= 1 && nlcount != NULL )
287  {
288  SCIP_Real nlscore;
289 
290  assert(scip != NULL);
291  assert(probindex >= 0);
292  assert(probindex < SCIPgetNVars(scip));
293 
294  nlscore = nlcount[probindex] / (SCIP_Real)nlcountmax;
295 
296  assert(nlscore >= 0.0);
297  assert(nlscore <= 1.0);
298  return nlscore;
299  }
300  else
301  return 0.0;
302 }
303 
304 /** calculates an overall score value for the given individual score values */
305 static
307  SCIP* scip, /**< SCIP data structure */
308  SCIP_BRANCHRULEDATA* branchruledata, /**< branching rule data */
309  SCIP_Real conflictscore, /**< conflict score of current variable */
310  SCIP_Real avgconflictscore, /**< average conflict score */
311  SCIP_Real conflengthscore, /**< conflict length score of current variable */
312  SCIP_Real avgconflengthscore, /**< average conflict length score */
313  SCIP_Real inferencescore, /**< inference score of current variable */
314  SCIP_Real avginferencescore, /**< average inference score */
315  SCIP_Real cutoffscore, /**< cutoff score of current variable */
316  SCIP_Real avgcutoffscore, /**< average cutoff score */
317  SCIP_Real pscostscore, /**< pscost score of current variable */
318  SCIP_Real avgpscostscore, /**< average pscost score */
319  SCIP_Real nlscore, /**< nonlinear score of current variable between 0 and 1 */
320  SCIP_Real frac /**< fractional value of variable in current solution */
321  )
322 {
323  SCIP_Real score;
324 
325  assert(branchruledata != NULL);
326  assert(0.0 < frac && frac < 1.0);
327 
328  score = branchruledata->conflictweight * (1.0 - 1.0/(1.0+conflictscore/avgconflictscore))
329  + branchruledata->conflengthweight * (1.0 - 1.0/(1.0+conflengthscore/avgconflengthscore))
330  + branchruledata->inferenceweight * (1.0 - 1.0/(1.0+inferencescore/avginferencescore))
331  + branchruledata->cutoffweight * (1.0 - 1.0/(1.0+cutoffscore/avgcutoffscore))
332  + branchruledata->pscostweight * (1.0 - 1.0/(1.0+pscostscore/avgpscostscore))
333  + branchruledata->nlscoreweight * nlscore;
334 
335  /* avoid close to integral variables */
336  if( MIN(frac, 1.0 - frac) < 10.0*SCIPfeastol(scip) )
337  score *= 1e-6;
338 
339  return score;
340 }
341 
342 /** adds given index and direction to bound change arrays */
343 static
345  SCIP* scip, /**< SCIP data structure */
346  int** bdchginds, /**< pointer to bound change index array */
347  SCIP_BOUNDTYPE** bdchgtypes, /**< pointer to bound change types array */
348  SCIP_Real** bdchgbounds, /**< pointer to bound change new bounds array */
349  int* nbdchgs, /**< pointer to number of bound changes */
350  int ind, /**< index to store in bound change index array */
351  SCIP_BOUNDTYPE type, /**< type of the bound change to store in bound change type array */
352  SCIP_Real bound /**< new bound to store in bound change new bounds array */
353  )
354 {
355  assert(bdchginds != NULL);
356  assert(bdchgtypes != NULL);
357  assert(bdchgbounds != NULL);
358  assert(nbdchgs != NULL);
359 
360  SCIP_CALL( SCIPreallocBufferArray(scip, bdchginds, (*nbdchgs) + 1) );
361  SCIP_CALL( SCIPreallocBufferArray(scip, bdchgtypes, (*nbdchgs) + 1) );
362  SCIP_CALL( SCIPreallocBufferArray(scip, bdchgbounds, (*nbdchgs) + 1) );
363  assert(*bdchginds != NULL);
364  assert(*bdchgtypes != NULL);
365  assert(*bdchgbounds != NULL);
366 
367  (*bdchginds)[*nbdchgs] = ind;
368  (*bdchgtypes)[*nbdchgs] = type;
369  (*bdchgbounds)[*nbdchgs] = bound;
370  (*nbdchgs)++;
371 
372  return SCIP_OKAY;
373 }
374 
375 /** frees bound change arrays */
376 static
377 void freeBdchgs(
378  SCIP* scip, /**< SCIP data structure */
379  int** bdchginds, /**< pointer to bound change index array */
380  SCIP_BOUNDTYPE** bdchgtypes, /**< pointer to bound change types array */
381  SCIP_Real** bdchgbounds, /**< pointer to bound change new bounds array */
382  int* nbdchgs /**< pointer to number of bound changes */
383  )
384 {
385  assert(bdchginds != NULL);
386  assert(bdchgtypes != NULL);
387  assert(bdchgbounds != NULL);
388  assert(nbdchgs != NULL);
389 
390  SCIPfreeBufferArrayNull(scip, bdchgbounds);
391  SCIPfreeBufferArrayNull(scip, bdchgtypes);
392  SCIPfreeBufferArrayNull(scip, bdchginds);
393  *nbdchgs = 0;
394 }
395 
396 /** applies bound changes stored in bound change arrays */
397 static
399  SCIP* scip, /**< SCIP data structure */
400  SCIP_VAR** vars, /**< problem variables */
401  int* bdchginds, /**< bound change index array */
402  SCIP_BOUNDTYPE* bdchgtypes, /**< bound change types array */
403  SCIP_Real* bdchgbounds, /**< bound change new bound array */
404  int nbdchgs, /**< number of bound changes */
405  SCIP_RESULT* result /**< result pointer */
406  )
407 {
408 #ifndef NDEBUG
409  SCIP_BRANCHRULE* branchrule;
410  SCIP_BRANCHRULEDATA* branchruledata;
411 #endif
412  SCIP_Bool infeasible;
413  SCIP_Bool tightened;
414  int i;
415 
416  assert(vars != NULL);
417 
418 #ifndef NDEBUG
419  /* find branching rule */
420  branchrule = SCIPfindBranchrule(scip, BRANCHRULE_NAME);
421  assert(branchrule != NULL);
422 
423  /* get branching rule data */
424  branchruledata = SCIPbranchruleGetData(branchrule);
425  assert(branchruledata != NULL);
426 #endif
427 
428  SCIPdebugMessage("applying %d bound changes\n", nbdchgs);
429 
430  for( i = 0; i < nbdchgs; ++i )
431  {
432  int v;
433 
434  v = bdchginds[i];
435 
436  SCIPdebugMessage(" -> <%s> [%g,%g]\n",
437  SCIPvarGetName(vars[v]), SCIPvarGetLbLocal(vars[v]), SCIPvarGetUbLocal(vars[v]));
438 
439  if( bdchgtypes[i] == SCIP_BOUNDTYPE_LOWER )
440  {
441  /* change lower bound of variable to given bound */
442  SCIP_CALL( SCIPtightenVarLb(scip, vars[v], bdchgbounds[i], TRUE, &infeasible, &tightened) );
443  if( infeasible )
444  {
445  *result = SCIP_CUTOFF;
446  return SCIP_OKAY;
447  }
448 
449  /* if we did propagation, the bound change might already have been added */
450  assert(tightened || (branchruledata->maxproprounds != 0));
451  }
452  else
453  {
454  assert(bdchgtypes[i] == SCIP_BOUNDTYPE_UPPER);
455 
456  /* change upper bound of variable to given bound */
457  SCIP_CALL( SCIPtightenVarUb(scip, vars[v], bdchgbounds[i], TRUE, &infeasible, &tightened) );
458  if( infeasible )
459  {
460  *result = SCIP_CUTOFF;
461  return SCIP_OKAY;
462  }
463 
464  /* if we did propagation, the bound change might already have been added */
465  assert(tightened || (branchruledata->maxproprounds != 0));
466  }
467  SCIPdebugMessage(" -> [%g,%g]\n", SCIPvarGetLbLocal(vars[v]), SCIPvarGetUbLocal(vars[v]));
468  }
469 
470  return SCIP_OKAY;
471 }
472 
473 /** execute reliability pseudo cost branching */
474 static
476  SCIP* scip, /**< SCIP data structure */
477  SCIP_BRANCHRULE* branchrule, /**< branching rule */
478  SCIP_Bool allowaddcons, /**< is the branching rule allowed to add constraints to the current node
479  * in order to cut off the current solution instead of creating a branching? */
480  SCIP_VAR** branchcands, /**< branching candidates */
481  SCIP_Real* branchcandssol, /**< solution value for the branching candidates */
482  SCIP_Real* branchcandsfrac, /**< fractional part of the branching candidates */
483  int nbranchcands, /**< number of branching candidates */
484  SCIP_Bool executebranch, /**< execute a branching step or run probing only */
485  SCIP_RESULT* result /**< pointer to the result of the execution */
486  )
487 {
488  SCIP_BRANCHRULEDATA* branchruledata;
489  SCIP_Real lpobjval;
490  SCIP_Real bestsbdown;
491  SCIP_Real bestsbup;
492  SCIP_Real provedbound;
493  SCIP_Bool bestsbdownvalid;
494  SCIP_Bool bestsbupvalid;
495  SCIP_Bool bestsbdowncutoff;
496  SCIP_Bool bestsbupcutoff;
497  SCIP_Bool bestisstrongbranch;
498  SCIP_Bool allcolsinlp;
499  SCIP_Bool exactsolve;
500  int ninitcands;
501  int bestcand;
502 
503  *result = SCIP_DIDNOTRUN;
504 
505  assert(SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL);
506 
507  /* get branching rule data */
508  branchruledata = SCIPbranchruleGetData(branchrule);
509  assert(branchruledata != NULL);
510 
511  /* get current LP objective bound of the local sub problem and global cutoff bound */
512  lpobjval = SCIPgetLPObjval(scip);
513 
514  /* check, if we want to solve the problem exactly, meaning that strong branching information is not useful
515  * for cutting off sub problems and improving lower bounds of children
516  */
517  exactsolve = SCIPisExactSolve(scip);
518 
519  /* check, if all existing columns are in LP, and thus the strong branching results give lower bounds */
520  allcolsinlp = SCIPallColsInLP(scip);
521 
522  bestcand = -1;
523  bestisstrongbranch = FALSE;
524  bestsbdown = SCIP_INVALID;
525  bestsbup = SCIP_INVALID;
526  bestsbdownvalid = FALSE;
527  bestsbupvalid = FALSE;
528  bestsbdowncutoff = FALSE;
529  bestsbupcutoff = FALSE;
530  provedbound = lpobjval;
531 
532  if( nbranchcands == 1 )
533  {
534  /* only one candidate: nothing has to be done */
535  bestcand = 0;
536  ninitcands = 0;
537  }
538  else
539  {
540  SCIP_VAR** vars;
541  int* initcands;
542  SCIP_Real* initcandscores;
543  SCIP_Real* newlbs = NULL;
544  SCIP_Real* newubs = NULL;
545  int* bdchginds;
546  SCIP_BOUNDTYPE* bdchgtypes;
547  SCIP_Real* bdchgbounds;
548  int maxninitcands;
549  int nuninitcands;
550  int nbdchgs;
551  int nbdconflicts;
552  SCIP_Real avgconflictscore;
553  SCIP_Real avgconflengthscore;
554  SCIP_Real avginferencescore;
555  SCIP_Real avgcutoffscore;
556  SCIP_Real avgpscostscore;
557  SCIP_Real bestpsscore;
558  SCIP_Real bestpsfracscore;
559  SCIP_Real bestpsdomainscore;
560  SCIP_Real bestsbscore;
561  SCIP_Real bestuninitsbscore;
562  SCIP_Real bestsbfracscore;
563  SCIP_Real bestsbdomainscore;
564  SCIP_Real prio;
565  SCIP_Real reliable;
566  SCIP_Real maxlookahead;
567  SCIP_Real lookahead;
568  SCIP_Real relerrorthreshold;
569  SCIP_Bool initstrongbranching;
570  SCIP_Bool propagate;
571  SCIP_Bool probingbounds;
572  SCIP_Longint nodenum;
573  SCIP_Longint nlpiterationsquot;
574  SCIP_Longint nsblpiterations;
575  SCIP_Longint maxnsblpiterations;
576  int bestsolidx;
577  int maxbdchgs;
578  int bestpscand;
579  int bestsbcand;
580  int bestuninitsbcand;
581  int inititer;
582  int nvars;
583  int i;
584  int c;
585  SCIP_CONFIDENCELEVEL clevel;
586 
587  vars = SCIPgetVars(scip);
588  nvars = SCIPgetNVars(scip);
589 
590  bestsolidx = SCIPgetBestSol(scip) == NULL ? -1 : SCIPsolGetIndex(SCIPgetBestSol(scip));
591 
592  /* get average conflict, inference, and pseudocost scores */
593  avgconflictscore = SCIPgetAvgConflictScore(scip);
594  avgconflictscore = MAX(avgconflictscore, 0.1);
595  avgconflengthscore = SCIPgetAvgConflictlengthScore(scip);
596  avgconflengthscore = MAX(avgconflengthscore, 0.1);
597  avginferencescore = SCIPgetAvgInferenceScore(scip);
598  avginferencescore = MAX(avginferencescore, 0.1);
599  avgcutoffscore = SCIPgetAvgCutoffScore(scip);
600  avgcutoffscore = MAX(avgcutoffscore, 0.1);
601  avgpscostscore = SCIPgetAvgPseudocostScore(scip);
602  avgpscostscore = MAX(avgpscostscore, 0.1);
603 
604  /* get nonlinear counts according to parameters */
605  SCIP_CALL( branchruledataEnsureNlcount(scip, branchruledata) );
606 
607  initstrongbranching = FALSE;
608 
609  /* check whether propagation should be performed */
610  propagate = (branchruledata->maxproprounds != 0);
611 
612  /* check whether valid bounds should be identified in probing-like fashion */
613  probingbounds = propagate && branchruledata->probingbounds;
614 
615  /* get maximal number of candidates to initialize with strong branching; if the current solutions is not basic,
616  * we cannot warmstart the simplex algorithm and therefore don't initialize any candidates
617  */
618  maxninitcands = MIN(nbranchcands, branchruledata->initcand);
619  if( !SCIPisLPSolBasic(scip) )
620  maxninitcands = 0;
621 
622  /* calculate maximal number of strong branching LP iterations; if we used too many, don't apply strong branching
623  * any more
624  */
625  nlpiterationsquot = (SCIP_Longint)(branchruledata->sbiterquot * SCIPgetNNodeLPIterations(scip));
626  maxnsblpiterations = nlpiterationsquot + branchruledata->sbiterofs + SCIPgetNRootStrongbranchLPIterations(scip);
627  nsblpiterations = SCIPgetNStrongbranchLPIterations(scip);
628  if( nsblpiterations > maxnsblpiterations )
629  maxninitcands = 0;
630 
631  /* get buffer for storing the unreliable candidates */
632  SCIP_CALL( SCIPallocBufferArray(scip, &initcands, maxninitcands+1) ); /* allocate one additional slot for convenience */
633  SCIP_CALL( SCIPallocBufferArray(scip, &initcandscores, maxninitcands+1) );
634  ninitcands = 0;
635 
636  /* get current node number */
637  nodenum = SCIPgetNNodes(scip);
638 
639  /* initialize bound change arrays */
640  bdchginds = NULL;
641  bdchgtypes = NULL;
642  bdchgbounds = NULL;
643  nbdchgs = 0;
644  nbdconflicts = 0;
645  maxbdchgs = branchruledata->maxbdchgs;
646  if( maxbdchgs == -1 )
647  maxbdchgs = INT_MAX;
648 
649  /* calculate value used as reliability */
650  prio = (maxnsblpiterations - nsblpiterations)/(nsblpiterations + 1.0);
651  prio = MIN(prio, 1.0);
652  prio = MAX(prio, (nlpiterationsquot - nsblpiterations)/(nsblpiterations + 1.0));
653  reliable = (1.0-prio) * branchruledata->minreliable + prio * branchruledata->maxreliable;
654 
655  /* calculate the threshold for the relative error in the same way; low tolerance is more strict than higher tolerance */
656  relerrorthreshold = (1.0 - prio) * branchruledata->higherrortol + prio * branchruledata->lowerrortol;
657 
658  clevel = (SCIP_CONFIDENCELEVEL)branchruledata->confidencelevel;
659  /* determine the confidence level for hypothesis testing based on value of prio */
660  if( branchruledata->usedynamicconfidence )
661  {
662  /* with decreasing priority, use a less strict confidence level */
663  if( prio >= 0.9 )
664  clevel = SCIP_CONFIDENCELEVEL_MAX;
665  else if( prio >= 0.7 )
666  clevel = SCIP_CONFIDENCELEVEL_HIGH;
667  else if( prio >= 0.5 )
669  else if( prio >= 0.3 )
670  clevel = SCIP_CONFIDENCELEVEL_LOW;
671  else
672  clevel = SCIP_CONFIDENCELEVEL_MIN;
673  }
674 
675  /* search for the best pseudo cost candidate, while remembering unreliable candidates in a sorted buffer */
676  nuninitcands = 0;
677  bestpscand = -1;
678  bestpsscore = -SCIPinfinity(scip);
679  bestpsfracscore = -SCIPinfinity(scip);
680  bestpsdomainscore = -SCIPinfinity(scip);
681 
682  /* search for the best candidate first */
683  if( branchruledata->usehyptestforreliability )
684  {
685  for( c = 0; c < nbranchcands; ++c )
686  {
687  SCIP_Real conflictscore;
688  SCIP_Real conflengthscore;
689  SCIP_Real inferencescore;
690  SCIP_Real cutoffscore;
691  SCIP_Real pscostscore;
692  SCIP_Real nlscore;
693  SCIP_Real score;
694 
695  conflictscore = SCIPgetVarConflictScore(scip, branchcands[c]);
696  conflengthscore = SCIPgetVarConflictlengthScore(scip, branchcands[c]);
697  inferencescore = SCIPgetVarAvgInferenceScore(scip, branchcands[c]);
698  cutoffscore = SCIPgetVarAvgCutoffScore(scip, branchcands[c]);
699  nlscore = calcNlscore(scip, branchruledata->nlcount, branchruledata->nlcountmax, SCIPvarGetProbindex(branchcands[c]));
700  pscostscore = SCIPgetVarPseudocostScore(scip, branchcands[c], branchcandssol[c]);
701 
702  /* replace the pseudo cost score with the already calculated one;
703  * @todo: use old data for strong branching with propagation?
704  */
705  if( SCIPgetVarStrongbranchNode(scip, branchcands[c]) == nodenum )
706  {
707  SCIP_Real down;
708  SCIP_Real up;
709  SCIP_Real lastlpobjval;
710  SCIP_Real downgain;
711  SCIP_Real upgain;
712 
713  /* use the score of the strong branching call at the current node */
714  SCIP_CALL( SCIPgetVarStrongbranchLast(scip, branchcands[c], &down, &up, NULL, NULL, NULL, &lastlpobjval) );
715  downgain = MAX(down - lastlpobjval, 0.0);
716  upgain = MAX(up - lastlpobjval, 0.0);
717  pscostscore = SCIPgetBranchScore(scip, branchcands[c], downgain, upgain);
718 
719  SCIPdebugMessage(" -> strong branching on variable <%s> already performed (down=%g (%+g), up=%g (%+g), pscostscore=%g)\n",
720  SCIPvarGetName(branchcands[c]), down, downgain, up, upgain, pscostscore);
721  }
722 
723  score = calcScore(scip, branchruledata, conflictscore, avgconflictscore, conflengthscore, avgconflengthscore,
724  inferencescore, avginferencescore, cutoffscore, avgcutoffscore, pscostscore, avgpscostscore, nlscore, branchcandsfrac[c]);
725 
726  /* check for better score of candidate */
727  if( SCIPisSumGE(scip, score, bestpsscore) )
728  {
729  SCIP_Real fracscore;
730  SCIP_Real domainscore;
731 
732  fracscore = MIN(branchcandsfrac[c], 1.0 - branchcandsfrac[c]);
733  domainscore = -(SCIPvarGetUbLocal(branchcands[c]) - SCIPvarGetLbLocal(branchcands[c]));
734  if( SCIPisSumGT(scip, score, bestpsscore)
735  || SCIPisSumGT(scip, fracscore, bestpsfracscore)
736  || (SCIPisSumGE(scip, fracscore, bestpsfracscore) && domainscore > bestpsdomainscore) )
737  {
738  bestpscand = c;
739  bestpsscore = score;
740  bestpsfracscore = fracscore;
741  bestpsdomainscore = domainscore;
742  }
743  }
744  }
745  }
746 
747  for( c = 0; c < nbranchcands; ++c )
748  {
749  SCIP_Real conflictscore;
750  SCIP_Real conflengthscore;
751  SCIP_Real inferencescore;
752  SCIP_Real cutoffscore;
753  SCIP_Real pscostscore;
754  SCIP_Real nlscore;
755  SCIP_Real score;
756  SCIP_Bool usesb;
757 
758  assert(branchcands[c] != NULL);
759  assert(!SCIPisFeasIntegral(scip, branchcandssol[c]));
760 
761  /* get conflict, inference, cutoff, nonlinear, and pseudo cost scores for candidate */
762  conflictscore = SCIPgetVarConflictScore(scip, branchcands[c]);
763  conflengthscore = SCIPgetVarConflictlengthScore(scip, branchcands[c]);
764  inferencescore = SCIPgetVarAvgInferenceScore(scip, branchcands[c]);
765  cutoffscore = SCIPgetVarAvgCutoffScore(scip, branchcands[c]);
766  nlscore = calcNlscore(scip, branchruledata->nlcount, branchruledata->nlcountmax, SCIPvarGetProbindex(branchcands[c]));
767  pscostscore = SCIPgetVarPseudocostScore(scip, branchcands[c], branchcandssol[c]);
768  usesb = FALSE;
769 
770  /* don't use strong branching on variables that have already been initialized at the current node;
771  * instead replace the pseudo cost score with the already calculated one;
772  * @todo: use old data for strong branching with propagation?
773  */
774  if( SCIPgetVarStrongbranchNode(scip, branchcands[c]) == nodenum )
775  {
776  SCIP_Real down;
777  SCIP_Real up;
778  SCIP_Real lastlpobjval;
779  SCIP_Real downgain;
780  SCIP_Real upgain;
781 
782  /* use the score of the strong branching call at the current node */
783  SCIP_CALL( SCIPgetVarStrongbranchLast(scip, branchcands[c], &down, &up, NULL, NULL, NULL, &lastlpobjval) );
784  downgain = MAX(down - lastlpobjval, 0.0);
785  upgain = MAX(up - lastlpobjval, 0.0);
786  pscostscore = SCIPgetBranchScore(scip, branchcands[c], downgain, upgain);
787 
788  SCIPdebugMessage(" -> strong branching on variable <%s> already performed (down=%g (%+g), up=%g (%+g), pscostscore=%g)\n",
789  SCIPvarGetName(branchcands[c]), down, downgain, up, upgain, pscostscore);
790  }
791  else if( maxninitcands > 0 )
792  {
793  SCIP_Real downsize;
794  SCIP_Real upsize;
795  SCIP_Real size;
796 
797  /* check, if the pseudo cost score of the variable is reliable */
798  downsize = SCIPgetVarPseudocostCountCurrentRun(scip, branchcands[c], SCIP_BRANCHDIR_DOWNWARDS);
799  upsize = SCIPgetVarPseudocostCountCurrentRun(scip, branchcands[c], SCIP_BRANCHDIR_UPWARDS);
800  size = MIN(downsize, upsize);
801 
802  /* determine if variable is considered reliable based on the current reliability setting */
803  /* check fixed number threshold (aka original) reliability first */
804  assert(!branchruledata->usehyptestforreliability || bestpscand >= 0);
805  usesb = FALSE;
806  if( size < reliable )
807  usesb = TRUE;
808  else if( branchruledata->userelerrorforreliability && branchruledata->usehyptestforreliability )
809  {
810  if( !SCIPisVarPscostRelerrorReliable(scip, branchcands[c], relerrorthreshold, clevel) &&
811  !SCIPsignificantVarPscostDifference(scip, branchcands[bestpscand], branchcandsfrac[bestpscand],
812  branchcands[c], branchcandsfrac[c], SCIP_BRANCHDIR_DOWNWARDS, clevel, TRUE) &&
813  !SCIPsignificantVarPscostDifference(scip, branchcands[bestpscand], 1 - branchcandsfrac[bestpscand],
814  branchcands[c], 1 - branchcandsfrac[c], SCIP_BRANCHDIR_UPWARDS, clevel, TRUE) )
815  usesb = TRUE;
816  }
817  /* check if relative error is tolerable */
818  else if( branchruledata->userelerrorforreliability &&
819  !SCIPisVarPscostRelerrorReliable(scip, branchcands[c], relerrorthreshold, clevel))
820  usesb = TRUE;
821  /* check if best pseudo-candidate is significantly better in both directions, use strong-branching otherwise */
822  else if( branchruledata->usehyptestforreliability &&
823  !SCIPsignificantVarPscostDifference(scip, branchcands[bestpscand], branchcandsfrac[bestpscand],
824  branchcands[c], branchcandsfrac[c], SCIP_BRANCHDIR_DOWNWARDS, clevel, TRUE) &&
825  !SCIPsignificantVarPscostDifference(scip, branchcands[bestpscand], 1 - branchcandsfrac[bestpscand],
826  branchcands[c], 1 - branchcandsfrac[c], SCIP_BRANCHDIR_UPWARDS, clevel, TRUE))
827  usesb = TRUE;
828 
829  /* count the number of variables that are completely uninitialized */
830  if( size < 0.1 )
831  nuninitcands++;
832  }
833 
834  /* combine the five score values */
835  score = calcScore(scip, branchruledata, conflictscore, avgconflictscore, conflengthscore, avgconflengthscore,
836  inferencescore, avginferencescore, cutoffscore, avgcutoffscore, pscostscore, avgpscostscore, nlscore, branchcandsfrac[c]);
837 
838  if( usesb )
839  {
840  int j;
841 
842  /* assign a random score to this uninitialized candidate */
843  if( branchruledata->randinitorder )
844  score = SCIPgetRandomReal(0.0, 1.0, &branchruledata->randseed);
845 
846  /* pseudo cost of variable is not reliable: insert candidate in initcands buffer */
847  for( j = ninitcands; j > 0 && score > initcandscores[j-1]; --j )
848  {
849  initcands[j] = initcands[j-1];
850  initcandscores[j] = initcandscores[j-1];
851  }
852  initcands[j] = c;
853  initcandscores[j] = score;
854  ninitcands++;
855  ninitcands = MIN(ninitcands, maxninitcands);
856  }
857  /* in the case of hypothesis reliability, the best pseudo candidate has been determined already */
858  else if( !branchruledata->usehyptestforreliability )
859  {
860  /* variable will keep it's pseudo cost value: check for better score of candidate */
861  if( SCIPisSumGE(scip, score, bestpsscore) )
862  {
863  SCIP_Real fracscore;
864  SCIP_Real domainscore;
865 
866  fracscore = MIN(branchcandsfrac[c], 1.0 - branchcandsfrac[c]);
867  domainscore = -(SCIPvarGetUbLocal(branchcands[c]) - SCIPvarGetLbLocal(branchcands[c]));
868  if( SCIPisSumGT(scip, score, bestpsscore)
869  || SCIPisSumGT(scip, fracscore, bestpsfracscore)
870  || (SCIPisSumGE(scip, fracscore, bestpsfracscore) && domainscore > bestpsdomainscore) )
871  {
872  bestpscand = c;
873  bestpsscore = score;
874  bestpsfracscore = fracscore;
875  bestpsdomainscore = domainscore;
876  }
877  }
878  }
879  }
880 
881  /* in the special case that only the best pseudo candidate was selected for strong branching, skip the strong branching */
882  if( branchruledata->usehyptestforreliability && ninitcands == 1 )
883  {
884  ninitcands = 0;
885  SCIPdebugMessage("Only one single candidate for initialization-->Skipping strong branching\n");
886  }
887 
888  /* initialize unreliable candidates with strong branching until maxlookahead is reached,
889  * search best strong branching candidate
890  */
891  maxlookahead = (SCIP_Real)branchruledata->maxlookahead * (1.0 + (SCIP_Real)nuninitcands/(SCIP_Real)nbranchcands);
892  inititer = branchruledata->inititer;
893  if( inititer == 0 )
894  {
895  SCIP_Longint nlpiterations;
896  SCIP_Longint nlps;
897 
898  /* iteration limit is set to twice the average number of iterations spent to resolve a dual feasible SCIP_LP;
899  * at the first few nodes, this average is not very exact, so we better increase the iteration limit on
900  * these very important nodes
901  */
902  nlpiterations = SCIPgetNDualResolveLPIterations(scip);
903  nlps = SCIPgetNDualResolveLPs(scip);
904  if( nlps == 0 )
905  {
906  nlpiterations = SCIPgetNNodeInitLPIterations(scip);
907  nlps = SCIPgetNNodeInitLPs(scip);
908  if( nlps == 0 )
909  {
910  nlpiterations = 1000;
911  nlps = 1;
912  }
913  }
914  assert(nlps >= 1);
915  inititer = (int)(2*nlpiterations / nlps);
916  inititer = (int)((SCIP_Real)inititer * (1.0 + 20.0/nodenum));
917  inititer = MAX(inititer, 10);
918  inititer = MIN(inititer, 500);
919  }
920 
921  SCIPdebugMessage("strong branching (reliable=%g, %d/%d cands, %d uninit, maxcands=%d, maxlookahead=%g, maxbdchgs=%d, inititer=%d, iterations:%" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", basic:%u)\n",
922  reliable, ninitcands, nbranchcands, nuninitcands, maxninitcands, maxlookahead, maxbdchgs, inititer,
923  SCIPgetNStrongbranchLPIterations(scip), maxnsblpiterations, SCIPisLPSolBasic(scip));
924 
925  bestsbcand = -1;
926  bestsbscore = -SCIPinfinity(scip);
927  bestsbfracscore = -SCIPinfinity(scip);
928  bestsbdomainscore = -SCIPinfinity(scip);
929  bestuninitsbscore = -SCIPinfinity(scip);
930  bestuninitsbcand = -1;
931  lookahead = 0.0;
932  for( i = 0; i < ninitcands && lookahead < maxlookahead && nbdchgs + nbdconflicts < maxbdchgs
933  && (i < (int) maxlookahead || SCIPgetNStrongbranchLPIterations(scip) < maxnsblpiterations); ++i )
934  {
935  SCIP_Real down;
936  SCIP_Real up;
937  SCIP_Real downgain;
938  SCIP_Real upgain;
939  SCIP_Bool downvalid;
940  SCIP_Bool upvalid;
941  SCIP_Longint ndomredsdown;
942  SCIP_Longint ndomredsup;
943  SCIP_Bool lperror;
944  SCIP_Bool downinf;
945  SCIP_Bool upinf;
946  SCIP_Bool downconflict;
947  SCIP_Bool upconflict;
948 
949  /* get candidate number to initialize */
950  c = initcands[i];
951  assert(!SCIPisFeasIntegral(scip, branchcandssol[c]));
952 
953  if( branchruledata->skipbadinitcands )
954  {
955  SCIP_Bool skipsb = FALSE;
956  /* if the current best candidate is a candidate found by strong branching, determine if candidate pseudo-costs are
957  * significantly smaller in at least one direction, in which case we safe the execution of strong-branching for now
958  */
959  if( bestsbscore > bestpsscore && bestsbscore > bestuninitsbscore && bestsbupvalid && bestsbdownvalid )
960  {
961  assert(bestsbcand != -1);
962  assert(bestsbup != SCIP_INVALID && bestsbdown != SCIP_INVALID); /*lint !e777 lint doesn't like comparing floats */
963 
964  /* test if the variable is unlikely to produce a better gain than the currently best one. Skip strong-branching
965  * in such a case
966  */
967  if( SCIPpscostThresholdProbabilityTest(scip, branchcands[c], branchcandsfrac[c], bestsbdown,
968  SCIP_BRANCHDIR_DOWNWARDS, clevel)
969  || SCIPpscostThresholdProbabilityTest(scip, branchcands[c], 1.0 - branchcandsfrac[c], bestsbup,
970  SCIP_BRANCHDIR_UPWARDS, clevel) )
971  skipsb = TRUE;
972  }
973  /* the currently best candidate is also a pseudo-candidate; apply significance test and skip candidate if it
974  * is significantly worse in at least one direction
975  */
976  else if( bestpscand != -1 && bestpsscore > bestuninitsbscore )
977  {
978  if( SCIPsignificantVarPscostDifference(scip, branchcands[bestpscand], branchcandsfrac[bestpscand],
979  branchcands[c], branchcandsfrac[c], SCIP_BRANCHDIR_DOWNWARDS, clevel, TRUE)
980  || SCIPsignificantVarPscostDifference(scip, branchcands[bestpscand], 1.0 - branchcandsfrac[bestpscand],
981  branchcands[c], 1.0 - branchcandsfrac[c], SCIP_BRANCHDIR_UPWARDS, clevel, TRUE) )
982  skipsb = TRUE;
983  }
984  /* compare against the best init cand that has been skipped already */
985  else if( bestuninitsbcand != -1 )
986  {
987  if( SCIPsignificantVarPscostDifference(scip, branchcands[bestuninitsbcand], branchcandsfrac[bestuninitsbcand],
988  branchcands[c], branchcandsfrac[c], SCIP_BRANCHDIR_DOWNWARDS, clevel, TRUE)
989  || SCIPsignificantVarPscostDifference(scip, branchcands[bestuninitsbcand], 1.0 - branchcandsfrac[bestuninitsbcand],
990  branchcands[c], 1.0 - branchcandsfrac[c], SCIP_BRANCHDIR_UPWARDS, clevel, TRUE) )
991  skipsb = TRUE;
992  }
993 
994  /* skip candidate, update the best score of an unitialized candidate */
995  if( skipsb )
996  {
997  if( bestuninitsbcand == -1 )
998  {
999  bestuninitsbcand = c;
1000  bestuninitsbscore = initcandscores[i];
1001  }
1002  continue;
1003  }
1004  }
1005  SCIPdebugMessage("init pseudo cost (%g/%g) of <%s> at %g (score:%g) with strong branching (%d iterations) -- %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT " iterations\n",
1008  SCIPvarGetName(branchcands[c]), branchcandssol[c], initcandscores[i],
1009  inititer, SCIPgetNStrongbranchLPIterations(scip), maxnsblpiterations);
1010 
1011  /* use strong branching on candidate */
1012  if( !initstrongbranching )
1013  {
1014  initstrongbranching = TRUE;
1015 
1016  SCIP_CALL( SCIPstartStrongbranch(scip, propagate) );
1017 
1018  /* create arrays for probing-like bound tightening */
1019  if( probingbounds )
1020  {
1021  SCIP_CALL( SCIPallocBufferArray(scip, &newlbs, nvars) );
1022  SCIP_CALL( SCIPallocBufferArray(scip, &newubs, nvars) );
1023  }
1024  }
1025 
1026  if( propagate )
1027  {
1028  /* apply strong branching */
1029  SCIP_CALL( SCIPgetVarStrongbranchWithPropagation(scip, branchcands[c], branchcandssol[c], lpobjval, inititer,
1030  branchruledata->maxproprounds, &down, &up, &downvalid, &upvalid, &ndomredsdown, &ndomredsup, &downinf, &upinf,
1031  &downconflict, &upconflict, &lperror, newlbs, newubs) );
1032  }
1033  else
1034  {
1035  /* apply strong branching */
1036  SCIP_CALL( SCIPgetVarStrongbranchFrac(scip, branchcands[c], inititer,
1037  &down, &up, &downvalid, &upvalid, &downinf, &upinf, &downconflict, &upconflict, &lperror) );
1038 
1039  ndomredsdown = ndomredsup = 0;
1040  }
1041 
1042  /* check for an error in strong branching */
1043  if( lperror )
1044  {
1045  if( !SCIPisStopped(scip) )
1046  {
1048  "(node %" SCIP_LONGINT_FORMAT ") error in strong branching call for variable <%s> with solution %g\n",
1049  SCIPgetNNodes(scip), SCIPvarGetName(branchcands[c]), branchcandssol[c]);
1050  }
1051  break;
1052  }
1053 
1054  /* Strong branching might have found a new primal solution which updated the cutoff bound. In this case, the
1055  * provedbound computed before can be higher than the cutoffbound and the current node can be cut off.
1056  * Additionally, also if the value for the current best candidate is valid and exceeds the new cutoff bound,
1057  * we want to change the domain of this variable rather than branching on it.
1058  */
1059  if( SCIPgetBestSol(scip) != NULL && SCIPsolGetIndex(SCIPgetBestSol(scip)) != bestsolidx )
1060  {
1061  bestsolidx = SCIPsolGetIndex(SCIPgetBestSol(scip));
1062 
1063  SCIPdebugMessage(" -> strong branching on variable <%s> lead to a new incumbent\n",
1064  SCIPvarGetName(branchcands[c]));
1065 
1066  /* proved bound for current node is larger than new cutoff bound -> cut off current node */
1067  if( SCIPisGE(scip, provedbound, SCIPgetCutoffbound(scip)) )
1068  {
1069  SCIPdebugMessage(" -> node can be cut off (provedbound=%g, cutoff=%g)\n", provedbound, SCIPgetCutoffbound(scip));
1070 
1071  *result = SCIP_CUTOFF;
1072  break; /* terminate initialization loop, because node is infeasible */
1073  }
1074  /* proved bound for down child of best candidate is larger than cutoff bound
1075  * -> increase lower bound of best candidate
1076  * we must only do this if the LP is complete, i.e., we are not doing column generation
1077  */
1078 
1079  else if( bestsbcand != -1 && allcolsinlp )
1080  {
1081  if( !bestsbdowncutoff && bestsbdownvalid && SCIPisGE(scip, bestsbdown, SCIPgetCutoffbound(scip)) )
1082  {
1083  bestsbdowncutoff = TRUE;
1084 
1085  SCIPdebugMessage(" -> valid dual bound for down child of best candidate <%s> is higher than new cutoff bound (valid=%u, bestsbdown=%g, cutoff=%g)\n",
1086  SCIPvarGetName(branchcands[bestsbcand]), bestsbdownvalid, bestsbdown, SCIPgetCutoffbound(scip));
1087 
1088  SCIPdebugMessage(" -> increase lower bound of best candidate <%s> to %g\n",
1089  SCIPvarGetName(branchcands[bestsbcand]), SCIPfeasCeil(scip, branchcandssol[bestsbcand]));
1090 
1091  SCIP_CALL( addBdchg(scip, &bdchginds, &bdchgtypes, &bdchgbounds, &nbdchgs, SCIPvarGetProbindex(branchcands[bestsbcand]),
1092  SCIP_BOUNDTYPE_LOWER, SCIPfeasCeil(scip, branchcandssol[bestsbcand])) );
1093  }
1094  /* proved bound for up child of best candidate is larger than cutoff bound -> decrease upper bound of best candidate */
1095  else if( !bestsbupcutoff && bestsbupvalid && SCIPisGE(scip, bestsbup, SCIPgetCutoffbound(scip)) )
1096  {
1097  bestsbupcutoff = TRUE;
1098 
1099  SCIPdebugMessage(" -> valid dual bound for up child of best candidate <%s> is higher than new cutoff bound (valid=%u, bestsbup=%g, cutoff=%g)\n",
1100  SCIPvarGetName(branchcands[bestsbcand]), bestsbupvalid, bestsbup, SCIPgetCutoffbound(scip));
1101 
1102  SCIPdebugMessage(" -> decrease upper bound of best candidate <%s> to %g\n",
1103  SCIPvarGetName(branchcands[bestsbcand]), SCIPfeasFloor(scip, branchcandssol[bestsbcand]));
1104 
1105  SCIP_CALL( addBdchg(scip, &bdchginds, &bdchgtypes, &bdchgbounds, &nbdchgs, SCIPvarGetProbindex(branchcands[bestsbcand]),
1106  SCIP_BOUNDTYPE_UPPER, SCIPfeasFloor(scip, branchcandssol[bestsbcand])) );
1107  }
1108  }
1109  }
1110 
1111  /* evaluate strong branching */
1112  down = MAX(down, lpobjval);
1113  up = MAX(up, lpobjval);
1114  downgain = down - lpobjval;
1115  upgain = up - lpobjval;
1116  assert(!allcolsinlp || exactsolve || !downvalid || downinf == SCIPisGE(scip, down, SCIPgetCutoffbound(scip)));
1117  assert(!allcolsinlp || exactsolve || !upvalid || upinf == SCIPisGE(scip, up, SCIPgetCutoffbound(scip)));
1118  assert(downinf || !downconflict);
1119  assert(upinf || !upconflict);
1120 
1121  /* @todo: store pseudo cost only for valid bounds?
1122  * depending on the user parameter choice of storesemiinitcosts, pseudo costs are also updated in single directions,
1123  * if the node in the other direction was infeasible or cut off
1124  */
1125  if( !downinf && (!upinf || branchruledata->storesemiinitcosts) )
1126  {
1127  /* update pseudo cost values */
1128  SCIP_CALL( SCIPupdateVarPseudocost(scip, branchcands[c], 0.0 - branchcandsfrac[c], downgain, 1.0) );
1129  }
1130  if( !upinf && (!downinf || branchruledata->storesemiinitcosts) )
1131  {
1132  SCIP_CALL( SCIPupdateVarPseudocost(scip, branchcands[c], 1.0 - branchcandsfrac[c], upgain, 1.0) );
1133  }
1134 
1135  /* the minimal lower bound of both children is a proved lower bound of the current subtree */
1136  if( allcolsinlp && !exactsolve && downvalid && upvalid )
1137  {
1138  SCIP_Real minbound;
1139 
1140  minbound = MIN(down, up);
1141  provedbound = MAX(provedbound, minbound);
1142  assert((downinf && upinf) || SCIPisLT(scip, provedbound, SCIPgetCutoffbound(scip)));
1143 
1144  /* save probing-like bounds detected during strong branching */
1145  if( probingbounds )
1146  {
1147  int v;
1148 
1149  assert(newlbs != NULL);
1150  assert(newubs != NULL);
1151 
1152  for( v = 0; v < nvars; ++v )
1153  {
1154  if( SCIPisGT(scip, newlbs[v], SCIPvarGetLbLocal(vars[v])) )
1155  {
1156  SCIPdebugMessage("better lower bound for variable <%s>: %.9g -> %.9g (by strongbranching on <%s>)\n",
1157  SCIPvarGetName(vars[v]), SCIPvarGetLbLocal(vars[v]), newlbs[v], SCIPvarGetName(branchcands[c]));
1158 
1159  SCIP_CALL( addBdchg(scip, &bdchginds, &bdchgtypes, &bdchgbounds, &nbdchgs, v,
1160  SCIP_BOUNDTYPE_LOWER, newlbs[v]) );
1161  }
1162  if( SCIPisLT(scip, newubs[v], SCIPvarGetUbLocal(vars[v])) )
1163  {
1164  SCIPdebugMessage("better upper bound for variable <%s>: %.9g -> %.9g (by strongbranching on <%s>)\n",
1165  SCIPvarGetName(vars[v]), SCIPvarGetUbLocal(vars[v]), newubs[v], SCIPvarGetName(branchcands[c]));
1166 
1167  SCIP_CALL( addBdchg(scip, &bdchginds, &bdchgtypes, &bdchgbounds, &nbdchgs, v,
1168  SCIP_BOUNDTYPE_UPPER, newubs[v]) );
1169  }
1170  }
1171  }
1172  }
1173 
1174  /* check if there are infeasible roundings */
1175  if( downinf || upinf )
1176  {
1177  assert(allcolsinlp || propagate);
1178  assert(!exactsolve);
1179 
1180  /* if for both infeasibilities, a conflict constraint was created, we don't need to fix the variable by hand,
1181  * but better wait for the next propagation round to fix them as an inference, and potentially produce a
1182  * cutoff that can be analyzed
1183  */
1184  if( allowaddcons && downinf == downconflict && upinf == upconflict )
1185  {
1186  SCIPdebugMessage(" -> variable <%s> is infeasible in %s: conflict constraint added\n",
1187  SCIPvarGetName(branchcands[c]),
1188  downinf && upinf ? "both directions" : (downinf ? "downward branch" : "upward branch"));
1189  *result = SCIP_CONSADDED;
1190  nbdconflicts++;
1191  if( (downinf && upinf) || (nbdchgs + nbdconflicts >= maxbdchgs) )
1192  break; /* terminate initialization loop, because enough roundings are performed or a cutoff was found */
1193  }
1194  else if( downinf && upinf )
1195  {
1196  /* both roundings are infeasible -> node is infeasible */
1197  SCIPdebugMessage(" -> variable <%s> is infeasible in both directions (conflict: %u/%u)\n",
1198  SCIPvarGetName(branchcands[c]), downconflict, upconflict);
1199  *result = SCIP_CUTOFF;
1200  break; /* terminate initialization loop, because node is infeasible */
1201  }
1202  else
1203  {
1204  /* rounding is infeasible in one direction -> round variable in other direction */
1205  SCIPdebugMessage(" -> variable <%s> is infeasible in %s branch (conflict: %u/%u)\n",
1206  SCIPvarGetName(branchcands[c]), downinf ? "downward" : "upward", downconflict, upconflict);
1207  SCIP_CALL( addBdchg(scip, &bdchginds, &bdchgtypes, &bdchgbounds, &nbdchgs, SCIPvarGetProbindex(branchcands[c]),
1209  (downinf ? SCIPfeasCeil(scip, branchcandssol[c]) : SCIPfeasFloor(scip, branchcandssol[c]))) );
1210  if( nbdchgs + nbdconflicts >= maxbdchgs )
1211  break; /* terminate initialization loop, because enough roundings are performed */
1212  }
1213  }
1214  else
1215  {
1216  SCIP_Real conflictscore;
1217  SCIP_Real conflengthscore;
1218  SCIP_Real inferencescore;
1219  SCIP_Real cutoffscore;
1220  SCIP_Real pscostscore;
1221  SCIP_Real nlscore;
1222  SCIP_Real score;
1223 
1224  /* check for a better score */
1225  conflictscore = SCIPgetVarConflictScore(scip, branchcands[c]);
1226  conflengthscore = SCIPgetVarConflictlengthScore(scip, branchcands[c]);
1227  nlscore = calcNlscore(scip, branchruledata->nlcount, branchruledata->nlcountmax, SCIPvarGetProbindex(branchcands[c]));
1228 
1229  /* optionally, use only local information obtained via strong branching for this candidate, i.e., local
1230  * domain reductions and no cutoff score
1231  */
1232  inferencescore = branchruledata->usesblocalinfo ? SCIPgetBranchScore(scip, branchcands[c], (SCIP_Real)ndomredsdown, (SCIP_Real)ndomredsup)
1233  : SCIPgetVarAvgInferenceScore(scip, branchcands[c]);
1234  cutoffscore = branchruledata->usesblocalinfo ? 0.0 : SCIPgetVarAvgCutoffScore(scip, branchcands[c]);
1235  pscostscore = SCIPgetBranchScore(scip, branchcands[c], downgain, upgain);
1236 
1237  score = calcScore(scip, branchruledata, conflictscore, avgconflictscore, conflengthscore, avgconflengthscore,
1238  inferencescore, avginferencescore, cutoffscore, avgcutoffscore, pscostscore, avgpscostscore, nlscore, branchcandsfrac[c]);
1239 
1240  if( SCIPisSumGE(scip, score, bestsbscore) )
1241  {
1242  SCIP_Real fracscore;
1243  SCIP_Real domainscore;
1244 
1245  fracscore = MIN(branchcandsfrac[c], 1.0 - branchcandsfrac[c]);
1246  domainscore = -(SCIPvarGetUbLocal(branchcands[c]) - SCIPvarGetLbLocal(branchcands[c]));
1247  if( SCIPisSumGT(scip, score, bestsbscore)
1248  || SCIPisSumGT(scip, fracscore, bestsbfracscore)
1249  || (SCIPisSumGE(scip, fracscore, bestsbfracscore) && domainscore > bestsbdomainscore) )
1250  {
1251  bestsbcand = c;
1252  bestsbscore = score;
1253  bestsbdown = down;
1254  bestsbup = up;
1255  bestsbdownvalid = downvalid;
1256  bestsbupvalid = upvalid;
1257  bestsbdowncutoff = FALSE;
1258  bestsbupcutoff = FALSE;
1259  bestsbfracscore = fracscore;
1260  bestsbdomainscore = domainscore;
1261  lookahead = 0.0;
1262  }
1263  else
1264  lookahead += 0.5;
1265  }
1266  else
1267  lookahead += 1.0;
1268 
1269  SCIPdebugMessage(" -> variable <%s> (solval=%g, down=%g (%+g,valid=%u), up=%g (%+g,valid=%u), score=%g/ %g/%g %g/%g -> %g)\n",
1270  SCIPvarGetName(branchcands[c]), branchcandssol[c], down, downgain, downvalid, up, upgain, upvalid,
1271  pscostscore, conflictscore, conflengthscore, inferencescore, cutoffscore, score);
1272  }
1273  }
1274 #ifdef SCIP_DEBUG
1275  if( bestsbcand >= 0 )
1276  {
1277  SCIPdebugMessage(" -> best: <%s> (%g / %g / %g), lookahead=%g/%g\n",
1278  SCIPvarGetName(branchcands[bestsbcand]), bestsbscore, bestsbfracscore, bestsbdomainscore,
1279  lookahead, maxlookahead);
1280  }
1281 #endif
1282 
1283  if( initstrongbranching )
1284  {
1285  if( probingbounds )
1286  {
1287  assert(newlbs != NULL);
1288  assert(newubs != NULL);
1289 
1290  SCIPfreeBufferArray(scip, &newubs);
1291  SCIPfreeBufferArray(scip, &newlbs);
1292  }
1293 
1294  SCIP_CALL( SCIPendStrongbranch(scip) );
1295 
1297  {
1298  assert(SCIPhasCurrentNodeLP(scip));
1299  *result = SCIP_CUTOFF;
1300  }
1301  }
1302 
1303  if( *result != SCIP_CUTOFF )
1304  {
1305  /* get the score of the best uninitialized strong branching candidate */
1306  if( i < ninitcands && bestuninitsbcand == -1 )
1307  bestuninitsbscore = initcandscores[i];
1308 
1309  /* if the best pseudo cost candidate is better than the best uninitialized strong branching candidate,
1310  * compare it to the best initialized strong branching candidate
1311  */
1312  if( bestpsscore > bestuninitsbscore && SCIPisSumGT(scip, bestpsscore, bestsbscore) )
1313  {
1314  bestcand = bestpscand;
1315  bestisstrongbranch = FALSE;
1316  }
1317  else if( bestsbcand >= 0 )
1318  {
1319  bestcand = bestsbcand;
1320  bestisstrongbranch = TRUE;
1321  }
1322  else
1323  {
1324  /* no candidate was initialized, and the best score is the one of the first candidate in the initialization
1325  * queue
1326  */
1327  assert(ninitcands >= 1);
1328  bestcand = initcands[0];
1329  bestisstrongbranch = FALSE;
1330  }
1331 
1332  /* update lower bound of current node */
1333  if( allcolsinlp && !exactsolve )
1334  {
1335  assert(SCIPisLT(scip, provedbound, SCIPgetCutoffbound(scip)));
1336  SCIP_CALL( SCIPupdateNodeLowerbound(scip, SCIPgetCurrentNode(scip), provedbound) );
1337  }
1338  }
1339 
1340  /* apply domain reductions */
1341  if( nbdchgs > 0 )
1342  {
1343  if( *result != SCIP_CUTOFF )
1344  {
1345  SCIP_CALL( applyBdchgs(scip, vars, bdchginds, bdchgtypes, bdchgbounds, nbdchgs, result) );
1346  if( *result != SCIP_CUTOFF )
1347  *result = SCIP_REDUCEDDOM;
1348  }
1349  freeBdchgs(scip, &bdchginds, &bdchgtypes, &bdchgbounds, &nbdchgs);
1350  }
1351 
1352  /* free buffer for the unreliable candidates */
1353  SCIPfreeBufferArray(scip, &initcandscores);
1354  SCIPfreeBufferArray(scip, &initcands);
1355  }
1356 
1357  /* if no domain could be reduced, create the branching */
1358  if( *result != SCIP_CUTOFF && *result != SCIP_REDUCEDDOM && *result != SCIP_CONSADDED && executebranch )
1359  {
1360  SCIP_NODE* downchild;
1361  SCIP_NODE* upchild;
1362  SCIP_VAR* var;
1363  SCIP_Real val;
1364 
1365  assert(*result == SCIP_DIDNOTRUN);
1366  assert(0 <= bestcand && bestcand < nbranchcands);
1367  assert(!SCIPisFeasIntegral(scip, branchcandssol[bestcand]));
1368  assert(SCIPisLT(scip, provedbound, SCIPgetCutoffbound(scip)));
1369  assert(!bestsbdowncutoff && !bestsbupcutoff);
1370 
1371  var = branchcands[bestcand];
1372  val = branchcandssol[bestcand];
1373 
1374  /* perform the branching */
1375  SCIPdebugMessage(" -> %d (%d) cands, sel cand %d: var <%s> (sol=%g, down=%g (%+g), up=%g (%+g), sb=%u, psc=%g/%g [%g])\n",
1376  nbranchcands, ninitcands, bestcand, SCIPvarGetName(var), branchcandssol[bestcand],
1377  bestsbdown, bestsbdown - lpobjval, bestsbup, bestsbup - lpobjval, bestisstrongbranch,
1380  SCIPgetVarPseudocostScoreCurrentRun(scip, var, branchcandssol[bestcand]));
1381  SCIP_CALL( SCIPbranchVarVal(scip, var, val, &downchild, NULL, &upchild) );
1382  assert(downchild != NULL);
1383  assert(upchild != NULL);
1384 
1385  /* update the lower bounds in the children */
1386  if( bestisstrongbranch && allcolsinlp && !exactsolve )
1387  {
1388  if( bestsbdownvalid )
1389  {
1390  assert(SCIPisLT(scip, bestsbdown, SCIPgetCutoffbound(scip)));
1391  SCIP_CALL( SCIPupdateNodeLowerbound(scip, downchild, bestsbdown) );
1392  assert(SCIPisGE(scip, SCIPgetNodeLowerbound(scip, downchild), provedbound));
1393  }
1394  if( bestsbupvalid )
1395  {
1396  assert(SCIPisLT(scip, bestsbup, SCIPgetCutoffbound(scip)));
1397  SCIP_CALL( SCIPupdateNodeLowerbound(scip, upchild, bestsbup) );
1398  assert(SCIPisGE(scip, SCIPgetNodeLowerbound(scip, upchild), provedbound));
1399  }
1400  }
1401 
1402  SCIPdebugMessage(" -> down child's lowerbound: %g\n", SCIPnodeGetLowerbound(downchild));
1403  SCIPdebugMessage(" -> up child's lowerbound : %g\n", SCIPnodeGetLowerbound(upchild));
1404 
1406 
1407  *result = SCIP_BRANCHED;
1408  }
1409 
1410  return SCIP_OKAY;
1411 }
1412 
1413 
1414 /*
1415  * Callback methods
1416  */
1417 
1418 /** copy method for branchrule plugins (called when SCIP copies plugins) */
1419 static
1420 SCIP_DECL_BRANCHCOPY(branchCopyRelpscost)
1421 { /*lint --e{715}*/
1422  assert(scip != NULL);
1423  assert(branchrule != NULL);
1424  assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0);
1425 
1426  /* call inclusion method of branchrule */
1428 
1429  return SCIP_OKAY;
1430 }
1431 
1432 /** destructor of branching rule to free user data (called when SCIP is exiting) */
1433 static
1434 SCIP_DECL_BRANCHFREE(branchFreeRelpscost)
1435 { /*lint --e{715}*/
1436  SCIP_BRANCHRULEDATA* branchruledata;
1438  /* free branching rule data */
1439  branchruledata = SCIPbranchruleGetData(branchrule);
1440  SCIPfreeMemory(scip, &branchruledata);
1441  SCIPbranchruleSetData(branchrule, NULL);
1442 
1443  return SCIP_OKAY;
1444 }
1445 
1446 
1447 /** solving process initialization method of branching rule (called when branch and bound process is about to begin) */
1448 static
1449 SCIP_DECL_BRANCHINITSOL(branchInitsolRelpscost)
1450 { /*lint --e{715}*/
1451  SCIP_BRANCHRULEDATA* branchruledata;
1453  /* initialize branching rule data */
1454  branchruledata = SCIPbranchruleGetData(branchrule);
1455  branchruledata->nlcount = NULL;
1456  branchruledata->nlcountsize = 0;
1457  branchruledata->nlcountmax = 1;
1458 
1459  branchruledata->randseed = (unsigned int)branchruledata->startrandseed;
1460 
1461  return SCIP_OKAY;
1462 }
1463 
1464 
1465 /** solving process deinitialization method of branching rule (called before branch and bound process data is freed) */
1466 static
1467 SCIP_DECL_BRANCHEXITSOL(branchExitsolRelpscost)
1468 { /*lint --e{715}*/
1469  SCIP_BRANCHRULEDATA* branchruledata;
1471  /* free memory in branching rule data */
1472  branchruledata = SCIPbranchruleGetData(branchrule);
1473  SCIPfreeBlockMemoryArrayNull(scip, &branchruledata->nlcount, branchruledata->nlcountsize);
1474 
1475  return SCIP_OKAY;
1476 }
1477 
1478 
1479 /** branching execution method for fractional LP solutions */
1480 static
1481 SCIP_DECL_BRANCHEXECLP(branchExeclpRelpscost)
1482 { /*lint --e{715}*/
1483  SCIP_VAR** tmplpcands;
1484  SCIP_VAR** lpcands;
1485  SCIP_Real* tmplpcandssol;
1486  SCIP_Real* lpcandssol;
1487  SCIP_Real* tmplpcandsfrac;
1488  SCIP_Real* lpcandsfrac;
1489  int nlpcands;
1490 
1491  assert(branchrule != NULL);
1492  assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0);
1493  assert(scip != NULL);
1494  assert(result != NULL);
1495 
1496  SCIPdebugMessage("Execlp method of relpscost branching in node %llu\n", SCIPnodeGetNumber(SCIPgetCurrentNode(scip)));
1497 
1498  /* get branching candidates */
1499  SCIP_CALL( SCIPgetLPBranchCands(scip, &tmplpcands, &tmplpcandssol, &tmplpcandsfrac, NULL, &nlpcands, NULL) );
1500  assert(nlpcands > 0);
1501 
1502  /* copy LP banching candidates and solution values, because they will be updated w.r.t. the strong branching LP
1503  * solution
1504  */
1505  SCIP_CALL( SCIPduplicateBufferArray(scip, &lpcands, tmplpcands, nlpcands) );
1506  SCIP_CALL( SCIPduplicateBufferArray(scip, &lpcandssol, tmplpcandssol, nlpcands) );
1507  SCIP_CALL( SCIPduplicateBufferArray(scip, &lpcandsfrac, tmplpcandsfrac, nlpcands) );
1508 
1509  /* execute branching rule */
1510  SCIP_CALL( execRelpscost(scip, branchrule, allowaddcons, lpcands, lpcandssol, lpcandsfrac, nlpcands, TRUE, result) );
1511 
1512  SCIPfreeBufferArray(scip, &lpcandsfrac);
1513  SCIPfreeBufferArray(scip, &lpcandssol);
1514  SCIPfreeBufferArray(scip, &lpcands);
1515 
1516  return SCIP_OKAY;
1517 }
1518 
1519 
1520 /*
1521  * branching specific interface methods
1522  */
1523 
1524 /** creates the reliable pseudo cost branching rule and includes it in SCIP */
1526  SCIP* scip /**< SCIP data structure */
1527  )
1529  SCIP_BRANCHRULEDATA* branchruledata;
1530  SCIP_BRANCHRULE* branchrule;
1531 
1532  /* create relpscost branching rule data */
1533  SCIP_CALL( SCIPallocMemory(scip, &branchruledata) );
1534 
1535  /* include branching rule */
1537  BRANCHRULE_MAXDEPTH, BRANCHRULE_MAXBOUNDDIST, branchruledata) );
1538 
1539  assert(branchrule != NULL);
1540 
1541  /* set non-fundamental callbacks via specific setter functions*/
1542  SCIP_CALL( SCIPsetBranchruleCopy(scip, branchrule, branchCopyRelpscost) );
1543  SCIP_CALL( SCIPsetBranchruleFree(scip, branchrule, branchFreeRelpscost) );
1544  SCIP_CALL( SCIPsetBranchruleInitsol(scip, branchrule, branchInitsolRelpscost) );
1545  SCIP_CALL( SCIPsetBranchruleExitsol(scip, branchrule, branchExitsolRelpscost) );
1546  SCIP_CALL( SCIPsetBranchruleExecLp(scip, branchrule, branchExeclpRelpscost) );
1547 
1548  /* relpscost branching rule parameters */
1550  "branching/relpscost/conflictweight",
1551  "weight in score calculations for conflict score",
1552  &branchruledata->conflictweight, TRUE, DEFAULT_CONFLICTWEIGHT, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
1554  "branching/relpscost/conflictlengthweight",
1555  "weight in score calculations for conflict length score",
1556  &branchruledata->conflengthweight, TRUE, DEFAULT_CONFLENGTHWEIGHT, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
1558  "branching/relpscost/inferenceweight",
1559  "weight in score calculations for inference score",
1560  &branchruledata->inferenceweight, TRUE, DEFAULT_INFERENCEWEIGHT, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
1562  "branching/relpscost/cutoffweight",
1563  "weight in score calculations for cutoff score",
1564  &branchruledata->cutoffweight, TRUE, DEFAULT_CUTOFFWEIGHT, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
1566  "branching/relpscost/pscostweight",
1567  "weight in score calculations for pseudo cost score",
1568  &branchruledata->pscostweight, TRUE, DEFAULT_PSCOSTWEIGHT, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
1570  "branching/relpscost/nlscoreweight",
1571  "weight in score calculations for nlcount score",
1572  &branchruledata->nlscoreweight, TRUE, DEFAULT_NLSCOREWEIGHT, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
1574  "branching/relpscost/minreliable",
1575  "minimal value for minimum pseudo cost size to regard pseudo cost value as reliable",
1576  &branchruledata->minreliable, TRUE, DEFAULT_MINRELIABLE, 0.0, SCIP_REAL_MAX, NULL, NULL) );
1578  "branching/relpscost/maxreliable",
1579  "maximal value for minimum pseudo cost size to regard pseudo cost value as reliable",
1580  &branchruledata->maxreliable, TRUE, DEFAULT_MAXRELIABLE, 0.0, SCIP_REAL_MAX, NULL, NULL) );
1582  "branching/relpscost/sbiterquot",
1583  "maximal fraction of strong branching LP iterations compared to node relaxation LP iterations",
1584  &branchruledata->sbiterquot, FALSE, DEFAULT_SBITERQUOT, 0.0, SCIP_REAL_MAX, NULL, NULL) );
1585  SCIP_CALL( SCIPaddIntParam(scip,
1586  "branching/relpscost/sbiterofs",
1587  "additional number of allowed strong branching LP iterations",
1588  &branchruledata->sbiterofs, FALSE, DEFAULT_SBITEROFS, 0, INT_MAX, NULL, NULL) );
1589  SCIP_CALL( SCIPaddIntParam(scip,
1590  "branching/relpscost/maxlookahead",
1591  "maximal number of further variables evaluated without better score",
1592  &branchruledata->maxlookahead, TRUE, DEFAULT_MAXLOOKAHEAD, 1, INT_MAX, NULL, NULL) );
1593  SCIP_CALL( SCIPaddIntParam(scip,
1594  "branching/relpscost/initcand",
1595  "maximal number of candidates initialized with strong branching per node",
1596  &branchruledata->initcand, FALSE, DEFAULT_INITCAND, 0, INT_MAX, NULL, NULL) );
1597  SCIP_CALL( SCIPaddIntParam(scip,
1598  "branching/relpscost/inititer",
1599  "iteration limit for strong branching initializations of pseudo cost entries (0: auto)",
1600  &branchruledata->inititer, FALSE, DEFAULT_INITITER, 0, INT_MAX, NULL, NULL) );
1601  SCIP_CALL( SCIPaddIntParam(scip,
1602  "branching/relpscost/maxbdchgs",
1603  "maximal number of bound tightenings before the node is reevaluated (-1: unlimited)",
1604  &branchruledata->maxbdchgs, TRUE, DEFAULT_MAXBDCHGS, -1, INT_MAX, NULL, NULL) );
1605  SCIP_CALL( SCIPaddIntParam(scip,
1606  "branching/relpscost/maxproprounds",
1607  "maximum number of propagation rounds to be performed during strong branching before solving the LP (-1: no limit, -2: parameter settings)",
1608  &branchruledata->maxproprounds, TRUE, DEFAULT_MAXPROPROUNDS, -2, INT_MAX, NULL, NULL) );
1610  "branching/relpscost/probingbounds",
1611  "should valid bounds be identified in a probing-like fashion during strong branching (only with propagation)?",
1612  &branchruledata->probingbounds, TRUE, DEFAULT_PROBINGBOUNDS, NULL, NULL) );
1613 
1614  SCIP_CALL( SCIPaddBoolParam(scip, "branching/relpscost/userelerrorreliability",
1615  "should reliability be based on relative errors?", &branchruledata->userelerrorforreliability, TRUE, DEFAULT_USERELERRORFORRELIABILITY,
1616  NULL, NULL) );
1617 
1618  SCIP_CALL( SCIPaddRealParam(scip, "branching/relpscost/lowerrortol", "low relative error tolerance for reliability",
1619  &branchruledata->lowerrortol, TRUE, DEFAULT_LOWERRORTOL, 0.0, SCIP_REAL_MAX, NULL, NULL) );
1620 
1621  SCIP_CALL( SCIPaddRealParam(scip, "branching/relpscost/higherrortol", "high relative error tolerance for reliability",
1622  &branchruledata->higherrortol, TRUE, DEFAULT_HIGHERRORTOL, 0.0, SCIP_REAL_MAX, NULL, NULL) );
1623 
1624  SCIP_CALL( SCIPaddBoolParam(scip, "branching/relpscost/storesemiinitcosts",
1625  "should strong branching result be considered for pseudo costs if the other direction was infeasible?",
1626  &branchruledata->storesemiinitcosts, TRUE, DEFAULT_STORESEMIINITCOSTS,
1627  NULL, NULL) );
1628 
1629  SCIP_CALL( SCIPaddBoolParam(scip, "branching/relpscost/usesblocalinfo",
1630  "should the scoring function use only local cutoff and inference information obtained for strong branching candidates?",
1631  &branchruledata->usesblocalinfo, TRUE, DEFAULT_USESBLOCALINFO,
1632  NULL, NULL) );
1633 
1634  SCIP_CALL( SCIPaddBoolParam(scip, "branching/relpscost/usehyptestforreliability",
1635  "should the strong branching decision be based on a hypothesis test?",
1636  &branchruledata->usehyptestforreliability, TRUE, DEFAULT_USEHYPTESTFORRELIABILITY,
1637  NULL, NULL) );
1638 
1639  SCIP_CALL( SCIPaddBoolParam(scip, "branching/relpscost/usedynamicconfidence",
1640  "should the confidence level be adjusted dynamically?",
1641  &branchruledata->usedynamicconfidence, TRUE, DEFAULT_USEDYNAMICCONFIDENCE,
1642  NULL, NULL) );
1643  SCIP_CALL( SCIPaddBoolParam(scip, "branching/relpscost/skipbadinitcands",
1644  "should branching rule skip candidates that have a low probability to "
1645  "be better than the best strong-branching or pseudo-candidate?",
1646  &branchruledata->skipbadinitcands, TRUE, DEFAULT_SKIPBADINITCANDS,
1647  NULL, NULL) );
1648  SCIP_CALL( SCIPaddIntParam(scip,
1649  "branching/relpscost/confidencelevel",
1650  "the confidence level for statistical methods, between 0 (Min) and 4 (Max).",
1651  &branchruledata->confidencelevel, TRUE, DEFAULT_CONFIDENCELEVEL, 0, 4, NULL, NULL) );
1652 
1653  SCIP_CALL( SCIPaddBoolParam(scip, "branching/relpscost/randinitorder",
1654  "should candidates be initialized in randomized order?",
1655  &branchruledata->randinitorder, TRUE, DEFAULT_RANDINITORDER,
1656  NULL, NULL) );
1657  SCIP_CALL( SCIPaddIntParam(scip, "branching/relpscost/startrandseed", "start seed for random number generation",
1658  &branchruledata->startrandseed, TRUE, DEFAULT_STARTRANDSEED, 0, INT_MAX, NULL, NULL) );
1659 
1660  return SCIP_OKAY;
1661 }
1662 
1663 /** execution reliability pseudo cost branching with the given branching candidates */
1665  SCIP* scip, /**< SCIP data structure */
1666  SCIP_Bool allowaddcons, /**< is the branching rule allowed to add constraints to the current node
1667  * in order to cut off the current solution instead of creating a branching? */
1668  SCIP_VAR** branchcands, /**< branching candidates */
1669  SCIP_Real* branchcandssol, /**< solution value for the branching candidates */
1670  SCIP_Real* branchcandsfrac, /**< fractional part of the branching candidates */
1671  int nbranchcands, /**< number of branching candidates */
1672  SCIP_Bool executebranching, /**< perform a branching step after probing */
1673  SCIP_RESULT* result /**< pointer to the result of the execution */
1674  )
1675 {
1676  SCIP_BRANCHRULE* branchrule;
1677 
1678  assert(scip != NULL);
1679  assert(result != NULL);
1680 
1681  /* find branching rule */
1682  branchrule = SCIPfindBranchrule(scip, BRANCHRULE_NAME);
1683  assert(branchrule != NULL);
1684 
1685  /* execute branching rule */
1686  SCIP_CALL( execRelpscost(scip, branchrule, allowaddcons, branchcands, branchcandssol, branchcandsfrac, nbranchcands, executebranching, result) );
1687 
1688  return SCIP_OKAY;
1689 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:51
static SCIP_RETCODE countNonlinearities(SCIP *scip, int *nlcount, int nlcountsize, int *nlcountmax)
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
static SCIP_Real calcNlscore(SCIP *scip, int *nlcount, int nlcountmax, int probindex)
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
Definition: scip.c:33125
SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition: var.c:16883
reliable pseudo costs branching rule
int SCIPgetNVars(SCIP *scip)
Definition: scip.c:10698
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip.c:5878
#define SCIPallocMemory(scip, ptr)
Definition: scip.h:20526
SCIP_Real SCIPgetAvgCutoffScore(SCIP *scip)
Definition: scip.c:39159
#define DEFAULT_PSCOSTWEIGHT
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16443
static void freeBdchgs(SCIP *scip, int **bdchginds, SCIP_BOUNDTYPE **bdchgtypes, SCIP_Real **bdchgbounds, int *nbdchgs)
#define BRANCHRULE_MAXDEPTH
#define DEFAULT_MAXBDCHGS
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip.h:20589
SCIP_Bool SCIPisSumGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41858
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:16623
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip.c:10653
#define DEFAULT_LOWERRORTOL
#define NULL
Definition: lpi_spx.cpp:130
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17113
SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4258
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip.c:1125
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
Definition: scip.c:42032
SCIP_RETCODE SCIPsetBranchruleInitsol(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHINITSOL((*branchinitsol)))
Definition: scip.c:8354
struct SCIP_BranchruleData SCIP_BRANCHRULEDATA
Definition: type_branch.h:43
static SCIP_RETCODE execRelpscost(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_Bool allowaddcons, SCIP_VAR **branchcands, SCIP_Real *branchcandssol, SCIP_Real *branchcandsfrac, int nbranchcands, SCIP_Bool executebranch, SCIP_RESULT *result)
static SCIP_RETCODE binvarGetActiveProbindex(SCIP *scip, SCIP_VAR *var, int *probindex)
#define BRANCHRULE_MAXBOUNDDIST
#define DEFAULT_STARTRANDSEED
int SCIPconshdlrGetNActiveConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4322
#define DEFAULT_SBITERQUOT
#define FALSE
Definition: def.h:56
SCIP_RETCODE SCIPstartStrongbranch(SCIP *scip, SCIP_Bool enablepropagation)
Definition: scip.c:17963
#define TRUE
Definition: def.h:55
SCIP_Real SCIPgetAvgConflictScore(SCIP *scip)
Definition: scip.c:38937
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_RETCODE SCIPupdateVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition: scip.c:23184
SCIP_Longint SCIPgetVarStrongbranchNode(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:19300
#define SCIP_CALL(x)
Definition: def.h:266
#define DEFAULT_INFERENCEWEIGHT
const char * SCIPbranchruleGetName(SCIP_BRANCHRULE *branchrule)
Definition: branch.c:1877
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)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
Definition: scip.c:42008
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
Definition: scip.c:38561
SCIP_Bool SCIPisSumGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41845
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip.h:20556
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip.c:26439
SCIP_RETCODE SCIPsetBranchruleCopy(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHCOPY((*branchcopy)))
Definition: scip.c:8290
SCIP_Longint SCIPgetNDualResolveLPIterations(SCIP *scip)
Definition: scip.c:37713
#define SCIPdebugMessage
Definition: pub_message.h:77
SCIP_RETCODE SCIPgetVarStrongbranchFrac(SCIP *scip, SCIP_VAR *var, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict, SCIP_Bool *lperror)
Definition: scip.c:18191
SCIP_RETCODE SCIPsetBranchruleFree(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHFREE((*branchfree)))
Definition: scip.c:8306
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:85
Constraint handler for "and" constraints, .
static SCIP_DECL_BRANCHINITSOL(branchInitsolRelpscost)
SCIP_Longint SCIPgetNNodeInitLPIterations(SCIP *scip)
Definition: scip.c:37785
static SCIP_DECL_BRANCHFREE(branchFreeRelpscost)
#define DEFAULT_HIGHERRORTOL
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition: scip.c:26482
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
Definition: scip.c:42044
SCIP_Bool SCIPallColsInLP(SCIP *scip)
Definition: scip.c:26829
static SCIP_DECL_BRANCHEXITSOL(branchExitsolRelpscost)
SCIP_Real SCIPgetAvgInferenceScore(SCIP *scip)
Definition: scip.c:39073
SCIP_RETCODE SCIPupdateNodeLowerbound(SCIP *scip, SCIP_NODE *node, SCIP_Real newbound)
Definition: scip.c:12363
SCIP_Bool SCIPpscostThresholdProbabilityTest(SCIP *scip, SCIP_VAR *var, SCIP_Real frac, SCIP_Real threshold, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel)
Definition: scip.c:23463
SCIP_Longint SCIPnodeGetNumber(SCIP_NODE *node)
Definition: tree.c:7016
#define DEFAULT_INITITER
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip.c:3547
SCIP_Real SCIPgetVarPseudocostCountCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip.c:23354
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:16562
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.c:3573
SCIP_RETCODE SCIPsetBranchruleExecLp(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHEXECLP((*branchexeclp)))
Definition: scip.c:8388
#define BRANCHRULE_NAME
SCIP_Real SCIPgetAvgConflictlengthScore(SCIP *scip)
Definition: scip.c:38987
SCIP_RETCODE SCIPgetBinvarRepresentative(SCIP *scip, SCIP_VAR *var, SCIP_VAR **repvar, SCIP_Bool *negated)
Definition: scip.c:17233
SCIP_Bool SCIPsignificantVarPscostDifference(SCIP *scip, SCIP_VAR *varx, SCIP_Real fracx, SCIP_VAR *vary, SCIP_Real fracy, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel, SCIP_Bool onesided)
Definition: scip.c:23433
#define SCIPfreeMemory(scip, ptr)
Definition: scip.h:20542
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41585
#define BRANCHRULE_PRIORITY
enum SCIP_Confidencelevel SCIP_CONFIDENCELEVEL
Definition: type_misc.h:44
SCIP_VAR ** SCIPgetVarsAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5075
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:8253
SCIP_Longint SCIPgetNDualResolveLPs(SCIP *scip)
Definition: scip.c:37693
static SCIP_RETCODE applyBdchgs(SCIP *scip, SCIP_VAR **vars, int *bdchginds, SCIP_BOUNDTYPE *bdchgtypes, SCIP_Real *bdchgbounds, int nbdchgs, SCIP_RESULT *result)
SCIP_Real SCIPgetVarConflictlengthScore(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:23707
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip.h:20574
SCIP_Longint SCIPgetNStrongbranchLPIterations(SCIP *scip)
Definition: scip.c:37857
void SCIPbranchruleSetData(SCIP_BRANCHRULE *branchrule, SCIP_BRANCHRULEDATA *branchruledata)
Definition: branch.c:1765
SCIP_Bool SCIPisNLPConstructed(SCIP *scip)
Definition: scip.c:28407
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:16598
#define DEFAULT_USEHYPTESTFORRELIABILITY
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip.h:20562
SCIP_VAR * SCIPgetResultantAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5100
SCIP_Real SCIPinfinity(SCIP *scip)
Definition: scip.c:41637
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition: scip.c:26354
SCIP_Real SCIPgetVarPseudocostScore(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
Definition: scip.c:23507
#define DEFAULT_SBITEROFS
#define DEFAULT_CUTOFFWEIGHT
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip.h:20598
#define DEFAULT_CONFLICTWEIGHT
SCIP_Longint SCIPgetNRootStrongbranchLPIterations(SCIP *scip)
Definition: scip.c:37893
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41611
static SCIP_RETCODE addBdchg(SCIP *scip, int **bdchginds, SCIP_BOUNDTYPE **bdchgtypes, SCIP_Real **bdchgbounds, int *nbdchgs, int ind, SCIP_BOUNDTYPE type, SCIP_Real bound)
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip.c:20193
SCIP_Real SCIPgetNodeLowerbound(SCIP *scip, SCIP_NODE *node)
Definition: scip.c:12228
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17123
#define SCIP_Bool
Definition: def.h:53
static SCIP_DECL_BRANCHEXECLP(branchExeclpRelpscost)
static SCIP_DECL_BRANCHCOPY(branchCopyRelpscost)
#define DEFAULT_CONFLENGTHWEIGHT
#define DEFAULT_SKIPBADINITCANDS
SCIP_Real SCIPgetVarConflictScore(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:23645
#define DEFAULT_MINRELIABLE
#define MAX(x, y)
Definition: tclique_def.h:75
#define DEFAULT_MAXPROPROUNDS
#define DEFAULT_INITCAND
SCIP_Real SCIPgetVarPseudocostCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: scip.c:23300
#define DEFAULT_NLSCOREWEIGHT
#define DEFAULT_MAXLOOKAHEAD
int SCIPsolGetIndex(SCIP_SOL *sol)
Definition: sol.c:2283
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition: scip.c:36779
SCIP_RETCODE SCIPsetBranchruleExitsol(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHEXITSOL((*branchexitsol)))
Definition: scip.c:8370
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip.c:1298
static SCIP_Real calcScore(SCIP *scip, SCIP_BRANCHRULEDATA *branchruledata, SCIP_Real conflictscore, SCIP_Real avgconflictscore, SCIP_Real conflengthscore, SCIP_Real avgconflengthscore, SCIP_Real inferencescore, SCIP_Real avginferencescore, SCIP_Real cutoffscore, SCIP_Real avgcutoffscore, SCIP_Real pscostscore, SCIP_Real avgpscostscore, SCIP_Real nlscore, SCIP_Real frac)
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41624
#define SCIP_REAL_MAX
Definition: def.h:128
SCIP_Real SCIPgetRandomReal(SCIP_Real minrandval, SCIP_Real maxrandval, unsigned int *seedp)
Definition: misc.c:7719
#define DEFAULT_USERELERRORFORRELIABILITY
#define SCIP_REAL_MIN
Definition: def.h:129
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:20585
SCIP_Real SCIPgetVarPseudocostScoreCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
Definition: scip.c:23545
SCIP_Real SCIPgetVarAvgCutoffScore(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:24131
SCIP_RETCODE SCIPincludeBranchruleRelpscost(SCIP *scip)
#define DEFAULT_PROBINGBOUNDS
SCIP_BRANCHRULEDATA * SCIPbranchruleGetData(SCIP_BRANCHRULE *branchrule)
Definition: branch.c:1755
SCIP_Real SCIPgetBranchScore(SCIP *scip, SCIP_VAR *var, SCIP_Real downgain, SCIP_Real upgain)
Definition: scip.c:33580
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip.h:20593
#define DEFAULT_USESBLOCALINFO
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:16750
SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
Definition: scip.c:8436
#define DEFAULT_STORESEMIINITCOSTS
#define SCIP_Real
Definition: def.h:127
SCIP_RETCODE SCIPgetNLPVarsNonlinearity(SCIP *scip, int *nlcount)
Definition: scip.c:28518
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip.c:20299
#define MIN(x, y)
Definition: memory.c:67
#define SCIP_INVALID
Definition: def.h:147
SCIP_Real SCIPfeastol(SCIP *scip)
Definition: scip.c:41146
#define SCIP_Longint
Definition: def.h:112
#define DEFAULT_USEDYNAMICCONFIDENCE
static SCIP_RETCODE branchruledataEnsureNlcount(SCIP *scip, SCIP_BRANCHRULEDATA *branchruledata)
SCIP_RETCODE SCIPendStrongbranch(SCIP *scip)
Definition: scip.c:18019
#define BRANCHRULE_DESC
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition: scip.c:10572
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:20597
SCIP_Real SCIPnodeGetLowerbound(SCIP_NODE *node)
Definition: tree.c:7036
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:16730
SCIP_Bool SCIPisLPSolBasic(SCIP *scip)
Definition: scip.c:26847
SCIP_RETCODE SCIPgetVarStrongbranchLast(SCIP *scip, SCIP_VAR *var, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Real *solval, SCIP_Real *lpobjval)
Definition: scip.c:19256
int SCIPgetNNLPVars(SCIP *scip)
Definition: scip.c:28496
SCIP_Real SCIPgetAvgPseudocostScore(SCIP *scip)
Definition: scip.c:38889
SCIP_Real SCIPgetVarAvgInferenceScore(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:23877
SCIP_Longint SCIPgetNNodeLPIterations(SCIP *scip)
Definition: scip.c:37749
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
Definition: scip.c:35767
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip.c:3629
#define DEFAULT_MAXRELIABLE
#define DEFAULT_CONFIDENCELEVEL
#define DEFAULT_RANDINITORDER
SCIP_Bool SCIPisVarPscostRelerrorReliable(SCIP *scip, SCIP_VAR *var, SCIP_Real threshold, SCIP_CONFIDENCELEVEL clevel)
Definition: scip.c:23482
SCIP_RETCODE SCIPbranchVarVal(SCIP *scip, SCIP_VAR *var, SCIP_Real val, SCIP_NODE **downchild, SCIP_NODE **eqchild, SCIP_NODE **upchild)
Definition: scip.c:33810
SCIP_Longint SCIPgetNNodeInitLPs(SCIP *scip)
Definition: scip.c:37767
SCIP_Longint SCIPgetNNodes(SCIP *scip)
Definition: scip.c:37372
SCIP_Bool SCIPisExactSolve(SCIP *scip)
Definition: scip.c:1012
SCIP_RETCODE SCIPgetVarStrongbranchWithPropagation(SCIP *scip, SCIP_VAR *var, SCIP_Real solval, SCIP_Real lpobjval, int itlim, int maxproprounds, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Longint *ndomredsdown, SCIP_Longint *ndomredsup, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict, SCIP_Bool *lperror, SCIP_Real *newlbs, SCIP_Real *newubs)
Definition: scip.c:18633
int SCIPgetNVarsAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5051