SCIP Doxygen Documentation
Loading...
Searching...
No Matches
history.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2026 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file history.c
26 * @ingroup OTHER_CFILES
27 * @brief methods for branching and inference history
28 * @author Tobias Achterberg
29 */
30
31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
32
33#include <assert.h>
34
35#include "scip/def.h"
36#include "scip/set.h"
37#include "scip/history.h"
38#include "scip/pub_misc.h"
39#include "scip/pub_history.h"
40#include "scip/pub_message.h"
41
42#ifndef NDEBUG
43#include "scip/struct_history.h"
44#endif
45
46/*
47 * methods for branching and inference history
48 */
49
50/** creates an empty history entry */
52 SCIP_HISTORY** history, /**< pointer to store branching and inference history */
53 BMS_BLKMEM* blkmem /**< block memory */
54 )
55{
56 assert(history != NULL);
57
58 SCIP_ALLOC( BMSallocBlockMemory(blkmem, history) );
59
60 SCIPhistoryReset(*history);
61
62 return SCIP_OKAY;
63}
64
65/** frees a history entry */
67 SCIP_HISTORY** history, /**< pointer to branching and inference history */
68 BMS_BLKMEM* blkmem /**< block memory */
69 )
70{
71 assert(history != NULL);
72 assert(*history != NULL);
73
74 BMSfreeBlockMemory(blkmem, history);
75}
76
77/** resets history entry to zero */
79 SCIP_HISTORY* history /**< branching and inference history */
80 )
81{
82 assert(history != NULL);
83
84 history->pscostcount[0] = 0.0;
85 history->pscostcount[1] = 0.0;
86 history->pscostweightedmean[0] = 0.0;
87 history->pscostweightedmean[1] = 0.0;
88 history->pscostvariance[0] = 0.0;
89 history->pscostvariance[1] = 0.0;
90 history->ancpscostcount[0] = 0.0;
91 history->ancpscostcount[1] = 0.0;
92 history->ancpscostweightedmean[0] = 0.0;
93 history->ancpscostweightedmean[1] = 0.0;
94 history->vsids[0] = 0.0;
95 history->vsids[1] = 0.0;
96 history->conflengthsum[0] = 0.0;
97 history->conflengthsum[1] = 0.0;
98 history->inferencesum[0] = 0.0;
99 history->inferencesum[1] = 0.0;
100 history->cutoffsum[0] = 0.0;
101 history->cutoffsum[1] = 0.0;
102 history->ratio = 0.0;
103 history->ratiovalid = FALSE;
104 history->balance = 0.0;
105 history->ngmi = 0;
106 history->gmieff = 0.0;
107 history->gmieffsum = 0.0;
108 history->nactiveconflicts[0] = 0;
109 history->nactiveconflicts[1] = 0;
110 history->nbranchings[0] = 0;
111 history->nbranchings[1] = 0;
112 history->branchdepthsum[0] = 0;
113 history->branchdepthsum[1] = 0;
114}
115
116/** unites two history entries by adding the values of the second one to the first one */
118 SCIP_HISTORY* history, /**< branching and inference history */
119 SCIP_HISTORY* addhistory, /**< history values to add to history */
120 SCIP_Bool switcheddirs /**< should the history entries be united with switched directories */
121 )
122{
123 int i;
124
125 assert(history != NULL);
126 assert(addhistory != NULL);
127
128 /* loop over both directions and combine the statistics */
129 for( i = 0; i <= 1; ++i )
130 {
131 int d;
132 d = (switcheddirs ? 1 - i : i);
133
134 history->pscostcount[i] += addhistory->pscostcount[d];
135 history->ancpscostcount[i] += addhistory->ancpscostcount[d];
136
137 /* if both histories a count of zero, there is nothing to do */
138 if( history->pscostcount[i] > 0.0 )
139 {
140 SCIP_Real oldmean;
141
142 oldmean = history->pscostweightedmean[i];
143
144 /* we update the mean as if the history was one observation with a large weight */
145 history->pscostweightedmean[i] += addhistory->pscostcount[d] * (addhistory->pscostweightedmean[d] - history->pscostweightedmean[i]) / history->pscostcount[i];
146
147 /* we update the variance of two sets A and B as S_A+B = S_A + (mu_A)^2 * count_A ...*/
148 /* @todo is there a numerically more stable variant for this merge? */
149 history->pscostvariance[i] = history->pscostvariance[i] + oldmean * oldmean * (history->pscostcount[i] - addhistory->pscostcount[d]) + \
150 /* S_B + (mu_B)^2 * count_B */
151 addhistory->pscostvariance[d] + addhistory->pscostcount[d] * addhistory->pscostweightedmean[d] * addhistory->pscostweightedmean[d] - \
152 /* - count_A+B * mu_A+B^ 2 */
153 history->pscostcount[i] * history->pscostweightedmean[i] * history->pscostweightedmean[i];
154
155 /* slight violations of nonnegativity are numerically possible */
156 history->pscostvariance[i] = MAX(history->pscostvariance[i], 0.0);
157 }
158#ifndef NDEBUG
159 else
160 {
161 assert(history->pscostweightedmean[i] == 0.0);
162 assert(history->pscostvariance[i] == 0.0);
163 }
164#endif
165 /* if both histories a discounted count of zero, there is nothing to do */
166 if( history->ancpscostcount[i] > 0.0 )
167 {
168 /* we update the mean as if the history was one observation with a large weight */
169 history->ancpscostweightedmean[i] += addhistory->ancpscostcount[d] * (addhistory->ancpscostweightedmean[d] - history->ancpscostweightedmean[i]) / history->ancpscostcount[i];
170 }
171#ifndef NDEBUG
172 else
173 {
174 assert(history->ancpscostweightedmean[i] == 0.0);
175 }
176#endif
177
178 history->vsids[i] += addhistory->vsids[d];
179 history->conflengthsum[i] += addhistory->conflengthsum[d];
180 history->inferencesum[i] += addhistory->inferencesum[d];
181 history->cutoffsum[i] += addhistory->cutoffsum[d];
182 history->nactiveconflicts[i] += addhistory->nactiveconflicts[d];
183 history->nbranchings[i] += addhistory->nbranchings[d];
184 history->branchdepthsum[i] += addhistory->branchdepthsum[d];
185 }
186}
187
188/** updates the pseudo costs for a change of "solvaldelta" in the variable's LP solution value and a change of "objdelta"
189 * in the LP's objective value
190 */
192 SCIP_HISTORY* history, /**< branching and inference history */
193 SCIP_SET* set, /**< global SCIP settings */
194 SCIP_Real solvaldelta, /**< difference of variable's new LP value - old LP value */
195 SCIP_Real objdelta, /**< difference of new LP's objective value - old LP's objective value */
196 SCIP_Real weight /**< weight of this update in pseudo cost sum (added to pscostcount) */
197 )
198{
199 SCIP_Real distance;
201 SCIP_Real sumcontribution;
202 SCIP_Real olddelta;
203 int dir;
204
205 assert(history != NULL);
206 assert(set != NULL);
207 assert(!SCIPsetIsInfinity(set, REALABS(solvaldelta)));
208 assert(!SCIPsetIsInfinity(set, objdelta));
209 assert(!SCIPsetIsNegative(set, objdelta));
210 assert(0.0 < weight && weight <= 1.0);
211
212 if( SCIPsetIsPositive(set, solvaldelta) )
213 {
214 /* variable's solution value moved upwards */
215 dir = 1;
216 distance = solvaldelta;
217 }
218 else if( SCIPsetIsNegative(set, solvaldelta) )
219 {
220 /* variable's solution value moved downwards */
221 dir = 0;
222 distance = -solvaldelta;
223 }
224 else
225 {
226 /* the variable's solution value didn't change, and the pseudo costs cannot be updated */
227 return;
228 }
229 assert(dir == 0 || dir == 1);
230 assert(SCIPsetIsPositive(set, distance));
231
232 /* apply a lower limit on the distance to avoid numerical instabilities due to very large summands */
234 distance = MAX(distance, eps);
235
236 /* slightly increase objective delta, s.t. pseudo cost values are not zero, and fractionalities are
237 * always used at least a bit
238 */
239 objdelta += SCIPsetPseudocostdelta(set);
240
241 sumcontribution = objdelta/distance;
242 /* update the pseudo cost values */
243 olddelta = sumcontribution - history->pscostweightedmean[dir];
244 history->pscostcount[dir] += weight;
245 history->pscostweightedmean[dir] += weight * olddelta / history->pscostcount[dir];
246 history->pscostvariance[dir] = history->pscostvariance[dir] + weight * olddelta * (sumcontribution - history->pscostweightedmean[dir]);
247
248 SCIPsetDebugMsg(set, "updated pseudo costs of history %p: dir=%d, distance=%g, objdelta=%g, weight=%g -> %g/%g\n",
249 (void*)history, dir, distance, objdelta, weight, history->pscostcount[dir], history->pscostweightedmean[dir]);
250}
251
252/** updates the ancestral pseudo costs for a change of "solvaldelta" in the variable's LP solution value and a change of "objdelta"
253 * in the LP's objective value
254 */
256 SCIP_HISTORY* history, /**< branching and inference history */
257 SCIP_SET* set, /**< global SCIP settings */
258 SCIP_Real solvaldelta, /**< difference of variable's new LP value - old LP value */
259 SCIP_Real objdelta, /**< difference of new LP's objective value - old LP's objective value */
260 SCIP_Real weight /**< weight of this update in discounted pseudo cost sum (added to pscostcount) */
261 )
262{
263 SCIP_Real distance;
265 SCIP_Real sumcontribution;
266 SCIP_Real olddelta;
267 int dir;
268
269 assert(history != NULL);
270 assert(set != NULL);
271 assert(!SCIPsetIsInfinity(set, REALABS(solvaldelta)));
272 assert(!SCIPsetIsInfinity(set, objdelta));
273 assert(!SCIPsetIsNegative(set, objdelta));
274 assert(0.0 < weight && weight <= 1.0);
275
276 if( SCIPsetIsPositive(set, solvaldelta) )
277 {
278 /* variable's solution value moved upwards */
279 dir = 1;
280 distance = solvaldelta;
281 }
282 else if( SCIPsetIsNegative(set, solvaldelta) )
283 {
284 /* variable's solution value moved downwards */
285 dir = 0;
286 distance = -solvaldelta;
287 }
288 else
289 {
290 /* the variable's solution value didn't change, and the pseudo costs cannot be updated */
291 return;
292 }
293 assert(dir == 0 || dir == 1);
294 assert(SCIPsetIsPositive(set, distance));
295
296 /* apply a lower limit on the distance to avoid numerical instabilities due to very large summands */
298 distance = MAX(distance, eps);
299
300 /* slightly increase objective delta, s.t. discounted pseudo cost values are not zero, and fractionalities are
301 * always used at least a bit
302 */
303 objdelta += SCIPsetPseudocostdelta(set);
304
305 sumcontribution = objdelta/distance;
306 /* update the pseudo cost values */
307 olddelta = sumcontribution - history->ancpscostweightedmean[dir];
308 history->ancpscostcount[dir] += weight;
309 history->ancpscostweightedmean[dir] += weight * olddelta / history->ancpscostcount[dir];
310
311 SCIPsetDebugMsg(set, "updated ancestor pseudo costs of history %p: dir=%d, distance=%g, objdelta=%g, weight=%g -> %g/%g\n",
312 (void*)history, dir, distance, objdelta, weight, history->ancpscostcount[dir], history->ancpscostweightedmean[dir]);
313}
314
315/**@name Value based history
316 *
317 * Value based history methods
318 *
319 * @{
320 */
321
322/** creates an empty value history */
324 SCIP_VALUEHISTORY** valuehistory, /**< pointer to store the value based branching and inference histories */
325 BMS_BLKMEM* blkmem /**< block memory */
326 )
327{
328 assert(valuehistory != NULL);
329
330 SCIP_ALLOC( BMSallocBlockMemory(blkmem, valuehistory) );
331
332 (*valuehistory)->nvalues = 0;
333 (*valuehistory)->sizevalues = 5;
334
335 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*valuehistory)->histories, (*valuehistory)->sizevalues) );
336 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*valuehistory)->values, (*valuehistory)->sizevalues) );
337
338 return SCIP_OKAY;
339}
340
341/** frees a value history */
343 SCIP_VALUEHISTORY** valuehistory, /**< pointer to value based history */
344 BMS_BLKMEM* blkmem /**< block memory */
345 )
346{
347 assert(valuehistory != NULL);
348
349 if( *valuehistory != NULL )
350 {
351 int i;
352
353 for( i = (*valuehistory)->nvalues-1; i >= 0; --i )
354 SCIPhistoryFree(&(*valuehistory)->histories[i], blkmem);
355
356 BMSfreeBlockMemoryArray(blkmem, &(*valuehistory)->histories, (*valuehistory)->sizevalues);
357 BMSfreeBlockMemoryArray(blkmem, &(*valuehistory)->values, (*valuehistory)->sizevalues);
358
359 BMSfreeBlockMemory(blkmem, valuehistory);
360 }
361}
362
363/** finds for the given domain value the history if it does not exist yet it will be created */
365 SCIP_VALUEHISTORY* valuehistory, /**< value based history */
366 BMS_BLKMEM* blkmem, /**< block memory */
367 SCIP_SET* set, /**< global SCIP settings */
368 SCIP_Real value, /**< domain value of interest */
369 SCIP_HISTORY** history /**< pointer to store the history for the given domain value */
370 )
371{
372 int pos;
373
374 assert(valuehistory != NULL);
375 assert(blkmem != NULL);
376 assert(set != NULL);
377 assert(history != NULL);
378
379 *history = NULL;
380
381 if( valuehistory->nvalues == 0 || !SCIPsortedvecFindReal(valuehistory->values, value, valuehistory->nvalues, &pos) )
382 {
383 /* check if we need to resize the history array */
384 if( valuehistory->nvalues == valuehistory->sizevalues )
385 {
386 int newsize;
387
388 newsize = SCIPsetCalcMemGrowSize(set, valuehistory->sizevalues + 1);
389 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &valuehistory->histories, valuehistory->nvalues, newsize) );
390 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &valuehistory->values, valuehistory->nvalues, newsize) );
391 valuehistory->sizevalues = newsize;
392 }
393
394 /* create new empty history entry */
395 SCIP_CALL( SCIPhistoryCreate(history, blkmem) );
396
397 /* insert new history into the value based history array */
398 SCIPsortedvecInsertRealPtr(valuehistory->values, (void**)valuehistory->histories, value, (void*)(*history), &valuehistory->nvalues, NULL);
399 }
400 else
401 (*history) = valuehistory->histories[pos]; /*lint !e530*/
402
403 assert(*history != NULL);
404
405 return SCIP_OKAY;
406}
407
408/** scales the conflict score values with the given scalar for each value history entry */
410 SCIP_VALUEHISTORY* valuehistory, /**< value based history */
411 SCIP_Real scalar /**< scalar to multiply the conflict scores with */
412 )
413{
414 if( valuehistory != NULL )
415 {
416 int i;
417
418 for( i = valuehistory->nvalues-1; i >= 0; --i )
419 {
420 SCIPhistoryScaleVSIDS(valuehistory->histories[i], scalar);
421 }
422 }
423}
424
425
426/*
427 * simple functions implemented as defines
428 */
429
430#ifdef NDEBUG
431
432/* In debug mode, the following methods are implemented as function calls to ensure
433 * type validity.
434 * In optimized mode, the methods are implemented as defines to improve performance.
435 * However, we want to have them in the library anyways, so we have to undef the defines.
436 */
437
438#undef SCIPvaluehistoryGetNValues
439#undef SCIPvaluehistoryGetHistories
440#undef SCIPvaluehistoryGetValues
441
442#endif
443
444/** return the number of (domain) values for which a history exists */
446 SCIP_VALUEHISTORY* valuehistory /**< value based history */
447 )
448{
449 assert(valuehistory != NULL);
450
451 return valuehistory->nvalues;
452}
453
454/** return the array containing the histories for the individual (domain) values */
456 SCIP_VALUEHISTORY* valuehistory /**< value based history */
457 )
458{
459 assert(valuehistory != NULL);
460
461 return valuehistory->histories;
462}
463
464/** return the array containing the (domain) values for which a history exists */
466 SCIP_VALUEHISTORY* valuehistory /**< value based history */
467 )
468{
469 assert(valuehistory != NULL);
470
471 return valuehistory->values;
472}
473
474/**@} */
475
476/*
477 * simple functions implemented as defines
478 */
479
480#ifdef NDEBUG
481
482/* In debug mode, the following methods are implemented as function calls to ensure
483 * type validity.
484 * In optimized mode, the methods are implemented as defines to improve performance.
485 * However, we want to have them in the library anyways, so we have to undef the defines.
486 */
487
488#undef SCIPbranchdirOpposite
489#undef SCIPhistoryGetPseudocost
490#undef SCIPhistoryGetPseudocostCount
491#undef SCIPhistoryIsPseudocostEmpty
492#undef SCIPhistoryGetAncPseudocost
493#undef SCIPhistoryGetAncPseudocostCount
494#undef SCIPhistoryIsAncPseudocostEmpty
495#undef SCIPhistoryIncVSIDS
496#undef SCIPhistoryScaleVSIDS
497#undef SCIPhistoryGetVSIDS
498#undef SCIPhistoryIncNActiveConflicts
499#undef SCIPhistoryGetNActiveConflicts
500#undef SCIPhistoryGetAvgConflictlength
501#undef SCIPhistoryIncNBranchings
502#undef SCIPhistoryIncInferenceSum
503#undef SCIPhistoryIncCutoffSum
504#undef SCIPhistoryGetNBranchings
505#undef SCIPhistoryGetInferenceSum
506#undef SCIPhistoryGetAvgInferences
507#undef SCIPhistoryGetCutoffSum
508#undef SCIPhistoryGetAvgCutoffs
509#undef SCIPhistoryGetAvgBranchdepth
510#undef SCIPhistoryIsRatioValid
511#undef SCIPhistoryGetLastRatio
512#undef SCIPhistorySetRatioHistory
513#undef SCIPhistoryGetLastBalance
514#undef SCIPhistorySetLastGMIeff
515#undef SCIPhistoryGetLastGMIeff
516#undef SCIPhistoryIncGMIeffSum
517#undef SCIPhistoryGetAvgGMIeff
518#undef SCIPhistoryGetPseudocostVariance
519
520#endif
521
522/** returns the opposite direction of the given branching direction */
530
531/** returns the expected dual gain for moving the corresponding variable by "solvaldelta" */
533 SCIP_HISTORY* history, /**< branching and inference history */
534 SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
535 )
536{
537 assert(history != NULL);
538
539 if( solvaldelta >= 0.0 )
540 return solvaldelta * (history->pscostcount[1] > 0.0 ? history->pscostweightedmean[1] : 1.0);
541 else
542 return -solvaldelta * (history->pscostcount[0] > 0.0 ? history->pscostweightedmean[0] : 1.0);
543}
544
545/** returns the expected ancestral dual gain for moving the corresponding variable by "solvaldelta" */
547 SCIP_HISTORY* history, /**< branching and inference history */
548 SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */
549 )
550{
551 assert(history != NULL);
552
553 if( solvaldelta >= 0.0 )
554 return solvaldelta * (history->ancpscostcount[1] > 0.0 ? history->ancpscostweightedmean[1] : 1.0);
555 else
556 return -solvaldelta * (history->ancpscostcount[0] > 0.0 ? history->ancpscostweightedmean[0] : 1.0);
557}
558
559/** returns the variance of pseudo costs about the mean. */
561 SCIP_HISTORY* history, /**< branching and inference history */
562 SCIP_BRANCHDIR direction /**< direction of variable: 1 for upwards history, 0 for downwards history */
563 )
564{
565 int dir;
566 SCIP_Real correctionfactor;
567
568 assert(history != NULL);
569 assert(direction == SCIP_BRANCHDIR_UPWARDS || direction == SCIP_BRANCHDIR_DOWNWARDS);
570
571 dir = (direction == SCIP_BRANCHDIR_UPWARDS ? 1 : 0);
572 correctionfactor = history->pscostcount[dir] - 1.0;
573
574 /** @todo for an unbiased estimate of the weighted sample variance, we need a correction factor that uses the sum of squared weights */
575 if( correctionfactor > 0.9 )
576 return history->pscostvariance[dir] / correctionfactor;
577 else
578 return 0.0;
579}
580
581/** returns the (possible fractional) number of (partial) pseudo cost updates performed on this pseudo cost entry in
582 * the given branching direction
583 */
585 SCIP_HISTORY* history, /**< branching and inference history */
586 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
587 )
588{
589 assert(history != NULL);
591 assert((int)dir == 0 || (int)dir == 1);
592
593 return history->pscostcount[dir];
594}
595
596/** returns the (possible fractional) number of (partial) ancestral pseudo cost updates performed on this pseudo cost entry in
597 * the given branching direction
598 */
600 SCIP_HISTORY* history, /**< branching and inference history */
601 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
602 )
603{
604 assert(history != NULL);
606 assert((int)dir == 0 || (int)dir == 1);
607
608 return history->ancpscostcount[dir];
609}
610
611/** returns whether the pseudo cost entry is empty in the given branching direction (whether no value was added yet) */
613 SCIP_HISTORY* history, /**< branching and inference history */
614 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
615 )
616{
617 assert(history != NULL);
619 assert((int)dir == 0 || (int)dir == 1);
620
621 return (history->pscostcount[dir] == 0.0);
622}
623
624/** returns whether the ancestral pseudo cost entry is empty in the given branching direction (whether no value was added yet) */
626 SCIP_HISTORY* history, /**< branching and inference history */
627 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
628 )
629{
630 assert(history != NULL);
632 assert((int)dir == 0 || (int)dir == 1);
633
634 return (history->ancpscostcount[dir] == 0.0);
635}
636
637/** increases the conflict score of the history entry by the given weight */
639 SCIP_HISTORY* history, /**< branching and inference history */
640 SCIP_BRANCHDIR dir, /**< branching direction */
641 SCIP_Real weight /**< weight of this update in conflict score */
642 )
643{
644 assert(history != NULL);
646 assert((int)dir == 0 || (int)dir == 1);
647
648 history->vsids[dir] += weight;
649}
650
651/** scales the conflict score values with the given scalar */
653 SCIP_HISTORY* history, /**< branching and inference history */
654 SCIP_Real scalar /**< scalar to multiply the conflict scores with */
655 )
656{
657 assert(history != NULL);
658
659 history->vsids[0] *= scalar;
660 history->vsids[1] *= scalar;
661}
662
663/** gets the conflict score of the history entry */
665 SCIP_HISTORY* history, /**< branching and inference history */
666 SCIP_BRANCHDIR dir /**< branching direction */
667 )
668{
669 assert(history != NULL);
671 assert((int)dir == 0 || (int)dir == 1);
672
673 return history->vsids[dir];
674}
675
676/** increases the number of active conflicts by one and the overall length of the history entry by the given weight */
678 SCIP_HISTORY* history, /**< branching and inference history */
679 SCIP_BRANCHDIR dir, /**< branching direction */
680 SCIP_Real length /**< length of the conflict */
681 )
682{
683 assert(history != NULL);
685 assert((int)dir == 0 || (int)dir == 1);
686 assert(length >= 0.0);
687
688 history->nactiveconflicts[dir]++;
689 history->conflengthsum[dir] += length;
690}
691
692/** gets the number of active conflicts of the history entry */
694 SCIP_HISTORY* history, /**< branching and inference history */
695 SCIP_BRANCHDIR dir /**< branching direction */
696 )
697{
698 assert(history != NULL);
700 assert((int)dir == 0 || (int)dir == 1);
701
702 return history->nactiveconflicts[dir];
703}
704
705/** gets the average conflict length of the history entry */
707 SCIP_HISTORY* history, /**< branching and inference history */
708 SCIP_BRANCHDIR dir /**< branching direction */
709 )
710{
711 assert(history != NULL);
713 assert((int)dir == 0 || (int)dir == 1);
714
715 return history->conflengthsum[dir] > 0.0 ? (SCIP_Real)history->nactiveconflicts[dir]/(SCIP_Real)history->conflengthsum[dir] : 0.0;
716}
717
718/** increases the number of branchings counter */
720 SCIP_HISTORY* history, /**< branching and inference history */
721 SCIP_BRANCHDIR dir, /**< branching direction (downwards, or upwards) */
722 int depth /**< depth at which the bound change took place */
723 )
724{
725 assert(history != NULL);
726 assert(depth >= 1);
728 assert((int)dir == 0 || (int)dir == 1);
729
730 history->nbranchings[dir]++;
731 history->branchdepthsum[dir] += depth;
732}
733
734/** increases the number of inferences counter by a certain value */
736 SCIP_HISTORY* history, /**< branching and inference history */
737 SCIP_BRANCHDIR dir, /**< branching direction (downwards, or upwards) */
738 SCIP_Real weight /**< weight of this update in inference score */
739 )
740{
741 assert(history != NULL);
743 assert((int)dir == 0 || (int)dir == 1);
744 assert(history->nbranchings[dir] >= 1);
745 assert(weight >= 0.0);
746
747 history->inferencesum[dir] += weight;
748}
749
750/** increases the number of cutoffs counter */
752 SCIP_HISTORY* history, /**< branching and inference history */
753 SCIP_BRANCHDIR dir, /**< branching direction (downwards, or upwards) */
754 SCIP_Real weight /**< weight of this update in cutoff score */
755 )
756{
757 assert(history != NULL);
759 assert((int)dir == 0 || (int)dir == 1);
760 assert(history->nbranchings[dir] >= 1);
761 assert(weight >= 0.0);
762
763 history->cutoffsum[dir] += weight;
764}
765
766/** get number of branchings counter */
768 SCIP_HISTORY* history, /**< branching and inference history */
769 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
770 )
771{
772 assert(history != NULL);
774 assert((int)dir == 0 || (int)dir == 1);
775
776 return history->nbranchings[dir];
777}
778
779/** get number of inferences counter */
781 SCIP_HISTORY* history, /**< branching and inference history */
782 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
783 )
784{
785 assert(history != NULL);
787 assert((int)dir == 0 || (int)dir == 1);
788
789 return history->inferencesum[dir];
790}
791
792/** returns the average number of inferences per branching */
794 SCIP_HISTORY* history, /**< branching and inference history */
795 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
796 )
797{
798 assert(history != NULL);
800 assert((int)dir == 0 || (int)dir == 1);
801
802 return history->nbranchings[dir] > 0 ? (SCIP_Real)history->inferencesum[dir]/(SCIP_Real)history->nbranchings[dir] : 0.0;
803}
804
805/** get number of cutoffs counter */
807 SCIP_HISTORY* history, /**< branching and inference history */
808 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
809 )
810{
811 assert(history != NULL);
813 assert((int)dir == 0 || (int)dir == 1);
814
815 return history->cutoffsum[dir];
816}
817
818/** returns the average number of cutoffs per branching */
820 SCIP_HISTORY* history, /**< branching and inference history */
821 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
822 )
823{
824 assert(history != NULL);
826 assert((int)dir == 0 || (int)dir == 1);
827
828 return history->nbranchings[dir] > 0 ? (SCIP_Real)history->cutoffsum[dir]/(SCIP_Real)history->nbranchings[dir] : 0.0;
829}
830
831/** returns the average depth of bound changes due to branching */
833 SCIP_HISTORY* history, /**< branching and inference history */
834 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */
835 )
836{
837 assert(history != NULL);
839 assert((int)dir == 0 || (int)dir == 1);
840
841 return history->nbranchings[dir] > 0 ? (SCIP_Real)history->branchdepthsum[dir]/(SCIP_Real)history->nbranchings[dir] : 1.0;
842}
843
844/** returns true if the given history contains a valid ratio */
846 SCIP_HISTORY* history /**< branching and inference history */
847 )
848{
849 assert(history != NULL);
850
851 return history->ratiovalid;
852}
853
854/** returns the most recent ratio computed given the variable history */
856 SCIP_HISTORY* history /**< branching and inference history */
857 )
858{
859 assert(history != NULL);
860 assert(history->ratiovalid);
861
862 return history->ratio;
863}
864
865/** returns the most recent value of r/l used to compute this variable's ratio */
867 SCIP_HISTORY* history /**< branching and inference history */
868 )
869{
870 assert(history != NULL);
871 assert(history->ratiovalid);
872
873 return history->balance;
874}
875
876/** returns the average efficacy value for the GMI cut produced by this variable */
878 SCIP_HISTORY* history /**< branching and inference history */
879 )
880{
881 assert(history != NULL);
882
883 return history->ngmi > 0 ? history->gmieffsum / history->ngmi : 0.0;
884}
885
886/** increases the average efficacy value for the GMI cut produced by this variable */
888 SCIP_HISTORY* history, /**< branching and inference history */
889 SCIP_Real gmieff /**< normalized efficacy value of a cut which will increase gmieff */
890 )
891{
892 assert(history != NULL);
893 assert(gmieff >= 0.0);
894
895 history->gmieffsum += gmieff;
896 history->ngmi += 1;
897}
898
899/** returns the most recent efficacy value for the GMI cut produced by this variable */
901 SCIP_HISTORY* history /**< branching and inference history */
902 )
903{
904 assert(history != NULL);
905
906 return history->gmieff;
907}
908
909/** sets the new most recent efficacy value for the GMI cut produced by this variable */
911 SCIP_HISTORY* history, /**< branching and inference history */
912 SCIP_Real gmieff /**< Efficacy of GMI cut produced from simplex tableau row of this var */
913 )
914{
915 assert(history != NULL);
916
917 history->gmieff = gmieff;
918}
919
920/** sets the ratio history for a particular variable */
922 SCIP_HISTORY* history, /**< branching and inference history */
923 SCIP_Bool valid, /**< True iff the ratio computed is valid */
924 SCIP_Real ratio, /**< Ratio of the characteristic polynomial with gains (1, rightgain/leftgain) */
925 SCIP_Real balance /**< The value of rightgain/leftgain */
926 )
927{
928 assert(history != NULL);
929
930 history->ratiovalid = valid;
931 history->ratio = ratio;
932 history->balance = balance;
933}
common defines and data types used in all packages of SCIP
#define NULL
Definition def.h:257
#define SCIP_Longint
Definition def.h:150
#define SCIP_Bool
Definition def.h:100
#define SCIP_ALLOC(x)
Definition def.h:375
#define SCIP_Real
Definition def.h:165
#define FALSE
Definition def.h:103
#define MAX(x, y)
Definition def.h:229
#define REALABS(x)
Definition def.h:191
#define SCIP_CALL(x)
Definition def.h:364
SCIP_Bool SCIPsortedvecFindReal(SCIP_Real *realarray, SCIP_Real val, int len, int *pos)
void SCIPsortedvecInsertRealPtr(SCIP_Real *realarray, void **ptrarray, SCIP_Real keyval, void *field1val, int *len, int *pos)
int SCIPvaluehistoryGetNValues(SCIP_VALUEHISTORY *valuehistory)
Definition history.c:445
SCIP_RETCODE SCIPvaluehistoryCreate(SCIP_VALUEHISTORY **valuehistory, BMS_BLKMEM *blkmem)
Definition history.c:323
SCIP_HISTORY ** SCIPvaluehistoryGetHistories(SCIP_VALUEHISTORY *valuehistory)
Definition history.c:455
SCIP_RETCODE SCIPvaluehistoryFind(SCIP_VALUEHISTORY *valuehistory, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_Real value, SCIP_HISTORY **history)
Definition history.c:364
SCIP_Real * SCIPvaluehistoryGetValues(SCIP_VALUEHISTORY *valuehistory)
Definition history.c:465
void SCIPvaluehistoryFree(SCIP_VALUEHISTORY **valuehistory, BMS_BLKMEM *blkmem)
Definition history.c:342
void SCIPvaluehistoryScaleVSIDS(SCIP_VALUEHISTORY *valuehistory, SCIP_Real scalar)
Definition history.c:409
return SCIP_OKAY
int depth
assert(minobj< SCIPgetCutoffbound(scip))
void SCIPhistoryReset(SCIP_HISTORY *history)
Definition history.c:78
SCIP_Real SCIPhistoryGetPseudocost(SCIP_HISTORY *history, SCIP_Real solvaldelta)
Definition history.c:532
SCIP_Real SCIPhistoryGetAvgInferences(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
Definition history.c:793
void SCIPhistorySetRatioHistory(SCIP_HISTORY *history, SCIP_Bool valid, SCIP_Real ratio, SCIP_Real balance)
Definition history.c:921
SCIP_Longint SCIPhistoryGetNActiveConflicts(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
Definition history.c:693
SCIP_Longint SCIPhistoryGetNBranchings(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
Definition history.c:767
SCIP_Real SCIPhistoryGetAvgConflictlength(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
Definition history.c:706
SCIP_Real SCIPhistoryGetAvgCutoffs(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
Definition history.c:819
SCIP_RETCODE SCIPhistoryCreate(SCIP_HISTORY **history, BMS_BLKMEM *blkmem)
Definition history.c:51
SCIP_Real SCIPhistoryGetAncPseudocostCount(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
Definition history.c:599
void SCIPhistorySetLastGMIeff(SCIP_HISTORY *history, SCIP_Real gmieff)
Definition history.c:910
void SCIPhistoryUpdateAncPseudocost(SCIP_HISTORY *history, SCIP_SET *set, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition history.c:255
SCIP_Real SCIPhistoryGetLastRatio(SCIP_HISTORY *history)
Definition history.c:855
void SCIPhistoryIncInferenceSum(SCIP_HISTORY *history, SCIP_BRANCHDIR dir, SCIP_Real weight)
Definition history.c:735
SCIP_Real SCIPhistoryGetAncPseudocost(SCIP_HISTORY *history, SCIP_Real solvaldelta)
Definition history.c:546
SCIP_Real SCIPhistoryGetCutoffSum(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
Definition history.c:806
SCIP_Real SCIPhistoryGetPseudocostCount(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
Definition history.c:584
SCIP_Bool SCIPhistoryIsPseudocostEmpty(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
Definition history.c:612
SCIP_Bool SCIPhistoryIsAncPseudocostEmpty(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
Definition history.c:625
SCIP_Real SCIPhistoryGetPseudocostVariance(SCIP_HISTORY *history, SCIP_BRANCHDIR direction)
Definition history.c:560
void SCIPhistoryIncNActiveConflicts(SCIP_HISTORY *history, SCIP_BRANCHDIR dir, SCIP_Real length)
Definition history.c:677
void SCIPhistoryScaleVSIDS(SCIP_HISTORY *history, SCIP_Real scalar)
Definition history.c:652
void SCIPhistoryIncCutoffSum(SCIP_HISTORY *history, SCIP_BRANCHDIR dir, SCIP_Real weight)
Definition history.c:751
void SCIPhistoryIncNBranchings(SCIP_HISTORY *history, SCIP_BRANCHDIR dir, int depth)
Definition history.c:719
void SCIPhistoryUpdatePseudocost(SCIP_HISTORY *history, SCIP_SET *set, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
Definition history.c:191
SCIP_Real SCIPhistoryGetVSIDS(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
Definition history.c:664
SCIP_Bool SCIPhistoryIsRatioValid(SCIP_HISTORY *history)
Definition history.c:845
SCIP_Real SCIPhistoryGetAvgBranchdepth(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
Definition history.c:832
SCIP_Real SCIPhistoryGetLastBalance(SCIP_HISTORY *history)
Definition history.c:866
SCIP_Real SCIPhistoryGetLastGMIeff(SCIP_HISTORY *history)
Definition history.c:900
SCIP_Real SCIPhistoryGetAvgGMIeff(SCIP_HISTORY *history)
Definition history.c:877
SCIP_Real SCIPhistoryGetInferenceSum(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
Definition history.c:780
void SCIPhistoryFree(SCIP_HISTORY **history, BMS_BLKMEM *blkmem)
Definition history.c:66
void SCIPhistoryUnite(SCIP_HISTORY *history, SCIP_HISTORY *addhistory, SCIP_Bool switcheddirs)
Definition history.c:117
void SCIPhistoryIncGMIeffSum(SCIP_HISTORY *history, SCIP_Real gmieff)
Definition history.c:887
SCIP_BRANCHDIR SCIPbranchdirOpposite(SCIP_BRANCHDIR dir)
Definition history.c:523
void SCIPhistoryIncVSIDS(SCIP_HISTORY *history, SCIP_BRANCHDIR dir, SCIP_Real weight)
Definition history.c:638
internal methods for branching and inference history
#define BMSfreeBlockMemory(mem, ptr)
Definition memory.h:465
#define BMSallocBlockMemory(mem, ptr)
Definition memory.h:451
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition memory.h:454
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition memory.h:467
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition memory.h:458
struct BMS_BlkMem BMS_BLKMEM
Definition memory.h:437
real eps
public methods for branching and inference history structure
public methods for message output
public data structures and miscellaneous methods
SCIP_Real SCIPsetPseudocosteps(SCIP_SET *set)
Definition set.c:6466
SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
Definition set.c:6654
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition set.c:6521
SCIP_Real SCIPsetPseudocostdelta(SCIP_SET *set)
Definition set.c:6476
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition set.c:6086
SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
Definition set.c:6665
internal methods for global SCIP settings
#define SCIPsetDebugMsg
Definition set.h:1811
SCIP_Real ancpscostcount[2]
SCIP_Longint nbranchings[2]
SCIP_Real pscostweightedmean[2]
SCIP_Longint nactiveconflicts[2]
SCIP_Bool ratiovalid
SCIP_Real pscostvariance[2]
SCIP_Real vsids[2]
SCIP_Real pscostcount[2]
SCIP_Real ratio
SCIP_Real cutoffsum[2]
SCIP_Real ngmi
SCIP_Real inferencesum[2]
SCIP_Real balance
SCIP_Real gmieff
SCIP_Real conflengthsum[2]
SCIP_Real ancpscostweightedmean[2]
SCIP_Real gmieffsum
SCIP_Longint branchdepthsum[2]
SCIP_HISTORY ** histories
datastructures for branching and inference history
struct SCIP_History SCIP_HISTORY
@ SCIP_BRANCHDIR_DOWNWARDS
@ SCIP_BRANCHDIR_AUTO
@ SCIP_BRANCHDIR_UPWARDS
struct SCIP_ValueHistory SCIP_VALUEHISTORY
enum SCIP_BranchDir SCIP_BRANCHDIR
enum SCIP_Retcode SCIP_RETCODE
struct SCIP_Set SCIP_SET
Definition type_set.h:71