Scippy

GCG

Branch-and-Price & Column Generation for Everyone

branch_relpsprob.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program */
4 /* GCG --- Generic Column Generation */
5 /* a Dantzig-Wolfe decomposition based extension */
6 /* of the branch-cut-and-price framework */
7 /* SCIP --- Solving Constraint Integer Programs */
8 /* */
9 /* Copyright (C) 2010-2021 Operations Research, RWTH Aachen University */
10 /* Zuse Institute Berlin (ZIB) */
11 /* */
12 /* This program is free software; you can redistribute it and/or */
13 /* modify it under the terms of the GNU Lesser General Public License */
14 /* as published by the Free Software Foundation; either version 3 */
15 /* of the License, or (at your option) any later version. */
16 /* */
17 /* This program is distributed in the hope that it will be useful, */
18 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
19 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
20 /* GNU Lesser General Public License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with this program; if not, write to the Free Software */
24 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.*/
25 /* */
26 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
27 
28 /**@file branch_relpsprob.c
29  * @ingroup BRANCHINGRULES
30  * @brief generalized reliable pseudo costs branching rule
31  * @author Tobias Achterberg
32  * @author Timo Berthold
33  * @author Jens Schulz
34  * @author Gerald Gamrath
35  *
36  * - probing is executed until depth 10 and afterwards with stepsize 5
37  * by that all pseudocost scores and inference informations are updated
38  * otherwise the variable with best score is branched on
39  * - NEW! probing is done according to reliability values per candidate depending on tree size and probing rounds
40  * - the node is reevaluated immediately if MAXBDCHGS occur during probing
41  */
42 
43 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
44 /* #define SCIP_DEBUG */
45 #include <assert.h>
46 #include <string.h>
47 
48 #include "branch_relpsprob.h"
49 #include "relax_gcg.h"
50 #include "cons_integralorig.h"
51 #include "pricer_gcg.h"
52 #include "gcg.h"
53 
54 #include "scip/nodesel_estimate.h"
55 #include "scip/nodesel_hybridestim.h"
56 #include "scip/nodesel_restartdfs.h"
57 #include "scip/branch_allfullstrong.h"
58 #include "scip/branch_fullstrong.h"
59 #include "scip/branch_inference.h"
60 #include "scip/branch_mostinf.h"
61 #include "scip/branch_leastinf.h"
62 #include "scip/branch_pscost.h"
63 #include "scip/branch_random.h"
64 #include "scip/branch_relpscost.h"
65 #include "scip/nodesel_bfs.h"
66 #include "scip/nodesel_dfs.h"
67 
68 
69 #define BRANCHRULE_NAME "relpsprob"
70 #define BRANCHRULE_DESC "generalized reliability branching using probing"
71 #define BRANCHRULE_PRIORITY -100
72 #define BRANCHRULE_MAXDEPTH -1
73 #define BRANCHRULE_MAXBOUNDDIST 1.0
74 
75 #define DEFAULT_CONFLICTWEIGHT 0.01 /**< weight in score calculations for conflict score */
76 #define DEFAULT_CONFLENGTHWEIGHT 0.0001 /**< weight in score calculations for conflict length score*/
77 #define DEFAULT_INFERENCEWEIGHT 0.1 /**< weight in score calculations for inference score */
78 #define DEFAULT_CUTOFFWEIGHT 0.0001 /**< weight in score calculations for cutoff score */
79 #define DEFAULT_PSCOSTWEIGHT 1.0 /**< weight in score calculations for pseudo cost score */
80 #define DEFAULT_MINRELIABLE 1.0 /**< minimal value for minimum pseudo cost size to regard pseudo cost value as reliable */
81 #define DEFAULT_MAXRELIABLE 8.0 /**< maximal value for minimum pseudo cost size to regard pseudo cost value as reliable */
82 #define DEFAULT_ITERQUOT 0.5 /**< maximal fraction of branching LP iterations compared to normal iters */
83 #define DEFAULT_ITEROFS 100000 /**< additional number of allowed LP iterations */
84 #define DEFAULT_MAXLOOKAHEAD 8 /**< maximal number of further variables evaluated without better score */
85 #define DEFAULT_INITCAND 100 /**< maximal number of candidates initialized with strong branching per node */
86 #define DEFAULT_MAXBDCHGS 20 /**< maximal number of bound tightenings before the node is immediately reevaluated (-1: unlimited) */
87 #define DEFAULT_MINBDCHGS 1 /**< minimal number of bound tightenings before the node is reevaluated */
88 #define DEFAULT_USELP TRUE /**< shall the lp be solved during probing? */
89 #define DEFAULT_RELIABILITY 0.8 /**< reliability value for probing */
90 
91 #define HASHSIZE_VARS 131101 /**< minimal size of hash table in bdchgdata */
92 
93 
94 /** branching rule data */
96 {
97  SCIP_Real conflictweight; /**< weight in score calculations for conflict score */
98  SCIP_Real conflengthweight; /**< weight in score calculations for conflict length score */
99  SCIP_Real inferenceweight; /**< weight in score calculations for inference score */
100  SCIP_Real cutoffweight; /**< weight in score calculations for cutoff score */
101  SCIP_Real pscostweight; /**< weight in score calculations for pseudo cost score */
102  SCIP_Real minreliable; /**< minimal value for minimum pseudo cost size to regard pseudo cost value as reliable */
103  SCIP_Real maxreliable; /**< maximal value for minimum pseudo cost size to regard pseudo cost value as reliable */
104  SCIP_Real iterquot; /**< maximal fraction of branching LP iterations compared to normal iters */
105  SCIP_Longint nlpiterations; /**< total number of used LP iterations */
106  int iterofs; /**< additional number of allowed LP iterations */
107  int maxlookahead; /**< maximal number of further variables evaluated without better score */
108  int initcand; /**< maximal number of candidates initialized with strong branching per node */
109  int maxbdchgs; /**< maximal number of bound tightenings before the node is immediately reevaluated (-1: unlimited) */
110  int minbdchgs; /**< minimal number of bound tightenings before bound changes are applied */
111  SCIP_Bool uselp; /**< shall the lp be solved during probing? */
112  int nprobingnodes; /**< counter to store the total number of probing nodes */
113  int ninfprobings; /**< counter to store the number of probings which led to an infeasible branch */
114  SCIP_Real reliability; /**< reliability value for branching variables */
115  int nbranchings; /**< counter to store the total number of nodes that are branched */
116  int nresolvesminbdchgs; /**< counter to store how often node is reevaluated due to min bdchgs */
117  int nresolvesinfcands; /**< counter to store how often node is reevaluated since candidate with inf branch is chosen */
118  int nprobings; /**< counter to store the total number of probings that were performed */
119  SCIP_HASHMAP* varhashmap; /**< hash storing variables; image is position in following arrays */
120  int* nvarbranchings; /**< array to store number of branchings per variable */
121  int* nvarprobings; /**< array to store number of probings per variable */
122  int nvars; /**< number of variables that are in hashmap */
123  int maxvars; /**< capacity of nvarbranchings and nvarprobings */
124 };
125 
126 /** data for pending bound changes */
127 struct BdchgData
128 {
129  SCIP_HASHMAP* varhashmap; /**< hash storing variables; image is position in lbchgs-array */
130  SCIP_Real* lbchgs; /**< array containing lower bounds per variable */
131  SCIP_Real* ubchgs; /**< array containing upper bounds per variable */
132  SCIP_Bool* infroundings; /**< array to store for each var if some rounding is infeasible */
133  int nvars; /**< number of variables that are considered so far */
134 };
135 typedef struct BdchgData BDCHGDATA;
136 
137 
138 /*
139  * local methods
140  */
141 
142 /** creates bound change data structure:
143  * all variables are put into a hashmap and arrays containig current lower and upper bounds are created
144  */
145 static
146 SCIP_RETCODE createBdchgData(
147  SCIP* scip, /**< SCIP data structure */
148  BDCHGDATA** bdchgdata, /**< bound change data to be allocated */
149  SCIP_VAR** vars, /**< array of variables to be watched */
150  int nvars /**< number of variables to be watched */
151  )
152 {
153 
154  int i;
155 
156  assert(scip != NULL);
157  assert(*bdchgdata == NULL);
158 
159  /* get memory for bound change data structure */
160  SCIP_CALL( SCIPallocBuffer(scip, bdchgdata) );
161 
162  /* create hash map */
163  SCIP_CALL( SCIPhashmapCreate(&(*bdchgdata)->varhashmap, SCIPblkmem(scip), HASHSIZE_VARS) );
164 
165  /* get all variables */
166  SCIP_CALL( SCIPallocBufferArray(scip, &(*bdchgdata)->lbchgs, nvars) );
167  SCIP_CALL( SCIPallocBufferArray(scip, &(*bdchgdata)->ubchgs, nvars) );
168  SCIP_CALL( SCIPallocBufferArray(scip, &(*bdchgdata)->infroundings, nvars) );
169  (*bdchgdata)->nvars = nvars;
170 
171  /* store current local bounds and capture variables */
172  for( i = 0; i < nvars; ++i )
173  {
174  SCIP_CALL( SCIPhashmapInsert((*bdchgdata)->varhashmap, vars[i], (void*) (size_t)i) );
175 
176  (*bdchgdata)->lbchgs[i] = SCIPfeasCeil(scip, SCIPvarGetLbLocal(vars[i]));
177  (*bdchgdata)->ubchgs[i] = SCIPfeasFloor(scip, SCIPvarGetUbLocal(vars[i]));
178  (*bdchgdata)->infroundings[i] = FALSE;
179  }
180 
181  return SCIP_OKAY;
182 }
183 
184 /** method to free bound change data strucutre */
185 static
186 SCIP_RETCODE freeBdchgData(
187  SCIP* scip, /**< SCIP data structure */
188  BDCHGDATA* bdchgdata /**< bound change data to be allocated */
189  )
190 {
191 
192  assert(scip != NULL);
193  assert(bdchgdata != NULL);
194 
195  /* free arrays & hashmap */
196  SCIPfreeBufferArray(scip, &bdchgdata->infroundings);
197  SCIPfreeBufferArray(scip, &bdchgdata->ubchgs);
198  SCIPfreeBufferArray(scip, &bdchgdata->lbchgs);
199 
200  SCIPhashmapFree(&(bdchgdata->varhashmap));
201 
202  /* free memory for bound change data structure */
203  SCIPfreeBuffer(scip, &bdchgdata);
204 
205  return SCIP_OKAY;
206 }
207 
208 
209 /** adds given variable and bound change to hashmap and bound change arrays */
210 static
211 SCIP_RETCODE addBdchg(
212  SCIP* scip, /**< SCIP data structure */
213  BDCHGDATA* bdchgdata, /**< structure to keep bound chage data */
214  SCIP_VAR* var, /**< variable to store bound change */
215  SCIP_Real newbound, /**< new bound for given variable */
216  SCIP_BOUNDTYPE boundtype, /**< lower or upper bound change */
217  SCIP_Bool infrounding, /**< is the bdchg valid due to an infeasible rounding of the given var */
218  int* nbdchgs, /**< total number of bound changes occured so far */
219  SCIP_Bool* infeasible /**< pointer to store whether bound change makes the node infeasible */
220  )
221 {
222  int nvars;
223  int pos;
224 
225  assert(scip != NULL);
226  assert(bdchgdata != NULL);
227  assert(bdchgdata->varhashmap != NULL);
228  assert(bdchgdata->lbchgs != NULL);
229  assert(bdchgdata->ubchgs != NULL);
230  assert(var != NULL);
231 
232  nvars = bdchgdata->nvars;
233 
234  if( infeasible != NULL )
235  *infeasible = FALSE;
236 
237  /* if variable is not in hashmap insert it and increase array sizes */
238  if( !SCIPhashmapExists(bdchgdata->varhashmap, var) )
239  {
240  SCIP_CALL( SCIPhashmapInsert(bdchgdata->varhashmap, var, (void*) (size_t)nvars) );
241  SCIP_CALL( SCIPreallocBufferArray(scip, &bdchgdata->lbchgs, nvars + 1) );
242  SCIP_CALL( SCIPreallocBufferArray(scip, &bdchgdata->ubchgs, nvars + 1) );
243 
244  bdchgdata->lbchgs[nvars] = SCIPfeasCeil(scip, SCIPvarGetLbLocal(var));
245  bdchgdata->ubchgs[nvars] = SCIPfeasFloor(scip, SCIPvarGetUbLocal(var));
246  (bdchgdata->nvars)++;
247 
248  assert(SCIPhashmapExists(bdchgdata->varhashmap, var)
249  && (int)(size_t) SCIPhashmapGetImage(bdchgdata->varhashmap, var) == nvars); /*lint !e507*/
250 
251  }
252 
253  /* get position of this variable */
254  pos = (int)(size_t) SCIPhashmapGetImage(bdchgdata->varhashmap, var); /*lint !e507*/
255 
256  if( infrounding )
257  {
258  bdchgdata->infroundings[pos] = TRUE;
259  }
260 
261  /* update bounds if necessary */
262  if( boundtype == SCIP_BOUNDTYPE_LOWER )
263  {
264  if( bdchgdata->lbchgs[pos] < newbound )
265  {
266  bdchgdata->lbchgs[pos] = newbound;
267  (*nbdchgs)++;
268  }
269 
270  if( (infeasible != NULL) && (newbound > bdchgdata->ubchgs[pos]) )
271  {
272  *infeasible = TRUE;
273  }
274 
275  }
276  else
277  {
278  if( newbound < bdchgdata->ubchgs[pos] )
279  {
280  bdchgdata->ubchgs[pos] = newbound;
281  (*nbdchgs)++;
282  }
283  if( (infeasible != NULL) && (newbound < bdchgdata->lbchgs[pos]) )
284  {
285  *infeasible = TRUE;
286  }
287  }
288 
289  return SCIP_OKAY;
290 }
291 
292 
293 
294 /** applies bound changes stored in bound change arrays */
295 static
296 SCIP_RETCODE applyBdchgs(
297  SCIP* scip, /**< SCIP data structure */
298  BDCHGDATA* bdchgdata, /**< structure containing bound changes for almost all variables */
299  SCIP_NODE* node /**< node for which bound changes are applied, NULL for curnode */
300  )
301 {
302  SCIP_VAR** vars;
303 
304  int nintvars;
305  int nbinvars;
306  int nvars;
307  int nbdchgs;
308  int i;
309 
310  assert(scip != NULL);
311  assert(bdchgdata != NULL);
312 
313  SCIPdebugMessage("apply bound changes\n");
314 
315  nbdchgs = 0;
316 
317  /* get all variables */
318  SCIP_CALL( SCIPgetVarsData(scip, &vars, NULL, &nbinvars, &nintvars, NULL, NULL) );
319  nvars = nbinvars + nintvars;
320  assert(vars != NULL);
321 
322  /* get variable image in hashmap and update bounds if better ones found */
323  for( i = 0; i < nvars; ++i )
324  {
325  if( SCIPhashmapExists(bdchgdata->varhashmap, vars[i]) )
326  {
327  int pos;
328  pos = (int)(size_t)SCIPhashmapGetImage(bdchgdata->varhashmap, vars[i]); /*lint !e507*/
329 
330  /* update lower bounds */
331  if( SCIPisFeasGT(scip, (bdchgdata->lbchgs)[pos], SCIPvarGetLbLocal(vars[i])) )
332  {
333  SCIPdebugMessage("branch_relpsprob: update lower bound of <%s> from %g to %g\n",
334  SCIPvarGetName(vars[i]), SCIPvarGetLbLocal(vars[i]), (bdchgdata->lbchgs)[pos]);
335  SCIP_CALL( SCIPchgVarLbNode(scip, node, vars[i], (bdchgdata->lbchgs)[pos]) );
336  ++nbdchgs;
337  }
338  /* update upper bounds */
339  if( SCIPisFeasLT(scip, (bdchgdata->ubchgs)[pos], SCIPvarGetUbLocal(vars[i])) )
340  {
341  SCIPdebugMessage("branch_relpsprob: update upper bound of <%s> from %g to %g\n",
342  SCIPvarGetName(vars[i]), SCIPvarGetUbLocal(vars[i]), (bdchgdata->ubchgs)[pos]);
343 
344  SCIP_CALL( SCIPchgVarUbNode(scip, node, vars[i], (bdchgdata->ubchgs)[pos]) );
345  ++nbdchgs;
346  }
347  }
348  }
349 
350  SCIPdebugMessage("applied %d bound changes\n", nbdchgs);
351  return SCIP_OKAY;
352 }
353 
354 
355 /** calculates an overall score value for the given individual score values */
356 static
357 SCIP_Real calcScore(
358  SCIP* scip, /**< SCIP data structure */
359  SCIP_BRANCHRULEDATA* branchruledata, /**< branching rule data */
360  SCIP_Real conflictscore, /**< conflict score of current variable */
361  SCIP_Real avgconflictscore, /**< average conflict score */
362  SCIP_Real conflengthscore, /**< conflict length score of current variable */
363  SCIP_Real avgconflengthscore, /**< average conflict length score */
364  SCIP_Real inferencescore, /**< inference score of current variable */
365  SCIP_Real avginferencescore, /**< average inference score */
366  SCIP_Real cutoffscore, /**< cutoff score of current variable */
367  SCIP_Real avgcutoffscore, /**< average cutoff score */
368  SCIP_Real pscostscore, /**< pscost score of current variable */
369  SCIP_Real avgpscostscore, /**< average pscost score */
370  SCIP_Real frac /**< fractional value of variable in current solution */
371  )
372 {
373  SCIP_Real score;
374 
375  assert(branchruledata != NULL);
376  /* assert(0.0 < frac && frac < 1.0); */
377 
378  score = branchruledata->conflictweight * (1.0 - 1.0/(1.0+conflictscore/avgconflictscore))
379  + branchruledata->conflengthweight * (1.0 - 1.0/(1.0+conflengthscore/avgconflengthscore))
380  + branchruledata->inferenceweight * (1.0 - 1.0/(1.0+inferencescore/avginferencescore))
381  + branchruledata->cutoffweight * (1.0 - 1.0/(1.0+cutoffscore/avgcutoffscore))
382  + branchruledata->pscostweight * (1.0 - 1.0/(1.0+pscostscore/avgpscostscore));
383 
384  /* values close to integral are possible and are adjusted to small non-zero values */
385  if( frac < 0.00000001 || frac > 0.999999 )
386  frac = 0.0001;
387  if( MIN(frac, 1.0 - frac) < 10.0*SCIPfeastol(scip) )
388  score *= 1e-6;
389 
390  return score;
391 }
392 
393 
394 /* calculates variable bounds for an up-branch and a down-branch, supposig a LP or pseudo solution is given */
395 static
396 SCIP_RETCODE calculateBounds(
397  SCIP* scip, /**< SCIP data structure */
398  SCIP_VAR* branchvar, /**< branching variable */
399  SCIP_Real* downlb, /**< lower bound of variable in down branch */
400  SCIP_Real* downub, /**< upper bound of variable in down branch */
401  SCIP_Real* uplb, /**< lower bound of variable in up branch */
402  SCIP_Real* upub /**< upper bound of variable in up branch */
403  )
404 {
405  SCIP_Real varsol;
406  SCIP_Real lbdown;
407  SCIP_Real ubdown;
408  SCIP_Real lbup;
409  SCIP_Real ubup;
410 
411  SCIP_Real lblocal;
412  SCIP_Real ublocal;
413 
414  assert(scip != NULL);
415  assert(branchvar != NULL);
416 
417  varsol = SCIPgetVarSol(scip, branchvar);
418 
419  lblocal = SCIPfeasCeil(scip, SCIPvarGetLbLocal(branchvar));
420  ublocal = SCIPfeasFloor(scip, SCIPvarGetUbLocal(branchvar));
421 
422  /* calculate bounds in down branch */
423  lbdown = lblocal;
424 
425  /* in down branch: new upper bound is at most local upper bound - 1 */
426  ubdown = SCIPfeasFloor(scip, varsol) ;
427  if( SCIPisEQ(scip, ubdown, ublocal) )
428  ubdown -= 1.0;
429 
430  assert(lbdown <= ubdown);
431 
432  /* calculate bounds in up branch */
433  ubup = ublocal;
434 
435  /* in right branch: new lower bound is at least local lower bound + 1 */
436  lbup = SCIPfeasCeil(scip, varsol);
437  if( SCIPisEQ(scip, lbup, lblocal) )
438  lbup += 1.0;
439 
440  assert(SCIPisLE(scip, lbup, ubup));
441 
442  /* ensure that both branches partition the domain */
443  if( SCIPisEQ(scip, lbup, ubdown) )
444  {
445  SCIP_Real middle = SCIPfloor(scip, lblocal/2 + ublocal/2);
446 
447  if( SCIPisLE(scip, lbup, middle) )
448  ubdown -= 1.0;
449  else
450  lbup += 1.0;
451  }
452 
453  /* ensure a real partition of the domain */
454  assert(SCIPisLT(scip, ubdown, lbup));
455  assert(SCIPisLE(scip, lbdown, ubdown));
456  assert(SCIPisLE(scip, lbup, ubup));
457 
458  /* set return values */
459  if( downlb != NULL )
460  *downlb = lbdown;
461  if( downub != NULL )
462  *downub = ubdown;
463  if( uplb != NULL )
464  *uplb = lbup;
465  if( upub != NULL )
466  *upub = ubup;
467 
468  return SCIP_OKAY;
469 }
470 
471 
472 /** applies probing of a single variable in the given direction, and stores evaluation in given arrays */
473 static
474 SCIP_RETCODE applyProbing(
475  SCIP* scip, /**< SCIP data structure */
476  SCIP_VAR** vars, /**< problem variables */
477  int nvars, /**< number of problem variables */
478  SCIP_VAR* probingvar, /**< variable to perform probing on */
479  SCIP_Bool probingdir, /**< value to fix probing variable to */
480  SCIP_Bool solvelp, /**< value to decide whether pricing loop shall be performed */
481  SCIP_Longint* nlpiterations, /**< pointer to store the number of used LP iterations */
482  SCIP_Real* proplbs, /**< array to store lower bounds after full propagation */
483  SCIP_Real* propubs, /**< array to store upper bounds after full propagation */
484  SCIP_Real* lpobjvalue, /**< pointer to store the lp obj value if lp was solved */
485  SCIP_Bool* lpsolved, /**< pointer to store whether the lp was solved */
486  SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occured or the
487  * solving process should be stopped (e.g., due to a time limit) */
488  SCIP_Bool* cutoff /**< pointer to store whether the probing direction is infeasible */
489  )
490 {
491  SCIP* masterscip;
492 
493  /* SCIP_Real varsol; */
494  SCIP_Real leftlbprobing;
495  SCIP_Real leftubprobing;
496  SCIP_Real rightlbprobing;
497  SCIP_Real rightubprobing;
498 
499  leftubprobing = -1.0;
500  leftlbprobing = -1.0;
501  rightlbprobing = -1.0;
502  rightubprobing = -1.0;
503 
504  assert(proplbs != NULL);
505  assert(propubs != NULL);
506  assert(cutoff != NULL);
507  assert(SCIPvarGetLbLocal(probingvar) - 0.5 < SCIPvarGetUbLocal(probingvar));
508  assert(SCIPisFeasIntegral(scip, SCIPvarGetLbLocal(probingvar)));
509  assert(SCIPisFeasIntegral(scip, SCIPvarGetUbLocal(probingvar)));
510 
511  assert(!solvelp || (lpsolved!=NULL && lpobjvalue!=NULL && lperror!=NULL));
512 
513  /* get SCIP data structure of master problem */
514  masterscip = GCGgetMasterprob(scip);
515  assert(masterscip != NULL);
516 
517  /* varsol = SCIPgetRelaxSolVal(scip, probingvar); */
518 
519  if( probingdir == FALSE )
520  {
521 
522  SCIP_CALL( calculateBounds(scip, probingvar,
523  &leftlbprobing, &leftubprobing, NULL, NULL) );
524  }
525  else
526  {
527  SCIP_CALL( calculateBounds(scip, probingvar,
528  NULL, NULL, &rightlbprobing, &rightubprobing) );
529  }
530 
531  SCIPdebugMessage("applying probing on variable <%s> == %u [%g,%g] (nlocks=%d/%d, impls=%d/%d, clqs=%d/%d)\n",
532  SCIPvarGetName(probingvar), probingdir,
533  probingdir ? rightlbprobing : leftlbprobing, probingdir ? rightubprobing : leftubprobing,
534  SCIPvarGetNLocksDown(probingvar), SCIPvarGetNLocksUp(probingvar),
535  SCIPvarGetNImpls(probingvar, FALSE), SCIPvarGetNImpls(probingvar, TRUE),
536  SCIPvarGetNCliques(probingvar, FALSE), SCIPvarGetNCliques(probingvar, TRUE));
537 
538  /* start probing mode */
539  SCIP_CALL( GCGrelaxStartProbing(scip, NULL) );
540  SCIP_CALL( GCGrelaxNewProbingnodeOrig(scip) );
541 
542  *lpsolved = FALSE;
543  *lperror = FALSE;
544 
545  /* change variable bounds for the probing directions*/
546  if( probingdir == FALSE )
547  {
548  SCIP_CALL( SCIPchgVarUbProbing(scip, probingvar, leftubprobing) );
549  }
550  else
551  {
552  SCIP_CALL( SCIPchgVarLbProbing(scip, probingvar, rightlbprobing) );
553  }
554 
555  /* apply propagation */
556  if( !(*cutoff) )
557  {
558  SCIP_CALL( SCIPpropagateProbing(scip, -1, cutoff, NULL) ); /** @todo use maxproprounds */
559  }
560 
561  /* evaluate propagation */
562  if( !(*cutoff) )
563  {
564  int i;
565 
566  for( i = 0; i < nvars; ++i )
567  {
568  proplbs[i] = SCIPvarGetLbLocal(vars[i]);
569  propubs[i] = SCIPvarGetUbLocal(vars[i]);
570  }
571  }
572 
573  /* if parameter is set, we want to use the outcome of the LP relaxation */
574  if( !(*cutoff) && solvelp )
575  {
576  *nlpiterations -= SCIPgetNLPIterations(masterscip);
577 
578  /** @todo handle the feasible result */
579  SCIP_CALL( GCGrelaxNewProbingnodeMaster(scip) );
580  SCIP_CALL( GCGrelaxPerformProbingWithPricing(scip, -1, nlpiterations, NULL,
581  lpobjvalue, lpsolved, lperror, cutoff) );
582  }
583 
584  /* exit probing mode */
585  SCIP_CALL( GCGrelaxEndProbing(scip) );
586 
587  SCIPdebugMessage("probing results in cutoff/lpsolved/lpobj: %s / %s / %g\n",
588  *cutoff?"cutoff":"no cutoff", *lpsolved?"lpsolved":"lp not solved", *lpobjvalue);
589 
590  return SCIP_OKAY;
591 }
592 
593 
594 /** gets generalized strong branching information on problem variable */
595 static
596 SCIP_RETCODE getVarProbingbranch(
597  SCIP* scip, /**< SCIP data structure */
598  SCIP_VAR* probingvar, /**< variable to get strong probing branching values for */
599  BDCHGDATA* bdchgdata, /**< structure containing bound changes for almost all variables */
600  SCIP_Bool solvelp, /**< value to decide whether pricing loop shall be performed */
601  SCIP_Longint* nlpiterations, /**< pointert to stroe the number of used LP iterations */
602  SCIP_Real* down, /**< stores dual bound after branching column down */
603  SCIP_Real* up, /**< stores dual bound after branching column up */
604  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
605  * otherwise, it can only be used as an estimate value */
606  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
607  * otherwise, it can only be used as an estimate value */
608  SCIP_Bool* downinf, /**< pointer to store whether the downwards branch is infeasible, or NULL */
609  SCIP_Bool* upinf, /**< pointer to store whether the upwards branch is infeasible, or NULL */
610  SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occured or the
611  * solving process should be stopped (e.g., due to a time limit) */
612  int* nbdchgs /**< pointer to store number of total bound changes */
613  )
614 {
615  /* data for variables and bdchg arrays */
616  SCIP_VAR** probvars;
617  SCIP_VAR** vars;
618  int nvars;
619  int nintvars;
620  int nbinvars;
621 
622  SCIP_Real* leftproplbs;
623  SCIP_Real* leftpropubs;
624  SCIP_Real* rightproplbs;
625  SCIP_Real* rightpropubs;
626 
627  SCIP_Real leftlpbound;
628  SCIP_Real rightlpbound;
629  SCIP_Bool leftlpsolved;
630  SCIP_Bool rightlpsolved;
631  SCIP_Bool leftlperror;
632  SCIP_Bool rightlperror;
633  SCIP_Bool leftcutoff;
634  SCIP_Bool rightcutoff;
635  SCIP_Bool cutoff;
636  int i;
637  int j;
638 
639  assert(lperror != NULL);
640 
641  if( downvalid != NULL )
642  *downvalid = FALSE;
643  if( upvalid != NULL )
644  *upvalid = FALSE;
645  if( downinf != NULL )
646  *downinf = FALSE;
647  if( upinf != NULL )
648  *upinf = FALSE;
649 
650  if( SCIPisStopped(scip) )
651  {
652  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL,
653  " (%.1fs) probing aborted: solving stopped\n", SCIPgetSolvingTime(scip));
654  return SCIP_OKAY;
655  }
656 
657  /* get all variables to store branching deductions of variable bounds */
658  /* get all variables and store them in array 'vars' */
659  SCIP_CALL( SCIPgetVarsData(scip, &probvars, NULL, &nbinvars, &nintvars, NULL, NULL) );
660  nvars = nbinvars + nintvars; /* continuous variables are not considered here */
661 
662  SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, probvars, nvars) );
663 
664  /* capture variables to make sure the variables are not deleted */
665  for( i = 0; i < nvars; ++i )
666  {
667  SCIP_CALL( SCIPcaptureVar(scip, vars[i]) );
668  }
669 
670  /* get temporary memory for storing probing results */
671  SCIP_CALL( SCIPallocBufferArray(scip, &leftproplbs, nvars) );
672  SCIP_CALL( SCIPallocBufferArray(scip, &leftpropubs, nvars) );
673  SCIP_CALL( SCIPallocBufferArray(scip, &rightproplbs, nvars) );
674  SCIP_CALL( SCIPallocBufferArray(scip, &rightpropubs, nvars) );
675 
676  /* for each binary variable, probe fixing the variable to left and right */
677  cutoff = FALSE;
678  leftcutoff = FALSE;
679  rightcutoff = FALSE;
680 
681  /* better assume we don't have an error (fixes clang warning)*/
682  leftlperror = FALSE;
683  rightlperror = FALSE;
684 
685  /* better assume we don't have solved the lp (fixes clang warning)*/
686  leftlpsolved = FALSE;
687  rightlpsolved = FALSE;
688 
689 
690  /* left branch: apply probing for setting ub to LP solution value */
691  SCIP_CALL( applyProbing(scip, vars, nvars, probingvar, FALSE, solvelp, nlpiterations,
692  leftproplbs, leftpropubs,
693  &leftlpbound, &leftlpsolved, &leftlperror, &leftcutoff) );
694 
695  if( leftcutoff )
696  {
697  SCIP_Real newbound;
698 
699  SCIP_CALL( calculateBounds(scip, probingvar, NULL, NULL, &newbound, NULL) );
700 
701  /* lower bound can be updated */
702  SCIPdebugMessage("change lower bound of probing variable <%s> from %g to %g, nlocks=(%d/%d)\n",
703  SCIPvarGetName(probingvar), SCIPvarGetLbLocal(probingvar), newbound,
704  SCIPvarGetNLocksDown(probingvar), SCIPvarGetNLocksUp(probingvar));
705 
706  SCIP_CALL( addBdchg(scip, bdchgdata, probingvar, newbound, SCIP_BOUNDTYPE_LOWER, TRUE, nbdchgs, &cutoff) );
707  }
708 
709  if( !cutoff )
710  {
711  /* right branch: apply probing for setting lb to LP solution value */
712  SCIP_CALL( applyProbing(scip, vars, nvars, probingvar, TRUE, solvelp, nlpiterations,
713  rightproplbs, rightpropubs,
714  &rightlpbound, &rightlpsolved, &rightlperror, &rightcutoff) );
715 
716  if( rightcutoff )
717  {
718  SCIP_Real newbound;
719 
720  SCIP_CALL( calculateBounds(scip, probingvar, NULL, &newbound, NULL, NULL) );
721 
722  /* upper bound can be updated */
723  SCIPdebugMessage("change probing variable <%s> upper bound from %g to %g, nlocks=(%d/%d)\n",
724  SCIPvarGetName(probingvar), SCIPvarGetUbLocal(probingvar), newbound,
725  SCIPvarGetNLocksDown(probingvar), SCIPvarGetNLocksUp(probingvar));
726 
727  SCIP_CALL( addBdchg(scip, bdchgdata, probingvar, newbound, SCIP_BOUNDTYPE_UPPER, TRUE, nbdchgs, &cutoff) );
728  }
729  }
730 
731  /* set return value of lperror */
732  cutoff = cutoff || (leftcutoff && rightcutoff);
733  *lperror = leftlperror || rightlperror;
734 
735 
736  /* analyze probing deductions */
737 
738  /* 1. dualbounds */
739  if( leftlpsolved )
740  *down = leftlpbound;
741  if( rightlpsolved )
742  *up = rightlpbound; /*lint !e644*/
743 
744  /* 2. update bounds */
745  for( j = 0; j < nvars && !cutoff; ++j )
746  {
747  SCIP_Real newlb;
748  SCIP_Real newub;
749 
750  if( vars[j] == probingvar )
751  continue;
752 
753  /* new bounds of the variable is the union of the propagated bounds of the left and right case */
754  newlb = MIN(leftproplbs[j], rightproplbs[j]);
755  newub = MAX(leftpropubs[j], rightpropubs[j]);
756 
757  /* check for fixed variables */
758  if( SCIPisFeasEQ(scip, newlb, newub) )
759  {
760  /* in both probings, variable j is deduced to a fixed value */
761  SCIP_CALL( addBdchg(scip, bdchgdata, vars[j], newlb, SCIP_BOUNDTYPE_LOWER, FALSE, nbdchgs, &cutoff) );
762  SCIP_CALL( addBdchg(scip, bdchgdata, vars[j], newub, SCIP_BOUNDTYPE_UPPER, FALSE, nbdchgs, &cutoff) );
763  continue;
764  }
765  else
766  {
767  SCIP_Real oldlb;
768  SCIP_Real oldub;
769 
770  assert(SCIPvarGetType(vars[j]) == SCIP_VARTYPE_BINARY || SCIPvarGetType(vars[j]) == SCIP_VARTYPE_INTEGER);
771 
772  /* check for bound tightenings */
773  oldlb = SCIPvarGetLbLocal(vars[j]);
774  oldub = SCIPvarGetUbLocal(vars[j]);
775  if( SCIPisLbBetter(scip, newlb, oldlb, oldub) )
776  {
777  /* in both probings, variable j is deduced to be at least newlb: tighten lower bound */
778  SCIP_CALL( addBdchg(scip, bdchgdata, vars[j], newlb, SCIP_BOUNDTYPE_LOWER, FALSE, nbdchgs, &cutoff) );
779  }
780  if( SCIPisUbBetter(scip, newub, oldlb, oldub) && !cutoff )
781  {
782  /* in both probings, variable j is deduced to be at most newub: tighten upper bound */
783  SCIP_CALL( addBdchg(scip, bdchgdata, vars[j], newub, SCIP_BOUNDTYPE_UPPER, FALSE, nbdchgs, &cutoff) );
784  }
785 
786  }
787 
788  } /* end check for deductions */
789 
790  /* set correct return values */
791  if( down != NULL && leftlpsolved )
792  *down = leftlpbound;
793  if( up != NULL && rightlpsolved )
794  *up = rightlpbound;
795  if( downvalid != NULL && leftlpsolved )
796  *downvalid = TRUE;
797  if( downvalid != NULL && !leftlpsolved )
798  *downvalid = FALSE;
799  if( upvalid != NULL && rightlpsolved )
800  *upvalid = TRUE;
801  if( upvalid != NULL && !rightlpsolved )
802  *upvalid = FALSE;
803  if( downinf != NULL )
804  *downinf = leftcutoff;
805  if( upinf != NULL )
806  *upinf = rightcutoff;
807 
808  if( cutoff )
809  {
810  if( downinf != NULL )
811  *downinf = cutoff;
812  if( upinf != NULL )
813  *upinf = cutoff;
814  }
815 
816  /* free temporary memory */
817  SCIPfreeBufferArray(scip, &rightpropubs);
818  SCIPfreeBufferArray(scip, &rightproplbs);
819  SCIPfreeBufferArray(scip, &leftpropubs);
820  SCIPfreeBufferArray(scip, &leftproplbs);
821 
822  /* release variables */
823  for( i = 0; i < nvars; ++i )
824  {
825  SCIP_CALL( SCIPreleaseVar(scip, &vars[i]) );
826  }
827  SCIPfreeBufferArray(scip, &vars);
828 
829 
830  return SCIP_OKAY;
831 }
832 
833 
834 
835 
836 /** adds branching candidates to branchruledata to collect infos about it */
837 static
838 SCIP_RETCODE addBranchcandsToData(
839  SCIP* scip, /**< SCIP data structure */
840  SCIP_BRANCHRULE* branchrule, /**< branching rule */
841  SCIP_VAR** branchcands, /**< branching candidates */
842  int nbranchcands /**< number of branching candidates */
843  )
844 {
845 
846  SCIP_BRANCHRULEDATA* branchruledata;
847  int j;
848 
849 
850  /* get branching rule data */
851  branchruledata = SCIPbranchruleGetData(branchrule);
852  assert(branchruledata != NULL);
853 
854  if( branchruledata->nvars == 0 )
855  { /* no variables known before, reinitialized hashmap and variable info storage */
856 
857  /* create hash map */
858  assert(branchruledata->varhashmap == NULL);
859  SCIP_CALL( SCIPhashmapCreate(&(branchruledata->varhashmap), SCIPblkmem(scip), HASHSIZE_VARS) );
860 
861  branchruledata->maxvars = SCIPcalcMemGrowSize(scip, nbranchcands);
862  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &branchruledata->nvarprobings, branchruledata->maxvars) );
863  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &branchruledata->nvarbranchings, branchruledata->maxvars) );
864  branchruledata->nvars = nbranchcands;
865 
866  /* store each variable in hashmap and initialize array entries */
867  for( j = 0; j < nbranchcands; ++j )
868  {
869  SCIP_CALL( SCIPhashmapInsert(branchruledata->varhashmap, branchcands[j], (void*) (size_t)j) );
870  branchruledata->nvarprobings[j] = 0;
871  branchruledata->nvarbranchings[j] = 0;
872  }
873  }
874  else /* possibly new variables need to be added */
875  {
876 
877  /* if var is not in hashmap, insert it */
878  for( j = 0; j < nbranchcands; ++j )
879  {
880  SCIP_VAR* var;
881  int nvars;
882 
883  var = branchcands[j];
884  assert(var != NULL);
885  nvars = branchruledata->nvars;
886 
887  /* if variable is not in hashmap insert it and increase array sizes */
888  if( !SCIPhashmapExists(branchruledata->varhashmap, var) )
889  {
890  int newsize = SCIPcalcMemGrowSize(scip, nvars + 1);
891  SCIP_CALL( SCIPhashmapInsert(branchruledata->varhashmap, var, (void*) (size_t)nvars) );
892  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &branchruledata->nvarprobings, branchruledata->maxvars,
893  newsize) );
894  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &branchruledata->nvarbranchings, branchruledata->maxvars,
895  newsize) );
896  branchruledata->maxvars = newsize;
897 
898  branchruledata->nvarprobings[nvars] = 0;
899  branchruledata->nvarbranchings[nvars] = 0;
900 
901  assert(SCIPhashmapExists(branchruledata->varhashmap, var)
902  && (int)(size_t) SCIPhashmapGetImage(branchruledata->varhashmap, var) == nvars); /*lint !e507*/
903 
904  ++(branchruledata->nvars);
905  }
906 
907  }
908  }
909 
910  return SCIP_OKAY;
911 }
912 
913 /** increases number of branchings that took place on the given variable */
914 static
915 SCIP_RETCODE incNVarBranchings(
916  SCIP* scip, /**< SCIP data structure */
917  SCIP_BRANCHRULE* branchrule, /**< branching rule */
918  SCIP_VAR* var /**< variable to increase number of branchings on */
919  )
920 {
921  SCIP_BRANCHRULEDATA* branchruledata;
922  int pos;
923 
924  assert(scip != NULL);
925  assert(branchrule != NULL);
926  assert(var != NULL);
927 
928  /* get branching rule data */
929  branchruledata = SCIPbranchruleGetData(branchrule);
930  assert(branchruledata != NULL);
931 
932  assert(SCIPhashmapExists(branchruledata->varhashmap, var) );
933 
934  pos = (int)(size_t) SCIPhashmapGetImage(branchruledata->varhashmap, var); /*lint !e507*/
935  (branchruledata->nvarbranchings[pos])++;
936 
937  (branchruledata->nbranchings)++;
938 
939  return SCIP_OKAY;
940 }
941 
942 /** increases number of probings that took place on the given variable */
943 static
944 SCIP_RETCODE incNVarProbings(
945  SCIP* scip, /**< SCIP data structure */
946  SCIP_BRANCHRULE* branchrule, /**< branching rule */
947  SCIP_VAR* var /**< variable to increase number of branchings on */
948  )
949 {
950  SCIP_BRANCHRULEDATA* branchruledata;
951  int pos;
952 
953  assert(scip != NULL);
954  assert(branchrule != NULL);
955  assert(var != NULL);
956 
957  /* get branching rule data */
958  branchruledata = SCIPbranchruleGetData(branchrule);
959  assert(branchruledata != NULL);
960 
961  assert(SCIPhashmapExists(branchruledata->varhashmap, var) );
962 
963  pos = (int)(size_t) SCIPhashmapGetImage(branchruledata->varhashmap, var); /*lint !e507*/
964  (branchruledata->nvarprobings[pos])++;
965 
966  (branchruledata->nprobings)++;
967 
968  return SCIP_OKAY;
969 }
970 
971 
972 /** execute generalized reliability pseudo cost probing branching */
973 static
974 SCIP_RETCODE execRelpsprob(
975  SCIP* scip, /**< SCIP data structure */
976  SCIP_BRANCHRULE* branchrule, /**< branching rule */
977  SCIP_VAR** branchcands, /**< branching candidates */
978  SCIP_Real* branchcandssol, /**< solution value for the branching candidates */
979  int nbranchcands, /**< number of branching candidates */
980  int nvars, /**< number of variables to be watched be bdchgdata */
981  SCIP_RESULT* result, /**< pointer to the result of the execution */
982  SCIP_VAR** branchvar /**< pointer to the variable to branch on */
983  )
984 {
985  SCIP* masterscip;
986  SCIP_BRANCHRULEDATA* branchruledata;
987  BDCHGDATA* bdchgdata;
988  SCIP_Real lpobjval;
989 #ifndef NDEBUG
990  SCIP_Real cutoffbound;
991 #endif
992  SCIP_Real provedbound;
993 #ifdef SCIP_DEBUG
994  SCIP_Bool bestisstrongbranch = FALSE;
995 #endif
996  int bestcand = -1;
997 
998  *result = SCIP_DIDNOTRUN;
999 
1000  SCIPdebugMessage("execrelpsprob method called\n relpsprob\n relpsprob\n relpsprob\n relpsprob\n relpsprob\n relpsprob\n relpsprob\n relpsprob\n");
1001 
1002  /* get SCIP pointer of master problem */
1003  masterscip = GCGgetMasterprob(scip);
1004  assert(masterscip != NULL);
1005 
1006  /* get branching rule data */
1007  branchruledata = SCIPbranchruleGetData(branchrule);
1008  assert(branchruledata != NULL);
1009 
1010  /* add all branching candidates into branchruledata if not yet inserted */
1011  SCIP_CALL( addBranchcandsToData(scip, branchrule, branchcands, nbranchcands) );
1012 
1013  bdchgdata = NULL;
1014  /* create data structure for bound change infos */
1015  SCIP_CALL( createBdchgData(scip, &bdchgdata, branchcands, nvars) );
1016  assert(bdchgdata != NULL);
1017 
1018  /* get current LP objective bound of the local sub problem and global cutoff bound */
1019  lpobjval = SCIPgetLocalLowerbound(scip);
1020 #ifndef NDEBUG
1021  cutoffbound = SCIPgetCutoffbound(scip);
1022 #endif
1023  provedbound = lpobjval;
1024 
1025  if( nbranchcands == 1 )
1026  {
1027  /* only one candidate: nothing has to be done */
1028  bestcand = 0;
1029  }
1030  else
1031  {
1032  SCIP_Real* initcandscores;
1033  int* initcands;
1034  int maxninitcands;
1035  int nbdchgs;
1036  SCIP_Real avgconflictscore;
1037  SCIP_Real avgconflengthscore;
1038  SCIP_Real avginferencescore;
1039  SCIP_Real avgcutoffscore;
1040  SCIP_Real avgpscostscore;
1041  SCIP_Real bestpsscore;
1042  SCIP_Real bestsbscore;
1043  SCIP_Real bestuninitsbscore;
1044  SCIP_Real bestsbfracscore;
1045  SCIP_Real bestsbdomainscore;
1046  int ninfprobings;
1047  int maxbdchgs;
1048  int bestpscand;
1049  int bestsbcand;
1050  int i;
1051  int j;
1052  int c;
1053  int ninitcands = 0;
1054 
1055  /* get average conflict, inference, and pseudocost scores */
1056  avgconflictscore = SCIPgetAvgConflictScore(scip);
1057  avgconflictscore = MAX(avgconflictscore, 0.1);
1058  avgconflengthscore = SCIPgetAvgConflictlengthScore(scip);
1059  avgconflengthscore = MAX(avgconflengthscore, 0.1);
1060  avginferencescore = SCIPgetAvgInferenceScore(scip);
1061  avginferencescore = MAX(avginferencescore, 0.1);
1062  avgcutoffscore = SCIPgetAvgCutoffScore(scip);
1063  avgcutoffscore = MAX(avgcutoffscore, 0.1);
1064  avgpscostscore = SCIPgetAvgPseudocostScore(scip);
1065  avgpscostscore = MAX(avgpscostscore, 0.1);
1066 
1067  /* get maximal number of candidates to initialize with strong branching; if the current solutions is not basic,
1068  * we cannot apply the simplex algorithm and therefore don't initialize any candidates
1069  */
1070  maxninitcands = MIN(nbranchcands, branchruledata->initcand);
1071 
1072  if( !SCIPisLPSolBasic(masterscip) )
1073  {
1074  maxninitcands = 0;
1075  SCIPdebugMessage("solution is not basic\n");
1076  }
1077 
1078  SCIPdebugMessage("maxninitcands = %d\n", maxninitcands);
1079 
1080  /* get buffer for storing the unreliable candidates */
1081  SCIP_CALL( SCIPallocBufferArray(scip, &initcands, maxninitcands+1) ); /* allocate one additional slot for convenience */
1082  SCIP_CALL( SCIPallocBufferArray(scip, &initcandscores, maxninitcands+1) );
1083 
1084  /* initialize bound change arrays */
1085  nbdchgs = 0;
1086  maxbdchgs = branchruledata->maxbdchgs;
1087 
1088  ninfprobings = 0;
1089 
1090 
1091  /* search for the best pseudo cost candidate, while remembering unreliable candidates in a sorted buffer */
1092  bestpscand = -1;
1093  bestpsscore = -SCIPinfinity(scip);
1094  for( c = 0; c < nbranchcands; ++c )
1095  {
1096  SCIP_Real conflictscore;
1097  SCIP_Real conflengthscore;
1098  SCIP_Real inferencescore;
1099  SCIP_Real cutoffscore;
1100  SCIP_Real pscostscore;
1101  SCIP_Real score;
1102 
1103  assert(branchcands[c] != NULL);
1104 
1105  /* get conflict, inference, cutoff, and pseudo cost scores for candidate */
1106  conflictscore = SCIPgetVarConflictScore(scip, branchcands[c]);
1107  conflengthscore = SCIPgetVarConflictlengthScore(scip, branchcands[c]);
1108  inferencescore = SCIPgetVarAvgInferenceScore(scip, branchcands[c]);
1109  cutoffscore = SCIPgetVarAvgCutoffScore(scip, branchcands[c]);
1110  pscostscore = SCIPgetVarPseudocostScore(scip, branchcands[c], branchcandssol[c]);
1111 
1112 
1113  /* combine the four score values */
1114  score = calcScore(scip, branchruledata, conflictscore, avgconflictscore, conflengthscore, avgconflengthscore,
1115  inferencescore, avginferencescore, cutoffscore, avgcutoffscore, pscostscore, avgpscostscore,
1116  branchcandssol[c] - SCIPfloor(scip, branchcandssol[c]));
1117 
1118  /* pseudo cost of variable is not reliable: insert candidate in initcands buffer */
1119  for( j = ninitcands; j > 0 && score > initcandscores[j-1]; --j )
1120  {
1121  initcands[j] = initcands[j-1];
1122  initcandscores[j] = initcandscores[j-1];
1123  }
1124 
1125  initcands[j] = c;
1126  initcandscores[j] = score;
1127  ninitcands++;
1128  ninitcands = MIN(ninitcands, maxninitcands);
1129  }
1130 
1131  /* initialize unreliable candidates with probing,
1132  * search best strong branching candidate
1133  */
1134  SCIPdebugMessage("ninitcands = %d\n", ninitcands);
1135 
1136  bestsbcand = -1;
1137  bestsbscore = -SCIPinfinity(scip);
1138  bestsbfracscore = -SCIPinfinity(scip);
1139  bestsbdomainscore = -SCIPinfinity(scip);
1140  for( i = 0; i < ninitcands; ++i )
1141  {
1142  SCIP_Real down;
1143  SCIP_Real up;
1144  SCIP_Real downgain;
1145  SCIP_Real upgain;
1146  SCIP_Bool downvalid;
1147  SCIP_Bool upvalid;
1148  SCIP_Bool lperror;
1149  SCIP_Bool downinf;
1150  SCIP_Bool upinf;
1151 
1152  lperror = FALSE;
1153  up = 0.;
1154  down = 0.;
1155 
1156  /* get candidate number to initialize */
1157  c = initcands[i];
1158 
1159  SCIPdebugMessage("init pseudo cost (%g/%g) of <%s> with bounds [%g,%g] at %g (score:%g)\n",
1160  SCIPgetVarPseudocostCountCurrentRun(scip, branchcands[c], SCIP_BRANCHDIR_DOWNWARDS),
1161  SCIPgetVarPseudocostCountCurrentRun(scip, branchcands[c], SCIP_BRANCHDIR_UPWARDS),
1162  SCIPvarGetName(branchcands[c]), SCIPvarGetLbLocal(branchcands[c]), SCIPvarGetUbLocal(branchcands[c]),
1163  branchcandssol[c], initcandscores[i]);
1164 
1165  /* try branching on this variable (propagation + lp solving (pricing) ) */
1166  SCIP_CALL( getVarProbingbranch(scip, branchcands[c], bdchgdata, branchruledata->uselp, &branchruledata->nlpiterations,
1167  &down, &up, &downvalid, &upvalid, &downinf, &upinf, &lperror, &nbdchgs) );
1168 
1169  branchruledata->nprobingnodes++;
1170  branchruledata->nprobingnodes++;
1171  SCIP_CALL( incNVarProbings(scip, branchrule, branchcands[c]) );
1172 
1173  /* check for an error in strong branching */
1174  if( lperror )
1175  {
1176  if( !SCIPisStopped(scip) )
1177  {
1178  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL,
1179  "(node %"SCIP_LONGINT_FORMAT") error in strong branching call for variable <%s> with solution %g\n",
1180  SCIPgetNNodes(scip), SCIPvarGetName(branchcands[c]), branchcandssol[c]);
1181  }
1182  break;
1183  }
1184 
1185 
1186  if( SCIPisStopped(scip) )
1187  {
1188  break;
1189  }
1190 
1191  /* check if there are infeasible roundings */
1192  if( downinf && upinf )
1193  {
1194  /* both roundings are infeasible -> node is infeasible */
1195  SCIPdebugMessage(" -> variable <%s> is infeasible in both directions\n",
1196  SCIPvarGetName(branchcands[c]));
1197 
1198  *result = SCIP_CUTOFF;
1199  break; /* terminate initialization loop, because node is infeasible */
1200  }
1201 
1202 
1203  /* evaluate strong branching */
1204  down = MAX(down, lpobjval);
1205  up = MAX(up, lpobjval);
1206  downgain = down - lpobjval;
1207  upgain = up - lpobjval;
1208  assert(!downvalid || downinf == SCIPisGE(scip, down, cutoffbound));
1209  assert(!upvalid || upinf == SCIPisGE(scip, up, cutoffbound));
1210 
1211  /* the minimal lower bound of both children is a proved lower bound of the current subtree */
1212  if( downvalid && upvalid )
1213  {
1214  SCIP_Real minbound;
1215 
1216  minbound = MIN(down, up);
1217  provedbound = MAX(provedbound, minbound);
1218  }
1219 
1220 
1221  /* terminate initialization loop, if enough roundings are performed */
1222  if( maxbdchgs >= 0 && nbdchgs >= maxbdchgs )
1223  break;
1224 
1225  /* case one rounding is infeasible is regarded in method SCIPgetVarProbingbranch */
1226  if( downinf || upinf )
1227  {
1228  branchruledata->ninfprobings++;
1229  ninfprobings++;
1230  }
1231 
1232  /* if both roundings are valid, update scores */
1233  if( !downinf && !upinf )
1234  {
1235  SCIP_Real frac;
1236  SCIP_Real conflictscore;
1237  SCIP_Real conflengthscore;
1238  SCIP_Real inferencescore;
1239  SCIP_Real cutoffscore;
1240  SCIP_Real pscostscore;
1241  SCIP_Real score;
1242 
1243  frac = branchcandssol[c] - SCIPfloor(scip, branchcandssol[c]);
1244 
1245  /* check for a better score */
1246  conflictscore = SCIPgetVarConflictScore(scip, branchcands[c]);
1247  conflengthscore = SCIPgetVarConflictlengthScore(scip, branchcands[c]);
1248  inferencescore = SCIPgetVarAvgInferenceScore(scip, branchcands[c]);
1249  cutoffscore = SCIPgetVarAvgCutoffScore(scip, branchcands[c]);
1250  pscostscore = SCIPgetBranchScore(scip, branchcands[c], downgain, upgain);
1251  score = calcScore(scip, branchruledata, conflictscore, avgconflictscore, conflengthscore, avgconflengthscore,
1252  inferencescore, avginferencescore, cutoffscore, avgcutoffscore, pscostscore, avgpscostscore, frac);
1253 
1254  if( SCIPisSumGE(scip, score, bestsbscore) )
1255  {
1256  SCIP_Real fracscore;
1257  SCIP_Real domainscore;
1258 
1259  fracscore = MIN(frac, 1.0 - frac);
1260  domainscore = -(SCIPvarGetUbLocal(branchcands[c]) - SCIPvarGetLbLocal(branchcands[c]));
1261  if( SCIPisSumGT(scip, score, bestsbscore )
1262  || SCIPisSumGT(scip, fracscore, bestsbfracscore)
1263  || (SCIPisSumGE(scip, fracscore, bestsbfracscore) && domainscore > bestsbdomainscore) )
1264  {
1265  bestsbcand = c;
1266  bestsbscore = score;
1267  bestsbfracscore = fracscore;
1268  bestsbdomainscore = domainscore;
1269  }
1270  }
1271 
1272  /* update pseudo cost values */
1273  assert(!SCIPisFeasNegative(scip, frac));
1274  SCIP_CALL( SCIPupdateVarPseudocost(scip, branchcands[c], 0.0-frac, downgain, 1.0) );
1275  SCIP_CALL( SCIPupdateVarPseudocost(scip, branchcands[c], 1.0-frac, upgain, 1.0) );
1276 
1277  SCIPdebugMessage(" -> variable <%s> (solval=%g, down=%g (%+g), up=%g (%+g), score=%g/ %g/%g %g/%g -> %g)\n",
1278  SCIPvarGetName(branchcands[c]), branchcandssol[c], down, downgain, up, upgain,
1279  pscostscore, conflictscore, conflengthscore, inferencescore, cutoffscore, score);
1280 
1281  }
1282  }
1283 #ifdef SCIP_DEBUG
1284  if( bestsbcand >= 0 )
1285  {
1286  SCIPdebugMessage(" -> best: <%s> (%g / %g / %g)\n",
1287  SCIPvarGetName(branchcands[bestsbcand]), bestsbscore, bestsbfracscore, bestsbdomainscore);
1288  }
1289 #endif
1290  if( bestsbcand >= 0 )
1291  {
1292  SCIPdebugMessage(" -> best: <%s> (%g / %g / %g)\n",
1293  SCIPvarGetName(branchcands[bestsbcand]), bestsbscore, bestsbfracscore, bestsbdomainscore);
1294  }
1295 
1296  /* get the score of the best uninitialized strong branching candidate */
1297  if( i < ninitcands )
1298  bestuninitsbscore = initcandscores[i];
1299  else
1300  bestuninitsbscore = -SCIPinfinity(scip);
1301 
1302  /* if the best pseudo cost candidate is better than the best uninitialized strong branching candidate,
1303  * compare it to the best initialized strong branching candidate
1304  */
1305  if( bestpsscore > bestuninitsbscore && SCIPisSumGT(scip, bestpsscore, bestsbscore) )
1306  {
1307  bestcand = bestpscand;
1308 #ifdef SCIP_DEBUG
1309  bestisstrongbranch = FALSE;
1310 #endif
1311  }
1312  else if( bestsbcand >= 0 )
1313  {
1314  bestcand = bestsbcand;
1315 #ifdef SCIP_DEBUG
1316  bestisstrongbranch = TRUE;
1317 #endif
1318  }
1319  else
1320  {
1321  /* no candidate was initialized, and the best score is the one of the first candidate in the initialization
1322  * queue
1323  */
1324  assert(ninitcands >= 1);
1325  bestcand = initcands[0];
1326 #ifdef SCIP_DEBUG
1327  bestisstrongbranch = FALSE;
1328 #endif
1329  }
1330 
1331  /* apply domain reductions */
1332  if( (nbdchgs >= branchruledata->minbdchgs || ninfprobings >= 5 )
1333  && *result != SCIP_CUTOFF && !SCIPisStopped(scip) )
1334  {
1335  SCIP_CALL( applyBdchgs(scip, bdchgdata, SCIPgetCurrentNode(scip)) );
1336  branchruledata->nresolvesminbdchgs++;
1337  *result = SCIP_REDUCEDDOM; /* why was this commented out?? */
1338  }
1339 
1340  /* free buffer for the unreliable candidates */
1341  SCIPfreeBufferArray(scip, &initcandscores);
1342  SCIPfreeBufferArray(scip, &initcands);
1343  }
1344 
1345  /* if no domain could be reduced, create the branching */
1346  if( *result != SCIP_CUTOFF && *result != SCIP_REDUCEDDOM
1347  && *result != SCIP_CONSADDED && !SCIPisStopped(scip) )
1348  {
1349  assert(*result == SCIP_DIDNOTRUN);
1350  assert(0 <= bestcand && bestcand < nbranchcands);
1351  assert(SCIPisLT(scip, provedbound, cutoffbound));
1352 
1353 #ifdef SCIP_DEBUG
1354  SCIPdebugMessage(" -> best: <%s> (strongbranch = %ud)\n", SCIPvarGetName(branchcands[bestcand]), bestisstrongbranch);
1355 #endif
1356  *branchvar = branchcands[bestcand];
1357  SCIP_CALL( incNVarBranchings(scip, branchrule, *branchvar) );
1358  }
1359 
1360  /* free data structure for bound change infos */
1361  SCIP_CALL( freeBdchgData(scip, bdchgdata) );
1362 
1363  return SCIP_OKAY;
1364 }
1365 
1366 
1367 /*
1368  * Callback methods
1369  */
1370 
1371 /** destructor of branching rule to free user data (called when SCIP is exiting) */
1372 static
1373 SCIP_DECL_BRANCHFREE(branchFreeRelpsprob)
1374 { /*lint --e{715}*/
1375  SCIP_BRANCHRULEDATA* branchruledata;
1376 
1377  /* free branching rule data */
1378  branchruledata = SCIPbranchruleGetData(branchrule);
1379 
1380  SCIPdebugMessage("**needed in total %d probing nodes\n", branchruledata->nprobingnodes);
1381 
1382  SCIPfreeMemory(scip, &branchruledata);
1383  SCIPbranchruleSetData(branchrule, NULL);
1384 
1385  return SCIP_OKAY;
1386 }
1387 
1388 
1389 /** solving process initialization method of branching rule (called when branch and bound process is about to begin) */
1390 static
1391 SCIP_DECL_BRANCHINITSOL(branchInitsolRelpsprob)
1392 { /*lint --e{715}*/
1393  SCIP_BRANCHRULEDATA* branchruledata;
1394 
1395  /* free branching rule data */
1396  branchruledata = SCIPbranchruleGetData(branchrule);
1397 
1398  branchruledata->nprobingnodes = 0;
1399  branchruledata->nlpiterations = 0;
1400 
1401  branchruledata->nprobings = 0;
1402  branchruledata->nbranchings = 0;
1403  branchruledata->ninfprobings = 0;
1404  branchruledata->nresolvesminbdchgs = 0;
1405  branchruledata->nresolvesinfcands = 0;
1406 
1407  branchruledata->varhashmap = NULL;
1408  branchruledata->nvarbranchings = NULL;
1409  branchruledata->nvarprobings = NULL;
1410  branchruledata->nvars = 0;
1411  branchruledata->maxvars = 0;
1412 
1413  return SCIP_OKAY;
1414 }
1415 
1416 /** solving process deinitialization method of branching rule (called before branch and bound process data is freed) */
1417 static
1418 SCIP_DECL_BRANCHEXITSOL(branchExitsolRelpsprob)
1419 { /*lint --e{715}*/
1420  SCIP_BRANCHRULEDATA* branchruledata;
1421 
1422  /* free branching rule data */
1423  branchruledata = SCIPbranchruleGetData(branchrule);
1424 
1425  SCIPdebugMessage("**in total: nprobings = %d; part of it are ninfprobings = %d\n",
1426  branchruledata->nprobings, branchruledata->ninfprobings );
1427 
1428  SCIPdebugMessage("**nbranchings = %d, nresolvesinfcands = %d, nresolvesminbdchgs = %d\n",
1429  branchruledata->nbranchings, branchruledata->nresolvesinfcands, branchruledata->nresolvesminbdchgs );
1430 
1431 
1432  /* free arrays for variables & hashmap */
1433  SCIPfreeBlockMemoryArrayNull(scip, &branchruledata->nvarprobings, branchruledata->maxvars);
1434  SCIPfreeBlockMemoryArrayNull(scip, &branchruledata->nvarbranchings, branchruledata->maxvars);
1435  branchruledata->nvars = 0;
1436 
1437  if( branchruledata->varhashmap != NULL )
1438  {
1439  SCIPhashmapFree(&(branchruledata->varhashmap));
1440  }
1441 
1442  return SCIP_OKAY;
1443 }
1444 
1445 
1446 /*
1447  * branching specific interface methods
1448  */
1449 
1450 /** creates the reliable pseudo cost braching rule and includes it in SCIP */
1452  SCIP* scip /**< SCIP data structure */
1453  )
1454 {
1455  SCIP* origscip;
1456  SCIP_BRANCHRULE* branchrule;
1457  SCIP_BRANCHRULEDATA* branchruledata;
1458 
1459  /* get original problem */
1460  origscip = GCGmasterGetOrigprob(scip);
1461  assert(origscip != NULL);
1462 
1463  /* create relpsprob branching rule data */
1464  SCIP_CALL( SCIPallocMemory(scip, &branchruledata) );
1465 
1466  /* include branching rule */
1467  SCIP_CALL( SCIPincludeBranchruleBasic(scip, &branchrule, BRANCHRULE_NAME, BRANCHRULE_DESC, BRANCHRULE_PRIORITY,
1468  BRANCHRULE_MAXDEPTH, BRANCHRULE_MAXBOUNDDIST, branchruledata) );
1469  assert(branchrule != NULL);
1470 
1471  /* set non fundamental callbacks via setter functions */
1472  SCIP_CALL( SCIPsetBranchruleFree(scip, branchrule, branchFreeRelpsprob) );
1473  SCIP_CALL( SCIPsetBranchruleInitsol(scip, branchrule, branchInitsolRelpsprob) );
1474  SCIP_CALL( SCIPsetBranchruleExitsol(scip, branchrule, branchExitsolRelpsprob) );
1475 
1476  /* relpsprob branching rule parameters */
1477  SCIP_CALL( SCIPaddRealParam(origscip,
1478  "branching/relpsprob/conflictweight",
1479  "weight in score calculations for conflict score",
1480  &branchruledata->conflictweight, TRUE, DEFAULT_CONFLICTWEIGHT, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
1481  SCIP_CALL( SCIPaddRealParam(origscip,
1482  "branching/relpsprob/conflictlengthweight",
1483  "weight in score calculations for conflict length score",
1484  &branchruledata->conflengthweight, TRUE, DEFAULT_CONFLENGTHWEIGHT, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
1485  SCIP_CALL( SCIPaddRealParam(origscip,
1486  "branching/relpsprob/inferenceweight",
1487  "weight in score calculations for inference score",
1488  &branchruledata->inferenceweight, TRUE, DEFAULT_INFERENCEWEIGHT, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
1489  SCIP_CALL( SCIPaddRealParam(origscip,
1490  "branching/relpsprob/cutoffweight",
1491  "weight in score calculations for cutoff score",
1492  &branchruledata->cutoffweight, TRUE, DEFAULT_CUTOFFWEIGHT, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
1493  SCIP_CALL( SCIPaddRealParam(origscip,
1494  "branching/relpsprob/pscostweight",
1495  "weight in score calculations for pseudo cost score",
1496  &branchruledata->pscostweight, TRUE, DEFAULT_PSCOSTWEIGHT, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
1497  SCIP_CALL( SCIPaddRealParam(origscip,
1498  "branching/relpsprob/minreliable",
1499  "minimal value for minimum pseudo cost size to regard pseudo cost value as reliable",
1500  &branchruledata->minreliable, TRUE, DEFAULT_MINRELIABLE, 0.0, SCIP_REAL_MAX, NULL, NULL) );
1501  SCIP_CALL( SCIPaddRealParam(origscip,
1502  "branching/relpsprob/maxreliable",
1503  "maximal value for minimum pseudo cost size to regard pseudo cost value as reliable",
1504  &branchruledata->maxreliable, TRUE, DEFAULT_MAXRELIABLE, 0.0, SCIP_REAL_MAX, NULL, NULL) );
1505  SCIP_CALL( SCIPaddRealParam(origscip,
1506  "branching/relpsprob/iterquot",
1507  "maximal fraction of branching LP iterations compared to node relaxation LP iterations",
1508  &branchruledata->iterquot, FALSE, DEFAULT_ITERQUOT, 0.0, SCIP_REAL_MAX, NULL, NULL) );
1509  SCIP_CALL( SCIPaddIntParam(origscip,
1510  "branching/relpsprob/iterofs",
1511  "additional number of allowed LP iterations",
1512  &branchruledata->iterofs, FALSE, DEFAULT_ITEROFS, 0, INT_MAX, NULL, NULL) );
1513  SCIP_CALL( SCIPaddIntParam(origscip,
1514  "branching/relpsprob/maxlookahead",
1515  "maximal number of further variables evaluated without better score",
1516  &branchruledata->maxlookahead, TRUE, DEFAULT_MAXLOOKAHEAD, 1, INT_MAX, NULL, NULL) );
1517  SCIP_CALL( SCIPaddIntParam(origscip,
1518  "branching/relpsprob/initcand",
1519  "maximal number of candidates initialized with strong branching per node",
1520  &branchruledata->initcand, FALSE, DEFAULT_INITCAND, 0, INT_MAX, NULL, NULL) );
1521  SCIP_CALL( SCIPaddIntParam(origscip,
1522  "branching/relpsprob/maxbdchgs",
1523  "maximal number of bound tightenings before the node is immediately reevaluated (-1: unlimited)",
1524  &branchruledata->maxbdchgs, TRUE, DEFAULT_MAXBDCHGS, -1, INT_MAX, NULL, NULL) );
1525  SCIP_CALL( SCIPaddIntParam(origscip,
1526  "branching/relpsprob/minbdchgs",
1527  "minimal number of bound tightenings before bound changes are applied",
1528  &branchruledata->minbdchgs, TRUE, DEFAULT_MINBDCHGS, 1, INT_MAX, NULL, NULL) );
1529  SCIP_CALL( SCIPaddBoolParam(origscip,
1530  "branching/relpsprob/uselp",
1531  "shall the LP be solved during probing? (TRUE)",
1532  &branchruledata->uselp, FALSE, DEFAULT_USELP, NULL, NULL) );
1533  SCIP_CALL( SCIPaddRealParam(origscip,
1534  "branching/relpsprob/reliability",
1535  "reliability value for probing",
1536  &branchruledata->reliability, FALSE, DEFAULT_RELIABILITY, 0.0, 1.0, NULL, NULL) );
1537 
1538  /* notify cons_integralorig about the original variable branching rule */
1539  SCIP_CALL( GCGconsIntegralorigAddBranchrule(scip, branchrule) );
1540 
1541  return SCIP_OKAY;
1542 }
1543 
1544 /** execution reliability pseudo cost probing branching with the given branching candidates */
1546  SCIP* scip, /**< SCIP data structure */
1547  SCIP_VAR** branchcands, /**< brancing candidates */
1548  SCIP_Real* branchcandssol, /**< solution value for the branching candidates */
1549  int nbranchcands, /**< number of branching candidates */
1550  int nvars, /**< number of variables to be watched by bdchgdata */
1551  SCIP_RESULT* result, /**< pointer to the result of the execution */
1552  SCIP_VAR** branchvar /**< pointer to the variable to branch on */
1553  )
1554 {
1555  SCIP_BRANCHRULE* branchrule;
1556  SCIP* origscip;
1557 
1558  assert(scip != NULL);
1559  assert(result != NULL);
1560 
1561  /* find branching rule */
1562  branchrule = SCIPfindBranchrule(scip, BRANCHRULE_NAME);
1563  assert(branchrule != NULL);
1564  origscip = GCGmasterGetOrigprob(scip);
1565  assert(origscip != NULL);
1566 
1567  /* execute branching rule */
1568  SCIP_CALL( execRelpsprob(origscip, branchrule, branchcands, branchcandssol, nbranchcands, nvars, result, branchvar) );
1569 
1570  return SCIP_OKAY;
1571 }
#define DEFAULT_MAXLOOKAHEAD
#define DEFAULT_INFERENCEWEIGHT
#define DEFAULT_CUTOFFWEIGHT
SCIP_RETCODE SCIPincludeBranchruleRelpsprob(SCIP *scip)
GCG interface methods.
#define BRANCHRULE_DESC
static SCIP_RETCODE applyBdchgs(SCIP *scip, BDCHGDATA *bdchgdata, SCIP_NODE *node)
SCIP_RETCODE GCGrelaxNewProbingnodeMaster(SCIP *scip)
Definition: relax_gcg.c:4378
#define DEFAULT_MAXBDCHGS
SCIP_Bool * infroundings
static SCIP_RETCODE incNVarBranchings(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_VAR *var)
SCIP_HASHMAP * varhashmap
static SCIP_RETCODE incNVarProbings(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_VAR *var)
GCG variable pricer.
SCIP_RETCODE SCIPgetRelpsprobBranchVar(SCIP *scip, SCIP_VAR **branchcands, SCIP_Real *branchcandssol, int nbranchcands, int nvars, SCIP_RESULT *result, SCIP_VAR **branchvar)
static SCIP_RETCODE addBdchg(SCIP *scip, BDCHGDATA *bdchgdata, SCIP_VAR *var, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype, SCIP_Bool infrounding, int *nbdchgs, SCIP_Bool *infeasible)
#define DEFAULT_CONFLENGTHWEIGHT
SCIP_RETCODE GCGrelaxEndProbing(SCIP *scip)
Definition: relax_gcg.c:4658
static SCIP_DECL_BRANCHEXITSOL(branchExitsolRelpsprob)
SCIP * GCGgetMasterprob(SCIP *scip)
Definition: relax_gcg.c:3920
constraint handler for the integrality constraint
#define DEFAULT_ITEROFS
static SCIP_RETCODE freeBdchgData(SCIP *scip, BDCHGDATA *bdchgdata)
#define DEFAULT_MINBDCHGS
SCIP_Real * ubchgs
#define BRANCHRULE_MAXBOUNDDIST
#define DEFAULT_ITERQUOT
static SCIP_RETCODE createBdchgData(SCIP *scip, BDCHGDATA **bdchgdata, SCIP_VAR **vars, int nvars)
#define DEFAULT_INITCAND
static SCIP_RETCODE applyProbing(SCIP *scip, SCIP_VAR **vars, int nvars, SCIP_VAR *probingvar, SCIP_Bool probingdir, SCIP_Bool solvelp, SCIP_Longint *nlpiterations, SCIP_Real *proplbs, SCIP_Real *propubs, SCIP_Real *lpobjvalue, SCIP_Bool *lpsolved, SCIP_Bool *lperror, SCIP_Bool *cutoff)
SCIP_RETCODE GCGrelaxStartProbing(SCIP *scip, SCIP_HEUR *probingheur)
Definition: relax_gcg.c:4264
#define BRANCHRULE_PRIORITY
SCIP_RETCODE GCGrelaxNewProbingnodeOrig(SCIP *scip)
Definition: relax_gcg.c:4331
SCIP * GCGmasterGetOrigprob(SCIP *scip)
#define DEFAULT_USELP
static SCIP_RETCODE addBranchcandsToData(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_VAR **branchcands, int nbranchcands)
static SCIP_RETCODE execRelpsprob(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_VAR **branchcands, SCIP_Real *branchcandssol, int nbranchcands, int nvars, SCIP_RESULT *result, SCIP_VAR **branchvar)
#define BRANCHRULE_NAME
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 frac)
#define DEFAULT_RELIABILITY
SCIP_Real * lbchgs
#define BRANCHRULE_MAXDEPTH
GCG relaxator.
#define DEFAULT_PSCOSTWEIGHT
#define DEFAULT_CONFLICTWEIGHT
static SCIP_DECL_BRANCHINITSOL(branchInitsolRelpsprob)
SCIP_RETCODE GCGrelaxPerformProbingWithPricing(SCIP *scip, int maxpricerounds, SCIP_Longint *nlpiterations, int *npricerounds, SCIP_Real *lpobjvalue, SCIP_Bool *lpsolved, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: relax_gcg.c:4639
SCIP_Longint nlpiterations
#define DEFAULT_MINRELIABLE
SCIP_HASHMAP * varhashmap
static SCIP_RETCODE getVarProbingbranch(SCIP *scip, SCIP_VAR *probingvar, BDCHGDATA *bdchgdata, SCIP_Bool solvelp, SCIP_Longint *nlpiterations, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *lperror, int *nbdchgs)
#define DEFAULT_MAXRELIABLE
reliable pseudo costs branching rule
static SCIP_RETCODE calculateBounds(SCIP *scip, SCIP_VAR *branchvar, SCIP_Real *downlb, SCIP_Real *downub, SCIP_Real *uplb, SCIP_Real *upub)
static SCIP_DECL_BRANCHFREE(branchFreeRelpsprob)
#define HASHSIZE_VARS
SCIP_RETCODE GCGconsIntegralorigAddBranchrule(SCIP *scip, SCIP_BRANCHRULE *branchrule)