SCIP Doxygen Documentation
Loading...
Searching...
No Matches
branch_multaggr.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2026 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24/**@file branch_multaggr.c
25 * @ingroup DEFPLUGINS_BRANCH
26 * @brief fullstrong branching on fractional and multi-aggregated variables
27 * @author Anna Melchiori
28 * @author Gerald Gamrath
29 *
30 * This branching rule uses all fractional binary and integer variables as candidates,
31 * as well as fractional multiaggregated binary and integer variables. Although not
32 * directly contained in the presolved problem anymore, the multi-aggregation provides
33 * an affine linear sum of integer variables, on which branching can be performed.
34 *
35 * For more details, see
36 * G.Gamrath, A.Melchiori, T.Berthold, A.M.Gleixner, D.Salvagnin: Branching on Multi-aggregated Variables
37 * (http://dx.doi.org/10.1007/978-3-319-18008-3_10)
38 */
39/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
40
44#include "scip/cons_linear.h"
45#include "scip/pub_branch.h"
46#include "scip/pub_cons.h"
47#include "scip/pub_message.h"
48#include "scip/pub_tree.h"
49#include "scip/pub_var.h"
50#include "scip/scip_branch.h"
51#include "scip/scip_cons.h"
52#include "scip/scip_exact.h"
53#include "scip/scip_general.h"
54#include "scip/scip_lp.h"
55#include "scip/scip_mem.h"
56#include "scip/scip_message.h"
57#include "scip/scip_numerics.h"
58#include "scip/scip_param.h"
59#include "scip/scip_prob.h"
60#include "scip/scip_probing.h"
62#include "scip/scip_timing.h"
63#include "scip/scip_tree.h"
64#include "scip/scip_var.h"
65
66
67#define BRANCHRULE_NAME "multaggr"
68#define BRANCHRULE_DESC "fullstrong branching on fractional and multi-aggregated variables"
69#define BRANCHRULE_PRIORITY 0
70#define BRANCHRULE_MAXDEPTH -1
71#define BRANCHRULE_MAXBOUNDDIST 1.0
72
73
74#define DEFAULT_REEVALAGE 0LL /**< number of intermediate LPs solved to trigger reevaluation of strong branching
75 * value for a variable that was already evaluated at the current node */
76#define DEFAULT_MAXPROPROUNDS 0 /**< maximum number of propagation rounds to be performed during multaggr branching
77 * before solving the LP (-1: no limit, -2: parameter settings) */
78#define DEFAULT_PROBINGBOUNDS TRUE /**< should valid bounds be identified in a probing-like fashion during multi-aggr
79 * branching (only with propagation)? */
80
81/*
82 * Data structures
83 */
84
85/** branching rule data */
86struct SCIP_BranchruleData
87{
88 SCIP_Longint reevalage; /**< number of intermediate LPs solved to trigger reevaluation of strong branching
89 * value for a variable that was already evaluated at the current node */
90 SCIP_Bool probingbounds; /**< should valid bounds be identified in a probing-like fashion during strong
91 * branching (only with propagation)? */
92 int lastcand; /**< last evaluated candidate of last branching rule execution */
93 int maxproprounds; /**< maximum number of propagation rounds to be performed during strong branching
94 * before solving the LP (-1: no limit, -2: parameter settings) */
95 int skipsize; /**< size of skipdown and skipup array */
96 SCIP_Bool* skipdown; /**< should be branching on down child be skipped? */
97 SCIP_Bool* skipup; /**< should be branching on up child be skipped? */
98#ifdef SCIP_STATISTIC
99 SCIP_CLOCK* clckstrongbr; /**< clock to store the time spent inside the strong branching function on fractional variables */
100 SCIP_CLOCK* clckmultaggrbr; /**< clock to store the time spent inside the strong branching function on multi-aggragated variables */
101 SCIP_Real* ratioggain; /**< for each occurence of a branching on a multi-aggregated variable we store the ratio of the gain that
102 * we would have obtained branching on the best fractional variable over the gain obtained
103 * branching on the current multi-aggregated variable */
104 SCIP_Real ameanratio; /**< arithmetic mean of the ratioggain array */
105 SCIP_Bool noupdate; /**< pointer to store if the probing LP has not been solved so we do not want to
106 * update statistics */
107 int firstmultaggrdepth; /**< depth of the first branching on a multi-aggregated variable */
108 int rundepth; /**< the run of the first multi-aggregated branching */
109 int nmultaggrbranch; /**< number of branchings on multi-aggregated variables */
110 int nfracbranch; /**< number of branchings on fractional variables */
111 int nEscore; /**< number of times that the bestscore over all multi-aggregated variables is equal to the best
112 * fractional variables score and thus we do not branch on the multi-aggregate variable */
113 int nmultaggrcutoff; /**< number of cutoffs detected during the probing mode on multi-aggregated variables */
114 int nmultaggrconsadd; /**< number of times that a probing constraint of a multi-aggregated variable has been
115 * added to the original problem */
116 int nfractcutoff; /**< number of cutoffs detected during strong branching on fractional variables */
117 int nfractconsadd; /**< number of times that during strong branching on fractional variables a constraint has been
118 * added to the original problem or a variables domain has been reduced */
119 int nmultaggrvars; /**< number of multi-aggregated variables in the problem of the last run */
120 int nrun; /**< number of restarts */
121 int size; /**< size of the provided array to store the ratio gain */
122 int nstrongbrcall; /**< number of times that the selectVarstrongBranching function has been called */
123 int nmultaggrbrcall; /**< number of times that the selectVarMultAggrBranching function has been called */
124 int totallpcands; /**< total number of observed lpcands over all selectVarstrongBranching function calls */
125 int totalmultaggrcands; /**< total number of observed multi-aggregregated candidates over all selectVarMultAggrBranching
126 * function calls */
127#endif
128};
129
130
131/*
132 * Local methods
133 */
134
135/* this function ensures that the allocated memory is enough to store statistics data */
136#ifdef SCIP_STATISTIC
137static
138SCIP_RETCODE ensureArraySize(
139 SCIP* scip, /**< original SCIP data structure */
140 SCIP_BRANCHRULEDATA* branchruledata /**< branching rule data */
141 )
142{
143 assert(scip != NULL);
144 assert(branchruledata != NULL);
145 assert(branchruledata->ratioggain != NULL);
146 assert(branchruledata->nmultaggrbranch >= 0);
147 assert(branchruledata->size >= 0);
148
149 /* check whether the size of the array is big enough; reallocate memory if needed */
150 if( branchruledata->nmultaggrbranch + 1 > branchruledata->size )
151 {
152 int newsize = SCIPcalcMemGrowSize(scip, branchruledata->nmultaggrbranch + 1);
153 assert(newsize >= branchruledata->nmultaggrbranch + 1);
154 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &branchruledata->ratioggain, branchruledata->size, newsize) );
155 branchruledata->size = newsize;
156 }
157 return SCIP_OKAY;
158}
159#endif
160
161/* this function gives us the best candidate for branching among the multi-aggregated variables of the problem
162 * and the best fractional integer variable already selected by strong branching
163*/
164static
166 SCIP* scip, /**< original SCIP data structure */
167 SCIP_VAR** bestcand, /**< the best candidate variable selected by strong branching */
168 SCIP_Real* bestscore, /**< score of the best branching candidate */
169 SCIP_Real* bestsol, /**< solution value of the best branching candidate */
170 SCIP_Real* bestdown, /**< objective value of the down node when branching on bestcand */
171 SCIP_Real* bestup, /**< objective value of the up node when branching on bestcand */
172 SCIP_Bool* bestdownvalid, /**< is bestdown a valid dual bound for the down branch? */
173 SCIP_Bool* bestupvalid, /**< is bestup a valid dual bound for the up branch? */
174 SCIP_Real* provedbound, /**< proved dual bound for the current subtree */
175 SCIP_Real* estimatedown, /**< pointer to store the down child nodes estimate */
176 SCIP_Real* estimateup, /**< pointer to store the up child nodes estimate */
177#ifdef SCIP_STATISTIC
178 SCIP_Real* bestmultaggrscore, /**< pointer to store the multi aggregated score */
179#endif
180 SCIP_RESULT* result /**< pointer to store results of branching */
181 )
182{
183 SCIP_VAR** fixvars;
184 SCIP_CONS* probingconsdown;
185 SCIP_CONS* probingconsup;
186 SCIP_NODE* node;
187 SCIP_Real* fixvarssols;
188 SCIP_Real fixvarssol;
189 SCIP_Real lpobjval;
190 SCIP_Bool exactsolve;
191 SCIP_Bool allcolsinlp;
192 SCIP_Bool downnodeinf = FALSE;
193 SCIP_Bool startprobing = TRUE;
194 SCIP_Bool endprobing = FALSE;
195 int nfixvars;
196 int i;
197 int j;
198 int k;
199
200 /* import branchrule data for statistics */
201#ifdef SCIP_STATISTIC
202 SCIP_BRANCHRULE* branchrule;
203 SCIP_BRANCHRULEDATA* branchruledata;
204
206 assert(branchrule != NULL);
207
208 branchruledata = SCIPbranchruleGetData(branchrule);
209 assert(branchruledata != NULL);
210#endif
211
212 assert(scip != NULL);
213 assert(bestcand != NULL);
214 assert(bestscore != NULL);
215
216 /* check, if we want to solve the problem exactly, meaning that strong branching information is not useful
217 * for cutting off sub problems and improving lower bounds of children
218 */
219 exactsolve = SCIPisExact(scip);
220
221 /* check, if all existing columns are in LP, and thus the strong branching results give lower bounds */
222 allcolsinlp = SCIPallColsInLP(scip);
223
224 /* get fixed variables */
225 fixvars = SCIPgetFixedVars(scip);
226 nfixvars = SCIPgetNFixedVars(scip);
227 SCIPdebugMsg(scip, " fractional variable: <%s> with value: %f is selected by strong branching\n", SCIPvarGetName(*bestcand), *bestsol);
228
229 /* check if we would exceed the depth limit */
231 {
232 SCIPdebugMsg(scip, "cannot perform probing in selectVarMultAggrBranching, depth limit reached.\n");
234 return SCIP_OKAY;
235 }
236
237 if( nfixvars != 0 )
238 {
239 assert(fixvars != NULL);
240
241 SCIP_CALL( SCIPallocBufferArray(scip, &fixvarssols, nfixvars) );
242 lpobjval = SCIPgetLPObjval(scip);
243
244 /* store the values of the fixed variables at the current optimal solution */
245 for( i = 0; i < nfixvars; i++ )
246 {
247 assert(fixvars[i] != NULL);
248 fixvarssols[i] = SCIPvarGetLPSol(fixvars[i]);
249 }
250
251 for( i = 0; i < nfixvars; i++ )
252 {
253 assert(fixvars[i] != NULL);
254
255 /* only integer and binary multi-aggregated variables are potential branching candidates */
257 {
258 fixvarssol = fixvarssols[i];
259
260 /* start probing mode for the fractional multi-aggregated variable */
261 if( !SCIPisFeasIntegral(scip, fixvarssol) )
262 {
263 SCIP_VAR** downvars = NULL;
264 SCIP_VAR** upvars = NULL;
265 SCIP_Real* downvarssols = NULL;
266 SCIP_Real* upvarssols = NULL;
267 SCIP_LPSOLSTAT solstatdown;
268 SCIP_LPSOLSTAT solstatup;
269 SCIP_Real downobjval;
270 SCIP_Real upobjval;
271 SCIP_Real estimateprobdown = 0.0;
272 SCIP_Real estimateprobup = 0.0;
273 SCIP_Bool downinf;
274 SCIP_Bool upinf;
276 int ndownvars;
277 int nupvars;
278
279 /* start the probing mode if this is the first entrance */
280 if( startprobing )
281 {
283 startprobing = FALSE;
284 endprobing = TRUE;
285
286 SCIPdebugMsg(scip, "PROBING MODE:\n");
287 }
288
289 SCIPdebugMsg(scip, " multi-aggregated variable: <%s> with value: %f\n", SCIPvarGetName(fixvars[i]), fixvarssol);
290
291 SCIPstatistic(branchruledata->totalmultaggrcands += 1);
292
293 /* create the multi-aggregated rounded down constraint */
294 SCIP_CALL( SCIPcreateConsLinear(scip, &probingconsdown, "probingconsdown", SCIPvarGetMultaggrNVars(fixvars[i]),
296 SCIPfeasFloor(scip, fixvarssol) - SCIPvarGetMultaggrConstant(fixvars[i]), TRUE, TRUE, FALSE, FALSE,
297 TRUE, TRUE, FALSE, FALSE, FALSE, TRUE) );
298 assert(probingconsdown != NULL);
299
300 /* create the down child probing node */
302 node = SCIPgetCurrentNode(scip);
303 assert(node != NULL);
304
305 SCIP_CALL( SCIPaddConsNode(scip, node, probingconsdown, NULL) );
306 SCIP_CALL( SCIPreleaseCons(scip, &probingconsdown) );
307
308#ifdef PRINTNODECONS
309 SCIPdebugMsg(scip, " created down probing node with constraint:\n");
310 SCIP_CALL( SCIPprintCons(scip, probingconsdown, NULL) );
311 SCIPinfoMessage(scip, NULL, "\n");
312#endif
313
314 /* solve the down child probing node */
315 SCIP_CALL( SCIPsolveProbingLP(scip, -1, &lperror, &downinf) );
316 solstatdown = SCIPgetLPSolstat(scip);
317 lperror = lperror || (solstatdown == SCIP_LPSOLSTAT_NOTSOLVED && downinf == 0) || (solstatdown == SCIP_LPSOLSTAT_ITERLIMIT) ||
318 (solstatdown == SCIP_LPSOLSTAT_TIMELIMIT);
319 assert(solstatdown != SCIP_LPSOLSTAT_UNBOUNDEDRAY);
320
321 /* break the branching rule if an error occurred, problem was not solved, iteration or time limit was reached */
322 if( lperror )
323 {
324 SCIPdebugMsg(scip, "error solving down node probing LP: status=%d\n", solstatdown);
325 SCIPstatistic(branchruledata->noupdate = TRUE);
326 break;
327 }
328
329 downobjval = SCIPgetLPObjval(scip);
330 downinf = downinf || SCIPisGE(scip, downobjval, SCIPgetCutoffbound(scip));
331 assert(((solstatdown != SCIP_LPSOLSTAT_INFEASIBLE) && (solstatdown != SCIP_LPSOLSTAT_OBJLIMIT)) || downinf);
332
333 if( !downinf )
334 {
335 /* when an optimal solution has been found calculate down child's estimate based on pseudo costs */
336 /* estimate = lowerbound + sum(min{f_j * pscdown_j, (1-f_j) * pscup_j}) */
337 estimateprobdown = SCIPnodeGetLowerbound(node);
338 SCIP_CALL( SCIPgetLPBranchCands(scip, &downvars, &downvarssols, NULL, &ndownvars, NULL, NULL) );
339
340 for( j = 0 ; j < ndownvars; j++ )
341 {
342 SCIP_Real estimateincr;
343 SCIP_Real pscdown;
344 SCIP_Real pscup;
345
346 assert(downvars != NULL);
347 assert(downvars[j] != NULL);
348
349 pscdown = SCIPgetVarPseudocostVal(scip, downvars[j], SCIPfeasFloor(scip, downvarssols[j]) - downvarssols[j]);
350 pscup = SCIPgetVarPseudocostVal(scip, downvars[j], SCIPfeasCeil(scip, downvarssols[j]) - downvarssols[j]);
351 estimateincr = MIN(pscdown, pscup);
352
353 estimateprobdown += estimateincr;
354 }
355 }
357
358 /* create the multi-aggregated rounded up constraint */
359 SCIP_CALL( SCIPcreateConsLinear(scip, &probingconsup, "probingconsup", SCIPvarGetMultaggrNVars(fixvars[i]), SCIPvarGetMultaggrVars(fixvars[i]),
362 assert(probingconsup != NULL);
363
364 /* create the up child probing node */
366 node = SCIPgetCurrentNode(scip);
367
368 SCIP_CALL( SCIPaddConsNode(scip, node, probingconsup, NULL) );
369 SCIP_CALL( SCIPreleaseCons(scip, &probingconsup) );
370
371#ifdef PRINTNODECONS
372 SCIPdebugMsg(scip, " created up probing node with constraint:\n");
373 SCIP_CALL( SCIPprintCons(scip, probingconsup, NULL) );
374 SCIPinfoMessage(scip, NULL, "\n");
375#endif
376 /* solve the up child probing node */
377 SCIP_CALL( SCIPsolveProbingLP(scip, -1, &lperror, &upinf) );
378 solstatup = SCIPgetLPSolstat(scip);
379 lperror = lperror || (solstatup == SCIP_LPSOLSTAT_NOTSOLVED && upinf == 0) || (solstatup == SCIP_LPSOLSTAT_ITERLIMIT) ||
380 (solstatup == SCIP_LPSOLSTAT_TIMELIMIT);
382
383 /* break the branching rule if an error occurred, problem was not solved, iteration or time limit was reached */
384 if( lperror )
385 {
386 SCIPdebugMsg(scip, "error solving up node probing LP: status=%d\n", solstatup);
387 SCIPstatistic(branchruledata->noupdate = TRUE);
388 break;
389 }
390
391 upobjval = SCIPgetLPObjval(scip);
392 upinf = upinf || SCIPisGE(scip, upobjval, SCIPgetCutoffbound(scip));
393 assert(((solstatup != SCIP_LPSOLSTAT_INFEASIBLE) && (solstatup != SCIP_LPSOLSTAT_OBJLIMIT)) || upinf);
394
395 SCIPdebugMsg(scip, " down node objval: %g up node objval: %g\n", downobjval, upobjval);
396
397 if( !upinf )
398 {
399 /* when an optimal solution has been found calculate up child's estimate based on pseudo costs */
400 /* estimate = lowerbound + sum(min{f_j * pscdown_j, (1-f_j) * pscup_j}) */
401 estimateprobup = SCIPnodeGetLowerbound(node);
402 SCIP_CALL( SCIPgetLPBranchCands(scip, &upvars, &upvarssols, NULL, &nupvars, NULL, NULL) );
403
404 for( k = 0 ; k < nupvars; k++ )
405 {
406 SCIP_Real estimateincr;
407 SCIP_Real pscdown;
408 SCIP_Real pscup;
409
410 assert(upvars != NULL);
411 assert(upvars[k] != NULL);
412
413 pscdown = SCIPgetVarPseudocostVal(scip, upvars[k], SCIPfeasFloor(scip, upvarssols[k]) - upvarssols[k]);
414 pscup = SCIPgetVarPseudocostVal(scip, upvars[k], SCIPfeasCeil(scip, upvarssols[k]) - upvarssols[k]);
415 estimateincr = MIN(pscdown, pscup);
416 estimateprobup += estimateincr;
417 }
418 }
420
421 /* check whether the children nodes are solved to optimality and give a valid new lower bound or not */
422 if( downinf || upinf )
423 {
424 /* check if the LP is a valid relaxation and we can then collect new information */
425 if( allcolsinlp )
426 {
427 /* cut off the node either when both children are infeasible or the objective limit was reached;
428 * if only one child is feasible with LP value smaller than objective limit, add the corresponding
429 * constraint to the problem and break the branching rule in order to solve the updated LP
430 */
431 if( downinf && upinf )
432 {
433 SCIPdebugMsg(scip, "node can be cut off due to strong branching on multi-aggregated variable <%s>\n",
434 SCIPvarGetName(fixvars[i]));
435 SCIPstatistic(branchruledata->nmultaggrcutoff += 1);
436
438 break;
439 }
440 else
441 {
442 assert(!lperror);
443
444 if( downinf )
445 downnodeinf = TRUE;
446
447 SCIPdebugMsg(scip, "%s child of multi-aggregated variable <%s> is infeasible\n",
448 downinf ? "down" : "up", SCIPvarGetName(fixvars[i]) );
449 SCIPstatistic(branchruledata->nmultaggrconsadd += 1);
450
452 break;
453 }
454 }
455 }
456 else
457 {
458 /* if both children are solved to optimality and they both give a new valid bound, calculate the score of the
459 * multi-aggregated variable
460 */
461 SCIP_Real downgain;
462 SCIP_Real upgain;
463 SCIP_Real down;
464 SCIP_Real up;
465 SCIP_Real score;
466 SCIP_Real minbound;
467
468 assert(!downinf);
469 assert(!upinf);
470 assert(!lperror);
471
472 SCIPdebugMsg(scip, " both probing nodes are valid while branching on multi-aggregated variable: <%s>\n ", SCIPvarGetName(fixvars[i]));
473
474 down = MAX(downobjval, lpobjval);
475 up = MAX(upobjval, lpobjval);
476 downgain = down - lpobjval;
477 upgain = up - lpobjval;
478 score = SCIPgetBranchScore(scip, NULL, downgain, upgain);
479
480 if( allcolsinlp && !exactsolve )
481 {
482 /* the minimal lower bound of both children is a proved lower bound of the current subtree */
483 minbound = MIN(downobjval, upobjval);
484 *provedbound = MAX(*provedbound, minbound);
485 }
486
488 if( score > *bestmultaggrscore )
489 *bestmultaggrscore = score;
490 );
491
492 /* update the best branching candidate and all its values if a strictly greater score has been found */
493 if( score > *bestscore )
494 {
496 if( branchruledata->nmultaggrbranch == 0 )
497 {
498 branchruledata->rundepth = SCIPgetNRuns(scip);
499 branchruledata->firstmultaggrdepth = SCIPgetFocusDepth(scip);
500 }
501 )
502
503 SCIPdebugMsg(scip, " <%s> is a better candidate for branching\n", SCIPvarGetName(fixvars[i]));
504
505 *bestscore = MAX(score, *bestscore);
506 *bestcand = fixvars[i];
507 *bestsol = fixvarssol;
508 *bestdown = downobjval;
509 *bestup = upobjval;
510 *bestdownvalid = TRUE;
511 *bestupvalid = TRUE;
512 *estimatedown = estimateprobdown;
513 *estimateup = estimateprobup;
514 }
515 assert(bestscore != NULL);
516 assert(bestcand != NULL);
517 assert(bestup != NULL);
518 assert(bestdown != NULL);
519 }
520 }
521 }
522 }
523
524 /* end probing mode */
525 if( endprobing )
526 {
528 }
529
530 SCIPdebugMsg(scip, "\n");
531
532 /* one of the child nodes was infeasible, add the other constraint to the current node */
533 if( *result == SCIP_CONSADDED )
534 {
535 node = SCIPgetCurrentNode(scip);
536 if( downnodeinf )
537 {
538 SCIP_CALL( SCIPcreateConsLinear(scip, &probingconsup, "infconsup", SCIPvarGetMultaggrNVars(fixvars[i]),
540 SCIPfeasCeil(scip, fixvarssols[i]) - SCIPvarGetMultaggrConstant(fixvars[i]), SCIPinfinity(scip),
542 assert(probingconsup != NULL);
543 SCIP_CALL( SCIPaddConsNode(scip, node, probingconsup, NULL) );
544 SCIPdebugMsg(scip, " <%s> new valid constraint has been added to the original problem\n", SCIPconsGetName(probingconsup));
545 SCIP_CALL( SCIPreleaseCons(scip, &probingconsup) );
546 }
547 else
548 {
549 SCIP_CALL( SCIPcreateConsLinear(scip, &probingconsdown, "infconsdown", SCIPvarGetMultaggrNVars(fixvars[i]),
551 SCIPfeasFloor(scip, fixvarssols[i]) - SCIPvarGetMultaggrConstant(fixvars[i]), TRUE, TRUE, FALSE, FALSE,
552 TRUE, TRUE, FALSE, FALSE, FALSE, TRUE) );
553 assert(probingconsdown != NULL);
554 SCIP_CALL( SCIPaddConsNode(scip, node, probingconsdown, NULL) );
555 SCIPdebugMsg(scip, " <%s> new valid constraint has been added to the original problem\n", SCIPconsGetName(probingconsdown));
556 SCIP_CALL( SCIPreleaseCons(scip, &probingconsdown) );
557 }
558 }
559 SCIPfreeBufferArray(scip, &fixvarssols);
560 }
561 return SCIP_OKAY;
562}
563
564
565/*
566 * Callback methods of branching rule
567 */
568
569/** copy method for branchrule plugins (called when SCIP copies plugins) */
570static
571SCIP_DECL_BRANCHCOPY(branchCopyMultAggr)
572{ /*lint --e{715}*/
573 assert(scip != NULL);
574 assert(branchrule != NULL);
575
577
578 /* call inclusion method of branchrule */
580
581 return SCIP_OKAY;
582}
583
584/** destructor of branching rule to free user data (called when SCIP is exiting) */
585static
586SCIP_DECL_BRANCHFREE(branchFreeMultAggr)
587{ /*lint --e{715}*/
588 SCIP_BRANCHRULEDATA* branchruledata;
589
590 /* free branching rule data */
591 branchruledata = SCIPbranchruleGetData(branchrule);
592 assert(branchruledata != NULL);
593
594 SCIPstatistic(SCIPfreeBlockMemoryArrayNull(scip , &branchruledata->ratioggain, branchruledata->size));
595 SCIPfreeBlockMemoryArrayNull(scip, &branchruledata->skipdown, branchruledata->skipsize);
596 SCIPfreeBlockMemoryArrayNull(scip, &branchruledata->skipup, branchruledata->skipsize);
597
598 SCIPfreeBlockMemory(scip, &branchruledata);
599 SCIPbranchruleSetData(branchrule, NULL);
600
601 return SCIP_OKAY;
602}
603
604/** initialization method of branching rule (called after problem was transformed) */
605static
606SCIP_DECL_BRANCHINIT(branchInitMultAggr)
607{ /*lint --e{715}*/
608 SCIP_BRANCHRULEDATA* branchruledata;
609
610 branchruledata = SCIPbranchruleGetData(branchrule);
611 assert(branchruledata != NULL);
612
613 branchruledata->lastcand = 0;
615 branchruledata->firstmultaggrdepth = 0;
616 branchruledata->nmultaggrbranch = 0;
617 branchruledata->nfracbranch = 0;
618 branchruledata->nEscore = 0;
619 branchruledata->nmultaggrcutoff = 0;
620 branchruledata->nmultaggrconsadd = 0;
621 branchruledata->nfractcutoff = 0;
622 branchruledata->nfractconsadd = 0;
623 branchruledata->nrun = 0;
624 branchruledata->size = 100;
625 branchruledata->ameanratio = 0.0;
626 branchruledata->noupdate = FALSE;
627 branchruledata->clckstrongbr = NULL;
628 branchruledata->clckmultaggrbr = NULL;
629 branchruledata->nstrongbrcall = 0;
630 branchruledata->nmultaggrbrcall = 0;
631 branchruledata->totalmultaggrcands = 0;
632 branchruledata->totallpcands = 0;
633 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &branchruledata->ratioggain, branchruledata->size) );
634 BMSclearMemoryArray(branchruledata->ratioggain, branchruledata->size);
635 SCIP_CALL( SCIPcreateClock(scip, &branchruledata->clckstrongbr) );
636 SCIP_CALL( SCIPcreateClock(scip, &branchruledata->clckmultaggrbr) );
637 )
638 return SCIP_OKAY;
639}
640
641/** deinitialization method of branching rule (called before transformed problem is freed) */
642static
643SCIP_DECL_BRANCHEXIT(branchExitMultAggr)
644{ /*lint --e{715}*/
645 SCIP_BRANCHRULEDATA* branchruledata;
646
647 /* initialize branching rule data */
648 branchruledata = SCIPbranchruleGetData(branchrule);
649 assert(branchruledata != NULL);
650 assert((branchruledata->skipdown != NULL) == (branchruledata->skipup != NULL));
651
652 /* print statistics */
655 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "Multi-aggregated branching stats : \n");
656 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " nmultaggrvars : %d (last run)\n",
657 branchruledata->nmultaggrvars);
658 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " firstmultaggrbranchdepth : %d (in run %d)\n",
659 branchruledata->firstmultaggrdepth,
660 branchruledata->rundepth);
661 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " nmultaggrbranch : %d (tot %d)\n",
662 branchruledata->nmultaggrbranch, branchruledata->nmultaggrbranch + branchruledata->nfracbranch);
663 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " nmultaggrcutoff : %d\n", branchruledata->nmultaggrcutoff);
664 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " nmultaggrconsadd : %d\n", branchruledata->nmultaggrconsadd);
665 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " nfractcutoff : %d\n", branchruledata->nfractcutoff);
666 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " nfractconsadd : %d\n", branchruledata->nfractconsadd);
667 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " nEscore : %d\n", branchruledata->nEscore);
668
669 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " Branching Time : \n");
670 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " nstrongbrcall : %d\n", branchruledata->nstrongbrcall);
671 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " totalstrongbrtime : %g\n",
672 SCIPgetClockTime(scip, branchruledata->clckstrongbr));
673 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " totallpcands : %d\n", branchruledata->totallpcands);
674
675 if( branchruledata->totallpcands != 0 )
676 {
677 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " averagetimestrongbr : %g\n",
678 SCIPgetClockTime(scip, branchruledata->clckstrongbr) / branchruledata->totallpcands);
679 }
680 else
681 {
682 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " averagetimestrongbr : %s\n", "--");
683 }
684
685 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " nmultaggrbrcall : %d\n", branchruledata->nmultaggrbrcall);
686 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " totalmultaggrbrtime : %g\n",
687 SCIPgetClockTime(scip, branchruledata->clckmultaggrbr));
688 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " totalmultaggrcands : %d\n", branchruledata->totalmultaggrcands);
689
690 if( branchruledata->totalmultaggrcands != 0 )
691 {
692 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " averagetimemultaggrbr : %g\n",
693 SCIPgetClockTime(scip, branchruledata->clckmultaggrbr) / branchruledata->totalmultaggrcands);
694 }
695 else
696 {
697 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " averagetimemultaggrbr : %s\n", "--");
698 }
699
700 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " Ratioggain :\n");
701 if( branchruledata->nmultaggrbranch != 0 )
702 {
703 int j;
704 for( j = 0; j < branchruledata->nmultaggrbranch; j++ )
705 {
706 branchruledata->ameanratio += branchruledata->ratioggain[j];
707 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " %g", branchruledata->ratioggain[j]);
708 }
709
711 branchruledata->ameanratio = branchruledata->ameanratio / branchruledata->nmultaggrbranch;
713 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " ameanratio : %4.2f\n", branchruledata->ameanratio);
714 }
715 else
716 {
717 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " ameanratio : %s\n", "--");
718 }
719
721
722 /* free arrays */
723 SCIPfreeBlockMemoryArrayNull(scip, &branchruledata->ratioggain, branchruledata->size);
724 SCIP_CALL( SCIPfreeClock(scip, &branchruledata->clckstrongbr) );
725 SCIP_CALL( SCIPfreeClock(scip, &branchruledata->clckmultaggrbr) );
726 )
727 if( branchruledata->skipdown != NULL )
728 {
729 SCIPfreeBlockMemoryArray(scip, &branchruledata->skipup, branchruledata->skipsize);
730 SCIPfreeBlockMemoryArray(scip, &branchruledata->skipdown, branchruledata->skipsize);
731 branchruledata->skipdown = NULL;
732 branchruledata->skipup = NULL;
733 branchruledata->skipsize = 0;
734 }
735 return SCIP_OKAY;
736}
737
738/** branching execution method for fractional LP solutions */
739static
740SCIP_DECL_BRANCHEXECLP(branchExeclpMultAggr)
741{ /*lint --e{715}*/
742 SCIP_BRANCHRULEDATA* branchruledata;
744 SCIP_VAR** tmplpcands;
747 SCIP_Real* tmplpcandssol;
748 SCIP_Real* tmplpcandsfrac;
749 SCIP_NODE* downchild;
750 SCIP_NODE* upchild;
751 SCIP_Real bestup;
752 SCIP_Real bestdown;
753 SCIP_Real bestscore;
754 SCIP_Real provedbound;
755 SCIP_Real estimatedown = 0.0;
756 SCIP_Real estimateup = 0.0;
757 SCIP_Bool bestdownvalid;
758 SCIP_Bool bestupvalid;
759 SCIP_Longint oldreevalage;
760 int bestcandpos;
761 int nlpcands;
762 int npriolpcands;
764 SCIP_Real lpobjval;
766 )
767
768 assert(branchrule != NULL);
769 assert(scip != NULL);
770 assert(result != NULL);
771
773
774 SCIPdebugMsg(scip, "Execlp method of mult-aggreg branching\n ");
776
777 /* get branching rule data */
778 branchruledata = SCIPbranchruleGetData(branchrule);
779 assert(branchruledata != NULL);
780
781 SCIP_CALL( SCIPgetLongintParam(scip, "branching/fullstrong/reevalage", &oldreevalage) );
782 SCIP_CALL( SCIPsetLongintParam(scip, "branching/fullstrong/reevalage", branchruledata->reevalage) );
783
784 /* get the lpobjval and the number of multi aggregated variables of the problem as a statistic counter */
787 lpobjval = SCIPgetLPObjval(scip);
788
789 if( SCIPgetNRuns(scip) != branchruledata->nrun )
790 {
791 SCIP_VAR** fixvars;
792 int nfixvars;
793 int i;
794
795 branchruledata->nmultaggrvars = 0;
796 fixvars = SCIPgetFixedVars(scip);
797 nfixvars = SCIPgetNFixedVars(scip);
798
799 if( nfixvars != 0 )
800 {
801 for( i = 0; i < nfixvars; i++ )
802 {
804 {
805 branchruledata->nmultaggrvars += 1;
806 }
807 }
808 }
809 branchruledata->nrun = SCIPgetNRuns(scip);
810 }
811 )
812
813 /* get all branching candidates */
814 SCIP_CALL( SCIPgetLPBranchCands(scip, &tmplpcands, &tmplpcandssol, &tmplpcandsfrac, &nlpcands, &npriolpcands, NULL) );
815 assert(nlpcands > 0);
816 assert(npriolpcands > 0);
817
818 /* copy LP branching candidates and solution values, because they will be updated w.r.t. the strong branching LP
819 * solution
820 */
824
825 if( branchruledata->skipdown == NULL )
826 {
827 assert(branchruledata->skipup == NULL);
828
829 branchruledata->skipsize = SCIPgetNVars(scip);
830 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &branchruledata->skipdown, branchruledata->skipsize) );
831 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &branchruledata->skipup, branchruledata->skipsize) );
832 BMSclearMemoryArray(branchruledata->skipdown, branchruledata->skipsize);
833 BMSclearMemoryArray(branchruledata->skipup, branchruledata->skipsize);
834 }
835
836 /* start the clock to get the time spent inside the function */
838 SCIP_CALL( SCIPstartClock(scip, branchruledata->clckstrongbr) );
839 );
840
841 /* compute strong branching among the array of fractional variables in order to get the best one */
843 branchruledata->skipup, nlpcands, npriolpcands, nlpcands, &branchruledata->lastcand,
844 branchruledata->maxproprounds, branchruledata->probingbounds, TRUE,
845 &bestcandpos, &bestdown, &bestup, &bestscore, &bestdownvalid, &bestupvalid, &provedbound, result) );
846
848 SCIP_CALL( SCIPstopClock(scip, branchruledata->clckstrongbr) );
849 branchruledata->totallpcands += SCIPgetNLPBranchCands(scip);
850 branchruledata->nstrongbrcall += 1;
851 )
852
854 {
855 SCIP_VAR* bestcand = lpcands[bestcandpos];
856 SCIP_Real bestsol = lpcandssol[bestcandpos];
857 SCIPstatistic( SCIP_Real bestmultaggrscore = -SCIPinfinity(scip); )
858
860 SCIP_Real fdowngain = 0.0;
861 SCIP_Real fupgain = 0.0;
862
863 /* reoptimize is set to true if strong branching on fractional variables did not explicitly evaluate the objective
864 * values of the probing child nodes and thus we do not have updated information
865 */
866 if( SCIPisLT(scip, SCIPgetVarStrongbranchLPAge(scip, bestcand), branchruledata->reevalage)
867 || branchruledata->maxproprounds != 0 )
869
870 /* store values needed for the ratioggain statistic */
871 if( !reoptimize )
872 {
873 SCIP_Real fdown;
874 SCIP_Real fup;
875
876 fdown = MAX(bestdown, lpobjval);
877 fup = MAX(bestup, lpobjval);
878 fdowngain = fdown - lpobjval;
879 fupgain = fup - lpobjval;
880 }
881
882 /* start and then stop the clock to get the time spent inside the function */
883 SCIP_CALL( SCIPstartClock(scip, branchruledata->clckmultaggrbr) );
884 )
885
886 /* compute strong branching among the multi-aggregated variables and the best fractional variable */
887#ifdef SCIP_STATISTIC
888 SCIP_CALL( selectVarMultAggrBranching(scip, &bestcand, &bestscore, &bestsol, &bestdown, &bestup, &bestdownvalid, &bestupvalid, &provedbound,
889 &estimatedown, &estimateup, &bestmultaggrscore, result) );
890#else
891 SCIP_CALL( selectVarMultAggrBranching(scip, &bestcand, &bestscore, &bestsol, &bestdown, &bestup, &bestdownvalid, &bestupvalid, &provedbound,
892 &estimatedown, &estimateup, result) );
893#endif
895 SCIP_CALL( SCIPstopClock(scip, branchruledata->clckmultaggrbr) );
896 branchruledata->nmultaggrbrcall += 1;
897 )
898
899 if( *result != SCIP_CUTOFF && *result != SCIP_CONSADDED )
900 {
902 if( !(branchruledata->noupdate) )
903 {
904 if( SCIPisEQ(scip, bestmultaggrscore, bestscore) )
905 branchruledata->nEscore += 1;
906 }
907 )
908
909 assert(bestcand != NULL);
910 SCIPdebugMsg(scip, "BRANCHING MODE:\n");
911
912 /* perform branching on the best found candidate */
914 {
915 SCIP_CONS* multaggrconsdown;
916 SCIP_CONS* multaggrconsup;
917
919 if( !(branchruledata->noupdate) )
920 {
921 branchruledata->nmultaggrbranch += 1;
922
923 if( !reoptimize )
924 {
925 SCIP_Real gfractbranch;
926 SCIP_Real gmultaggrbranch;
927 SCIP_Real downgain;
928 SCIP_Real upgain;
929 SCIP_Real down;
930 SCIP_Real up;
931 int nmultaggrbranch;
932
933 down = MAX(bestdown, lpobjval);
934 up = MAX(bestup, lpobjval);
935 downgain = down - lpobjval;
936 upgain = up - lpobjval;
937
938 SCIP_CALL( ensureArraySize(scip, branchruledata) );
939
940 gfractbranch= sqrt(MAX(fdowngain,1e-06) * MAX(fupgain,1e-06));
941 gmultaggrbranch = sqrt(MAX(downgain,1e-06) * MAX(upgain,1e-06));
942
943 nmultaggrbranch = branchruledata->nmultaggrbranch;
944
945 if( gmultaggrbranch == 0.0 )
946 {
947 branchruledata->ratioggain[nmultaggrbranch - 1] = 1;
948 }
949 else
950 {
951 branchruledata->ratioggain[nmultaggrbranch - 1] = gfractbranch / gmultaggrbranch;
952 }
953 }
954 }
955 )
956
957 /* create the multi-aggregated constraints rounded up and down */
958 SCIP_CALL( SCIPcreateConsLinear(scip, &multaggrconsdown, "consdown", SCIPvarGetMultaggrNVars(bestcand),
962
967
968 /* create the child nodes */
969 SCIP_CALL( SCIPcreateChild(scip, &downchild, 1.0, estimatedown) );
970 SCIPdebugMsg(scip, " down node: lowerbound %f estimate %f\n", SCIPnodeGetLowerbound(downchild), SCIPnodeGetEstimate(downchild));
971
972 SCIP_CALL( SCIPcreateChild(scip, &upchild, 1.0, estimateup) );
973 SCIPdebugMsg(scip, " up node: lowerbound %f estimate %f\n", SCIPnodeGetLowerbound(upchild), SCIPnodeGetEstimate(upchild));
974
975 assert(downchild != NULL);
976 assert(upchild != NULL);
977
978 SCIP_CALL( SCIPaddConsNode(scip, downchild, multaggrconsdown, NULL) );
979 SCIP_CALL( SCIPaddConsNode(scip, upchild, multaggrconsup, NULL) );
980
981#ifdef PRINTNODECONS
982 SCIPdebugMsg(scip, "branching at node %lld\n", SCIPnodeGetNumber(SCIPgetCurrentNode(scip)));
983
984 SCIPdebugMsg(scip, "created child node %lld with constraint:\n", SCIPnodeGetNumber(downchild));
985 SCIP_CALL( SCIPprintCons(scip, multaggrconsdown, NULL) );
986 SCIPinfoMessage(scip, NULL, "\n");
987
988 SCIPdebugMsg(scip, "created child node %lld with constraint:\n", SCIPnodeGetNumber(upchild));
989 SCIP_CALL( SCIPprintCons(scip, multaggrconsup, NULL) );
990 SCIPinfoMessage(scip, NULL, "\n");
991#endif
992
993 /* relase constraints */
994 SCIP_CALL( SCIPreleaseCons(scip, &multaggrconsdown) );
995 SCIP_CALL( SCIPreleaseCons(scip, &multaggrconsup) );
996
997 SCIPdebugMsg(scip, "BRANCHED on multi-aggregated variable <%s>\n", SCIPvarGetName(bestcand));
998
1000 }
1001 else
1002 {
1004 if( !(branchruledata->noupdate) )
1005 branchruledata->nfracbranch += 1
1006 );
1007
1009 assert(SCIPisLT(scip, provedbound, SCIPgetCutoffbound(scip)));
1010
1011 SCIP_CALL( SCIPbranchVarVal(scip, bestcand, bestsol, &downchild, NULL, &upchild) );
1012
1013 assert(downchild != NULL);
1014 assert(upchild != NULL);
1015
1016 SCIPdebugMsg(scip, "BRANCHED on fractional variable <%s>\n", SCIPvarGetName(bestcand));
1017
1019 }
1020
1021 /* update the lower bounds in the children; we must not do this if columns are missing in the LP
1022 * (e.g., because we are doing branch-and-price) or the problem should be solved exactly
1023 */
1025 {
1026 SCIP_CALL( SCIPupdateNodeLowerbound(scip, downchild, bestdownvalid ? MAX(bestdown, provedbound) : provedbound) );
1027 SCIP_CALL( SCIPupdateNodeLowerbound(scip, upchild, bestupvalid ? MAX(bestup, provedbound) : provedbound) );
1028 }
1029 SCIPdebugMsg(scip, " -> down child's lowerbound: %g\n", SCIPnodeGetLowerbound(downchild));
1030 SCIPdebugMsg(scip, " -> up child's lowerbound: %g\n", SCIPnodeGetLowerbound(upchild));
1031 }
1032 }
1033 else
1034 {
1035 SCIPdebugMsg(scip, "strong branching breaks\n" );
1036
1038 if( *result == SCIP_CUTOFF )
1039 {
1040 branchruledata->nfractcutoff += 1;
1041 }
1042 else
1043 {
1044 branchruledata->nfractconsadd += 1;
1045 }
1046 )
1047 }
1048
1052
1053 SCIP_CALL( SCIPsetLongintParam(scip, "branching/fullstrong/reevalage", oldreevalage) );
1054
1055 return SCIP_OKAY;
1056}
1057
1058/*
1059 * branching rule specific interface methods
1060 */
1061
1062/** creates the multi-aggregated branching rule and includes it in SCIP */
1064 SCIP* scip /**< SCIP data structure */
1065 )
1066{
1067 SCIP_BRANCHRULEDATA* branchruledata;
1068 SCIP_BRANCHRULE* branchrule;
1069
1070 /* create multaggr branching rule data */
1071 SCIP_CALL( SCIPallocBlockMemory(scip, &branchruledata) );
1072 branchruledata->lastcand = 0;
1073 branchruledata->skipsize = 0;
1074 branchruledata->skipup = NULL;
1075 branchruledata->skipdown = NULL;
1076 SCIPstatistic(branchruledata->ratioggain = NULL);
1077
1078 /* include branching rule */
1080 BRANCHRULE_MAXDEPTH, BRANCHRULE_MAXBOUNDDIST, branchruledata) );
1081
1082 assert(branchrule != NULL);
1083
1084 /* set non fundamental callbacks via setter functions */
1085 SCIP_CALL( SCIPsetBranchruleCopy(scip, branchrule, branchCopyMultAggr) );
1086 SCIP_CALL( SCIPsetBranchruleFree(scip, branchrule, branchFreeMultAggr) );
1087 SCIP_CALL( SCIPsetBranchruleInit(scip, branchrule, branchInitMultAggr) );
1088 SCIP_CALL( SCIPsetBranchruleExit(scip, branchrule, branchExitMultAggr) );
1089 SCIP_CALL( SCIPsetBranchruleExecLp(scip, branchrule, branchExeclpMultAggr) );
1090
1091 /* multi-aggregated branching rule parameters */
1093 "branching/multaggr/reevalage",
1094 "number of intermediate LPs solved to trigger reevaluation of strong branching value for a variable that was already evaluated at the current node",
1095 &branchruledata->reevalage, TRUE, DEFAULT_REEVALAGE, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1097 "branching/multaggr/maxproprounds",
1098 "maximum number of propagation rounds to be performed during multaggr branching before solving the LP (-1: no limit, -2: parameter settings)",
1099 &branchruledata->maxproprounds, TRUE, DEFAULT_MAXPROPROUNDS, -2, INT_MAX, NULL, NULL) );
1101 "branching/multaggr/probingbounds",
1102 "should valid bounds be identified in a probing-like fashion during multaggr branching (only with propagation)?",
1103 &branchruledata->probingbounds, TRUE, DEFAULT_PROBINGBOUNDS, NULL, NULL) );
1104
1105 return SCIP_OKAY;
1106}
#define BRANCHRULE_DESC
#define BRANCHRULE_PRIORITY
#define BRANCHRULE_NAME
#define BRANCHRULE_MAXDEPTH
#define BRANCHRULE_MAXBOUNDDIST
#define DEFAULT_PROBINGBOUNDS
#define DEFAULT_REEVALAGE
#define DEFAULT_MAXPROPROUNDS
full strong LP branching rule
static SCIP_RETCODE selectVarMultAggrBranching(SCIP *scip, SCIP_VAR **bestcand, SCIP_Real *bestscore, SCIP_Real *bestsol, SCIP_Real *bestdown, SCIP_Real *bestup, SCIP_Bool *bestdownvalid, SCIP_Bool *bestupvalid, SCIP_Real *provedbound, SCIP_Real *estimatedown, SCIP_Real *estimateup, SCIP_RESULT *result)
fullstrong branching on fractional and multi-aggregated variables
Constraint handler for linear constraints in their most general form, .
#define NULL
Definition def.h:257
#define SCIP_Longint
Definition def.h:150
#define SCIP_MAXTREEDEPTH
Definition def.h:306
#define SCIP_Bool
Definition def.h:100
#define MIN(x, y)
Definition def.h:233
#define SCIP_STRINGEQ(name, reference, retcode)
Definition def.h:454
#define SCIP_Real
Definition def.h:165
#define TRUE
Definition def.h:102
#define FALSE
Definition def.h:103
#define MAX(x, y)
Definition def.h:229
#define SCIP_LONGINT_MAX
Definition def.h:151
#define SCIP_CALL(x)
Definition def.h:364
SCIP_RETCODE SCIPselectVarStrongBranching(SCIP *scip, SCIP_VAR **lpcands, SCIP_Real *lpcandssol, SCIP_Real *lpcandsfrac, SCIP_Bool *skipdown, SCIP_Bool *skipup, int nlpcands, int npriolpcands, int ncomplete, int *start, int maxproprounds, SCIP_Bool probingbounds, SCIP_Bool forcestrongbranch, int *bestcand, SCIP_Real *bestdown, SCIP_Real *bestup, SCIP_Real *bestscore, SCIP_Bool *bestdownvalid, SCIP_Bool *bestupvalid, SCIP_Real *provedbound, SCIP_RESULT *result)
SCIP_RETCODE SCIPincludeBranchruleMultAggr(SCIP *scip)
SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
int SCIPgetNVars(SCIP *scip)
Definition scip_prob.c:2246
int SCIPgetNFixedVars(SCIP *scip)
Definition scip_prob.c:2705
SCIP_VAR ** SCIPgetFixedVars(SCIP *scip)
Definition scip_prob.c:2662
SCIP_RETCODE SCIPupdateNodeLowerbound(SCIP *scip, SCIP_NODE *node, SCIP_Real newbound)
Definition scip_prob.c:4354
SCIP_RETCODE SCIPaddConsNode(SCIP *scip, SCIP_NODE *node, SCIP_CONS *cons, SCIP_NODE *validnode)
Definition scip_prob.c:3901
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
#define SCIPdebugMsg
SCIP_RETCODE SCIPaddLongintParam(SCIP *scip, const char *name, const char *desc, SCIP_Longint *valueptr, SCIP_Bool isadvanced, SCIP_Longint defaultvalue, SCIP_Longint minvalue, SCIP_Longint maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:111
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:83
SCIP_RETCODE SCIPsetLongintParam(SCIP *scip, const char *name, SCIP_Longint value)
Definition scip_param.c:545
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_param.c:57
SCIP_RETCODE SCIPgetLongintParam(SCIP *scip, const char *name, SCIP_Longint *value)
Definition scip_param.c:288
SCIP_RETCODE SCIPsetBranchruleInit(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
SCIP_RETCODE SCIPsetBranchruleExit(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
SCIP_RETCODE SCIPincludeBranchruleBasic(SCIP *scip, SCIP_BRANCHRULE **branchruleptr, const char *name, const char *desc, int priority, int maxdepth, SCIP_Real maxbounddist, SCIP_BRANCHRULEDATA *branchruledata)
const char * SCIPbranchruleGetName(SCIP_BRANCHRULE *branchrule)
Definition branch.c:2018
SCIP_BRANCHRULEDATA * SCIPbranchruleGetData(SCIP_BRANCHRULE *branchrule)
Definition branch.c:1886
SCIP_RETCODE SCIPsetBranchruleCopy(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
SCIP_RETCODE SCIPsetBranchruleExecLp(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
void SCIPbranchruleSetData(SCIP_BRANCHRULE *branchrule, SCIP_BRANCHRULEDATA *branchruledata)
Definition branch.c:1896
SCIP_RETCODE SCIPsetBranchruleFree(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
SCIP_RETCODE SCIPbranchVarVal(SCIP *scip, SCIP_VAR *var, SCIP_Real val, SCIP_NODE **downchild, SCIP_NODE **eqchild, SCIP_NODE **upchild)
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
int SCIPgetNLPBranchCands(SCIP *scip)
SCIP_RETCODE SCIPcreateChild(SCIP *scip, SCIP_NODE **node, SCIP_Real nodeselprio, SCIP_Real estimate)
SCIP_Real SCIPgetBranchScore(SCIP *scip, SCIP_VAR *var, SCIP_Real downgain, SCIP_Real upgain)
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition scip_cons.c:2536
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition cons.c:8393
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition scip_cons.c:1173
SCIP_Bool SCIPisExact(SCIP *scip)
Definition scip_exact.c:193
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition scip_lp.c:174
SCIP_Bool SCIPallColsInLP(SCIP *scip)
Definition scip_lp.c:655
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition scip_lp.c:253
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition scip_mem.h:110
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition scip_mem.c:139
#define SCIPallocBufferArray(scip, ptr, num)
Definition scip_mem.h:124
#define SCIPfreeBufferArray(scip, ptr)
Definition scip_mem.h:136
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition scip_mem.h:132
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition scip_mem.h:93
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition scip_mem.h:99
#define SCIPfreeBlockMemory(scip, ptr)
Definition scip_mem.h:108
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition scip_mem.h:111
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
SCIP_Real SCIPnodeGetLowerbound(SCIP_NODE *node)
Definition tree.c:8533
SCIP_Longint SCIPnodeGetNumber(SCIP_NODE *node)
Definition tree.c:8513
SCIP_Real SCIPnodeGetEstimate(SCIP_NODE *node)
Definition tree.c:8553
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
SCIP_RETCODE SCIPstartProbing(SCIP *scip)
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
int SCIPgetNRuns(SCIP *scip)
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
SCIP_RETCODE SCIPcreateClock(SCIP *scip, SCIP_CLOCK **clck)
Definition scip_timing.c:76
SCIP_RETCODE SCIPstopClock(SCIP *scip, SCIP_CLOCK *clck)
SCIP_RETCODE SCIPfreeClock(SCIP *scip, SCIP_CLOCK **clck)
SCIP_Real SCIPgetClockTime(SCIP *scip, SCIP_CLOCK *clck)
SCIP_RETCODE SCIPstartClock(SCIP *scip, SCIP_CLOCK *clck)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
int SCIPgetDepth(SCIP *scip)
Definition scip_tree.c:672
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition scip_tree.c:91
SCIP_Real SCIPvarGetMultaggrConstant(SCIP_VAR *var)
Definition var.c:23875
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition var.c:23418
SCIP_Bool SCIPvarIsNonimpliedIntegral(SCIP_VAR *var)
Definition var.c:23538
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:23299
SCIP_Longint SCIPgetVarStrongbranchLPAge(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:5053
SCIP_Real SCIPgetVarPseudocostVal(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
Definition scip_var.c:11188
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition var.c:24696
SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
Definition var.c:23838
int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
Definition var.c:23826
SCIP_Real * SCIPvarGetMultaggrScalars(SCIP_VAR *var)
Definition var.c:23850
return SCIP_OKAY
static SCIP_RETCODE reoptimize(SCIP *scip, SCIP_HEUR *heur, SCIP_SOL *sol, BLOCKPROBLEM **blockproblem, int nblocks, SCIP_Bool limits, SCIP_SOL **newsol, SCIP_Bool *success)
Definition heur_dps.c:1514
SCIP_Bool lperror
SCIPendProbing(scip))
SCIP_Real * lpcandssol
int nlpcands
SCIP_VAR ** lpcands
assert(minobj< SCIPgetCutoffbound(scip))
int bestcand
SCIP_Real * lpcandsfrac
memory allocation routines
#define BMSclearMemoryArray(ptr, num)
Definition memory.h:130
public methods for branching rules
public methods for managing constraints
public methods for message output
#define SCIPstatistic(x)
public methods for branch and bound tree
public methods for problem variables
public methods for branching rule plugins and branching
public methods for constraint handler plugins and constraints
public methods for exact solving
general public methods
public methods for the LP relaxation, rows and columns
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for global and local (sub)problems
public methods for the probing mode
public methods for querying solving statistics
public methods for timing
public methods for the branch-and-bound tree
public methods for SCIP variables
#define SCIP_DECL_BRANCHEXECLP(x)
#define SCIP_DECL_BRANCHINIT(x)
Definition type_branch.h:83
#define SCIP_DECL_BRANCHCOPY(x)
Definition type_branch.h:67
#define SCIP_DECL_BRANCHEXIT(x)
Definition type_branch.h:91
#define SCIP_DECL_BRANCHFREE(x)
Definition type_branch.h:75
struct SCIP_Branchrule SCIP_BRANCHRULE
Definition type_branch.h:56
struct SCIP_BranchruleData SCIP_BRANCHRULEDATA
Definition type_branch.h:57
struct SCIP_Clock SCIP_CLOCK
Definition type_clock.h:49
struct SCIP_Cons SCIP_CONS
Definition type_cons.h:63
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition type_lp.h:52
@ SCIP_LPSOLSTAT_NOTSOLVED
Definition type_lp.h:43
@ SCIP_LPSOLSTAT_TIMELIMIT
Definition type_lp.h:49
@ SCIP_LPSOLSTAT_UNBOUNDEDRAY
Definition type_lp.h:46
@ SCIP_LPSOLSTAT_INFEASIBLE
Definition type_lp.h:45
@ SCIP_LPSOLSTAT_OBJLIMIT
Definition type_lp.h:47
@ SCIP_LPSOLSTAT_ITERLIMIT
Definition type_lp.h:48
@ SCIP_VERBLEVEL_NORMAL
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ SCIP_CUTOFF
Definition type_result.h:48
@ SCIP_REDUCEDDOM
Definition type_result.h:51
@ SCIP_CONSADDED
Definition type_result.h:52
@ SCIP_BRANCHED
Definition type_result.h:54
enum SCIP_Result SCIP_RESULT
Definition type_result.h:61
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
struct SCIP_Node SCIP_NODE
Definition type_tree.h:63
struct SCIP_Var SCIP_VAR
Definition type_var.h:166
@ SCIP_VARSTATUS_MULTAGGR
Definition type_var.h:56