Scippy

    SCIP

    Solving Constraint Integer Programs

    nlhdlr.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-2025 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 nlhdlr.c
    26 * @ingroup OTHER_CFILES
    27 * @brief functions for nonlinearity handlers of nonlinear constraint handler
    28 * @author Ksenia Bestuzheva
    29 * @author Benjamin Mueller
    30 * @author Felipe Serrano
    31 * @author Stefan Vigerske
    32 */
    33
    34#include <assert.h>
    35#include <string.h>
    36
    37#include "scip/pub_nlhdlr.h"
    38#include "scip/nlhdlr.h"
    39#include "scip/struct_nlhdlr.h"
    40#include "scip/scip_datatree.h"
    41#include "scip/scip_timing.h"
    42#include "scip/scip_mem.h"
    43#include "scip/scip_param.h"
    44#include "scip/scip_message.h"
    45#include "scip/pub_message.h"
    46#include "scip/pub_misc.h"
    47
    48/**@addtogroup PublicNlhdlrInterfaceMethods
    49 * @{
    50 */
    51
    52#ifdef NDEBUG
    53/* Undo the defines from pub_nlhdlr.h, which exist if NDEBUG is defined. */
    54#undef SCIPnlhdlrSetCopyHdlr
    55#undef SCIPnlhdlrSetFreeHdlrData
    56#undef SCIPnlhdlrSetFreeExprData
    57#undef SCIPnlhdlrSetInitExit
    58#undef SCIPnlhdlrSetProp
    59#undef SCIPnlhdlrSetSepa
    60#undef SCIPnlhdlrSetSollinearize
    61#undef SCIPnlhdlrGetName
    62#undef SCIPnlhdlrGetDesc
    63#undef SCIPnlhdlrGetDetectPriority
    64#undef SCIPnlhdlrGetEnfoPriority
    65#undef SCIPnlhdlrIsEnabled
    66#undef SCIPnlhdlrGetData
    67#undef SCIPnlhdlrHasIntEval
    68#undef SCIPnlhdlrHasReverseProp
    69#undef SCIPnlhdlrHasInitSepa
    70#undef SCIPnlhdlrHasExitSepa
    71#undef SCIPnlhdlrHasEnfo
    72#undef SCIPnlhdlrHasEstimate
    73#undef SCIPnlhdlrHasSollinearize
    74#endif
    75
    76/** sets the copy handler callback of a nonlinear handler */
    78 SCIP_NLHDLR* nlhdlr, /**< nonlinear handler */
    79 SCIP_DECL_NLHDLRCOPYHDLR((*copy)) /**< copy callback (can be NULL) */
    80 )
    81{
    82 assert(nlhdlr != NULL);
    83
    84 nlhdlr->copyhdlr = copy;
    85}
    86
    87/** sets the nonlinear handler callback to free the nonlinear handler data */
    89 SCIP_NLHDLR* nlhdlr, /**< nonlinear handler */
    90 SCIP_DECL_NLHDLRFREEHDLRDATA((*freehdlrdata)) /**< handler free callback (can be NULL) */
    91 )
    92{
    93 assert(nlhdlr != NULL);
    94
    95 nlhdlr->freehdlrdata = freehdlrdata;
    96}
    97
    98/** sets the nonlinear handler callback to free expression specific data of nonlinear handler */
    100 SCIP_NLHDLR* nlhdlr, /**< nonlinear handler */
    101 SCIP_DECL_NLHDLRFREEEXPRDATA((*freeexprdata)) /**< nonlinear handler expression data free callback
    102 * (can be NULL if data does not need to be freed) */
    103 )
    104{
    105 assert(nlhdlr != NULL);
    106
    107 nlhdlr->freeexprdata = freeexprdata;
    108}
    109
    110/** sets the initialization and deinitialization callback of a nonlinear handler */
    112 SCIP_NLHDLR* nlhdlr, /**< nonlinear handler */
    113 SCIP_DECL_NLHDLRINIT((*init)), /**< initialization callback (can be NULL) */
    114 SCIP_DECL_NLHDLREXIT((*exit_)) /**< deinitialization callback (can be NULL) */
    115 )
    116{
    117 assert(nlhdlr != NULL);
    118
    119 nlhdlr->init = init;
    120 nlhdlr->exit = exit_;
    121}
    122
    123/** sets the propagation callbacks of a nonlinear handler */
    125 SCIP_NLHDLR* nlhdlr, /**< nonlinear handler */
    126 SCIP_DECL_NLHDLRINTEVAL((*inteval)), /**< interval evaluation callback (can be NULL) */
    127 SCIP_DECL_NLHDLRREVERSEPROP((*reverseprop)) /**< reverse propagation callback (can be NULL) */
    128 )
    129{
    130 assert(nlhdlr != NULL);
    131
    132 nlhdlr->inteval = inteval;
    133 nlhdlr->reverseprop = reverseprop;
    134}
    135
    136/** sets the enforcement callbacks of a nonlinear handler */
    138 SCIP_NLHDLR* nlhdlr, /**< nonlinear handler */
    139 SCIP_DECL_NLHDLRINITSEPA((*initsepa)), /**< separation initialization callback (can be NULL) */
    140 SCIP_DECL_NLHDLRENFO((*enfo)), /**< enforcement callback (can be NULL if estimate is not NULL) */
    141 SCIP_DECL_NLHDLRESTIMATE((*estimate)), /**< estimation callback (can be NULL if sepa is not NULL) */
    142 SCIP_DECL_NLHDLREXITSEPA((*exitsepa)) /**< separation deinitialization callback (can be NULL) */
    143 )
    144{
    145 assert(nlhdlr != NULL);
    146 assert(enfo != NULL || estimate != NULL);
    147
    148 nlhdlr->initsepa = initsepa;
    149 nlhdlr->enfo = enfo;
    150 nlhdlr->estimate = estimate;
    151 nlhdlr->exitsepa = exitsepa;
    152}
    153
    154/** sets the solution linearization callback of a nonlinear handler */
    156 SCIP_NLHDLR* nlhdlr, /**< nonlinear handler */
    157 SCIP_DECL_NLHDLRSOLLINEARIZE((*sollinearize)) /**< solution linearization callback */
    158 )
    159{
    160 assert(nlhdlr != NULL);
    161 assert(sollinearize != NULL);
    162
    163 nlhdlr->sollinearize = sollinearize;
    164}
    165
    166/** gives name of nonlinear handler */
    168 SCIP_NLHDLR* nlhdlr /**< nonlinear handler */
    169 )
    170{
    171 assert(nlhdlr != NULL);
    172
    173 return nlhdlr->name;
    174}
    175
    176/** gives description of nonlinear handler, can be NULL */
    178 SCIP_NLHDLR* nlhdlr /**< nonlinear handler */
    179 )
    180{
    181 assert(nlhdlr != NULL);
    182
    183 return nlhdlr->desc;
    184}
    185
    186/** gives detection priority of nonlinear handler */
    188 SCIP_NLHDLR* nlhdlr /**< nonlinear handler */
    189 )
    190{
    191 assert(nlhdlr != NULL);
    192
    193 return nlhdlr->detectpriority;
    194}
    195
    196/** gives enforcement priority of nonlinear handler */
    198 SCIP_NLHDLR* nlhdlr /**< nonlinear handler */
    199 )
    200{
    201 assert(nlhdlr != NULL);
    202
    203 return nlhdlr->enfopriority;
    204}
    205
    206/** returns whether nonlinear handler is enabled */
    208 SCIP_NLHDLR* nlhdlr /**< nonlinear handler */
    209 )
    210{
    211 assert(nlhdlr != NULL);
    212
    213 return nlhdlr->enabled;
    214}
    215
    216/** gives handler data of nonlinear handler */
    218 SCIP_NLHDLR* nlhdlr /**< nonlinear handler */
    219 )
    220{
    221 assert(nlhdlr != NULL);
    222
    223 return nlhdlr->data;
    224}
    225
    226/** returns whether nonlinear handler implements the interval evaluation callback */
    228 SCIP_NLHDLR* nlhdlr /**< nonlinear handler */
    229 )
    230{
    231 assert(nlhdlr != NULL);
    232
    233 return nlhdlr->inteval != NULL;
    234}
    235
    236/** returns whether nonlinear handler implements the reverse propagation callback */
    238 SCIP_NLHDLR* nlhdlr /**< nonlinear handler */
    239 )
    240{
    241 assert(nlhdlr != NULL);
    242
    243 return nlhdlr->reverseprop != NULL;
    244}
    245
    246/** returns whether nonlinear handler implements the separation initialization callback */
    248 SCIP_NLHDLR* nlhdlr /**< nonlinear handler */
    249 )
    250{
    251 assert(nlhdlr != NULL);
    252
    253 return nlhdlr->initsepa != NULL;
    254}
    255
    256/** returns whether nonlinear handler implements the separation deinitialization callback */
    258 SCIP_NLHDLR* nlhdlr /**< nonlinear handler */
    259 )
    260{
    261 assert(nlhdlr != NULL);
    262
    263 return nlhdlr->exitsepa != NULL;
    264}
    265
    266/** returns whether nonlinear handler implements the enforcement callback */
    268 SCIP_NLHDLR* nlhdlr /**< nonlinear handler */
    269 )
    270{
    271 assert(nlhdlr != NULL);
    272
    273 return nlhdlr->enfo != NULL;
    274}
    275
    276/** returns whether nonlinear handler implements the estimator callback */
    278 SCIP_NLHDLR* nlhdlr /**< nonlinear handler */
    279 )
    280{
    281 assert(nlhdlr != NULL);
    282
    283 return nlhdlr->estimate != NULL;
    284}
    285
    286/** returns whether nonlinear handler implements the solution linearization callback */
    288 SCIP_NLHDLR* nlhdlr /**< nonlinear handler */
    289 )
    290{
    291 assert(nlhdlr != NULL);
    292
    293 return nlhdlr->sollinearize != NULL;
    294}
    295
    296/** compares two nonlinear handlers by detection priority
    297 *
    298 * if handlers have same detection priority, then compare by name
    299 */
    301{
    302 SCIP_NLHDLR* h1;
    303 SCIP_NLHDLR* h2;
    304
    305 assert(elem1 != NULL);
    306 assert(elem2 != NULL);
    307
    308 h1 = (SCIP_NLHDLR*)elem1;
    309 h2 = (SCIP_NLHDLR*)elem2;
    310
    311 if( h1->detectpriority != h2->detectpriority )
    312 return h1->detectpriority - h2->detectpriority;
    313
    314 return strcmp(h1->name, h2->name);
    315}
    316
    317#ifdef SCIP_DISABLED_CODE
    318/** compares nonlinear handler by enforcement priority
    319 *
    320 * if handlers have same enforcement priority, then compare by detection priority, then by name
    321 */
    322SCIP_DECL_SORTPTRCOMP(SCIPnlhdlrCompEnfo)
    323{
    324 SCIP_NLHDLR* h1;
    325 SCIP_NLHDLR* h2;
    326
    327 assert(elem1 != NULL);
    328 assert(elem2 != NULL);
    329
    330 h1 = (SCIP_NLHDLR*)elem1;
    331 h2 = (SCIP_NLHDLR*)elem2;
    332
    333 if( h1->enfopriority != h2->enfopriority )
    334 return h1->enfopriority - h2->enfopriority;
    335
    336 if( h1->detectpriority != h2->detectpriority )
    337 return h1->detectpriority - h2->detectpriority;
    338
    339 return strcmp(h1->name, h2->name);
    340}
    341#endif
    342
    343/** @} */
    344
    345/* nlhdlr private API functions from nlhdlr.h */
    346
    347#ifndef NDEBUG
    348#undef SCIPnlhdlrResetNDetectionslast
    349#undef SCIPnlhdlrIncrementNCutoffs
    350#undef SCIPnlhdlrIncrementNSeparated
    351#endif
    352
    353/** creates a nonlinear handler */
    355 SCIP* scip, /**< SCIP data structure */
    356 SCIP_NLHDLR** nlhdlr, /**< buffer to store pointer to created nonlinear handler */
    357 const char* name, /**< name of nonlinear handler (must not be NULL) */
    358 const char* desc, /**< description of nonlinear handler (can be NULL) */
    359 int detectpriority, /**< detection priority of nonlinear handler */
    360 int enfopriority, /**< enforcement priority of nonlinear handler */
    361 SCIP_DECL_NLHDLRDETECT((*detect)), /**< structure detection callback of nonlinear handler */
    362 SCIP_DECL_NLHDLREVALAUX((*evalaux)), /**< auxiliary evaluation callback of nonlinear handler */
    363 SCIP_NLHDLRDATA* nlhdlrdata /**< data of nonlinear handler (can be NULL) */
    364 )
    365{
    367
    368 assert(scip != NULL);
    369 assert(nlhdlr != NULL);
    370 assert(name != NULL);
    371 assert(detect != NULL);
    372 assert(evalaux != NULL);
    373
    375
    376 SCIP_CALL( SCIPduplicateMemoryArray(scip, &(*nlhdlr)->name, name, strlen(name)+1) );
    377 if( desc != NULL )
    378 {
    379 SCIP_CALL_FINALLY( SCIPduplicateMemoryArray(scip, &(*nlhdlr)->desc, desc, strlen(desc)+1),
    380 SCIPfreeMemoryArray(scip, &(*nlhdlr)->name) );
    381 }
    382
    383 (*nlhdlr)->detectpriority = detectpriority;
    384 (*nlhdlr)->enfopriority = enfopriority;
    385 (*nlhdlr)->data = nlhdlrdata;
    386 (*nlhdlr)->detect = detect;
    387 (*nlhdlr)->evalaux = evalaux;
    388
    389 SCIP_CALL( SCIPcreateClock(scip, &(*nlhdlr)->detecttime) );
    390 SCIP_CALL( SCIPcreateClock(scip, &(*nlhdlr)->enfotime) );
    391 SCIP_CALL( SCIPcreateClock(scip, &(*nlhdlr)->proptime) );
    392 SCIP_CALL( SCIPcreateClock(scip, &(*nlhdlr)->intevaltime) );
    393
    394 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "nlhdlr/%s/enabled", name);
    395 SCIP_CALL( SCIPaddBoolParam(scip, paramname, "should this nonlinear handler be used",
    396 &(*nlhdlr)->enabled, FALSE, TRUE, NULL, NULL) );
    397
    398 return SCIP_OKAY;
    399}
    400
    401/** frees a nonlinear handler */
    403 SCIP* scip, /**< SCIP data structure */
    404 SCIP_NLHDLR** nlhdlr /**< pointer to nonlinear handler to be freed */
    405 )
    406{
    407 assert(nlhdlr != NULL);
    408 assert(*nlhdlr != NULL);
    409
    410 if( (*nlhdlr)->freehdlrdata != NULL )
    411 {
    412 SCIP_CALL( (*nlhdlr)->freehdlrdata(scip, *nlhdlr, &(*nlhdlr)->data) );
    413 }
    414
    415 /* free clocks */
    416 SCIP_CALL( SCIPfreeClock(scip, &(*nlhdlr)->detecttime) );
    417 SCIP_CALL( SCIPfreeClock(scip, &(*nlhdlr)->enfotime) );
    418 SCIP_CALL( SCIPfreeClock(scip, &(*nlhdlr)->proptime) );
    419 SCIP_CALL( SCIPfreeClock(scip, &(*nlhdlr)->intevaltime) );
    420
    421 SCIPfreeMemory(scip, &(*nlhdlr)->name);
    422 SCIPfreeMemoryNull(scip, &(*nlhdlr)->desc);
    423
    424 SCIPfreeBlockMemory(scip, nlhdlr);
    425
    426 return SCIP_OKAY;
    427}
    428
    429/** call the handler copy callback of a nonlinear handler */
    430SCIP_DECL_NLHDLRCOPYHDLR(SCIPnlhdlrCopyhdlr)
    431{
    432 /* TODO for now just don't copy disabled nlhdlr, a clean way would probably be to first copy and disable then */
    433 if( sourcenlhdlr->copyhdlr != NULL && sourcenlhdlr->enabled )
    434 {
    435 SCIP_CALL( sourcenlhdlr->copyhdlr(targetscip, targetconshdlr, sourceconshdlr, sourcenlhdlr) );
    436 }
    437
    438 return SCIP_OKAY;
    439}
    440
    441/** call the free expression specific data callback of a nonlinear handler */
    442SCIP_DECL_NLHDLRFREEEXPRDATA(SCIPnlhdlrFreeexprdata)
    443{
    444 assert(nlhdlr != NULL);
    445 assert(nlhdlrexprdata != NULL);
    446 assert(*nlhdlrexprdata != NULL);
    447
    448 if( nlhdlr->freeexprdata != NULL )
    449 {
    450 SCIP_CALL( nlhdlr->freeexprdata(scip, nlhdlr, expr, nlhdlrexprdata) );
    451 assert(*nlhdlrexprdata == NULL);
    452 }
    453
    454 return SCIP_OKAY;
    455}
    456
    457/** call the initialization callback of a nonlinear handler */
    458SCIP_DECL_NLHDLRINIT(SCIPnlhdlrInit)
    459{
    460 assert(nlhdlr != NULL);
    461
    462 nlhdlr->nenfocalls = 0;
    463 nlhdlr->nintevalcalls = 0;
    464 nlhdlr->npropcalls = 0;
    465 nlhdlr->nseparated = 0;
    466 nlhdlr->ncutoffs = 0;
    467 nlhdlr->ndomreds = 0;
    468 nlhdlr->nbranchscores = 0;
    469 nlhdlr->ndetections = 0;
    470 nlhdlr->ndetectionslast = 0;
    471
    476
    477 if( nlhdlr->init != NULL )
    478 {
    479 SCIP_CALL( nlhdlr->init(scip, nlhdlr) );
    480 }
    481
    482 return SCIP_OKAY;
    483}
    484
    485/** call the deinitialization callback of a nonlinear handler */
    486SCIP_DECL_NLHDLREXIT(SCIPnlhdlrExit)
    487{
    488 assert(nlhdlr != NULL);
    489
    490 if( nlhdlr->exit != NULL )
    491 {
    492 SCIP_CALL( nlhdlr->exit(scip, nlhdlr) );
    493 }
    494
    495 return SCIP_OKAY;
    496}
    497
    498/** call the detect callback of a nonlinear handler */
    499SCIP_DECL_NLHDLRDETECT(SCIPnlhdlrDetect)
    500{
    501 assert(scip != NULL);
    502 assert(nlhdlr != NULL);
    503 assert(nlhdlr->detect != NULL);
    504 assert(nlhdlr->detecttime != NULL);
    505 assert(participating != NULL);
    506
    508 SCIP_CALL( nlhdlr->detect(scip, conshdlr, nlhdlr, expr, cons, enforcing, participating, nlhdlrexprdata) );
    510
    511 if( *participating != SCIP_NLHDLR_METHOD_NONE )
    512 {
    513 ++nlhdlr->ndetections;
    514 ++nlhdlr->ndetectionslast;
    515 }
    516
    517 return SCIP_OKAY;
    518}
    519
    520/** call the auxiliary evaluation callback of a nonlinear handler */
    521SCIP_DECL_NLHDLREVALAUX(SCIPnlhdlrEvalaux)
    522{
    523 assert(nlhdlr != NULL);
    524 assert(nlhdlr->evalaux != NULL);
    525
    526 SCIP_CALL( nlhdlr->evalaux(scip, nlhdlr, expr, nlhdlrexprdata, auxvalue, sol) );
    527
    528 return SCIP_OKAY;
    529}
    530
    531/** call the interval evaluation callback of a nonlinear handler */
    532SCIP_DECL_NLHDLRINTEVAL(SCIPnlhdlrInteval)
    533{
    534 assert(scip != NULL);
    535 assert(nlhdlr != NULL);
    536 assert(nlhdlr->intevaltime != NULL);
    537
    538 if( nlhdlr->inteval != NULL )
    539 {
    541 SCIP_CALL( nlhdlr->inteval(scip, nlhdlr, expr, nlhdlrexprdata, interval, intevalvar, intevalvardata) );
    543
    544 ++nlhdlr->nintevalcalls;
    545 }
    546
    547 return SCIP_OKAY;
    548}
    549
    550/** call the reverse propagation callback of a nonlinear handler */
    551SCIP_DECL_NLHDLRREVERSEPROP(SCIPnlhdlrReverseprop)
    552{
    553 assert(scip != NULL);
    554 assert(nlhdlr != NULL);
    555 assert(nlhdlr->proptime != NULL);
    556 assert(infeasible != NULL);
    557 assert(nreductions != NULL);
    558
    559 if( nlhdlr->reverseprop == NULL )
    560 {
    561 *infeasible = FALSE;
    562 *nreductions = 0;
    563
    564 return SCIP_OKAY;
    565 }
    566
    568 SCIP_CALL( nlhdlr->reverseprop(scip, conshdlr, nlhdlr, expr, nlhdlrexprdata, bounds, infeasible, nreductions) );
    570
    571 /* update statistics */
    572 nlhdlr->ndomreds += *nreductions;
    573 if( *infeasible )
    574 ++nlhdlr->ncutoffs;
    575 ++nlhdlr->npropcalls;
    576
    577 return SCIP_OKAY;
    578}
    579
    580/** call the separation initialization callback of a nonlinear handler */
    581SCIP_DECL_NLHDLRINITSEPA(SCIPnlhdlrInitsepa)
    582{
    583 assert(scip != NULL);
    584 assert(nlhdlr != NULL);
    585 assert(nlhdlr->enfotime != NULL);
    586 assert(infeasible != NULL);
    587
    588 if( nlhdlr->initsepa == NULL )
    589 {
    590 *infeasible = FALSE;
    591 return SCIP_OKAY;
    592 }
    593
    595 SCIP_CALL( nlhdlr->initsepa(scip, conshdlr, cons, nlhdlr, expr, nlhdlrexprdata, overestimate, underestimate, infeasible) );
    597
    598 ++nlhdlr->nenfocalls;
    599 if( *infeasible )
    600 ++nlhdlr->ncutoffs;
    601
    602 return SCIP_OKAY;
    603}
    604
    605/** call the separation deinitialization callback of a nonlinear handler */
    606SCIP_DECL_NLHDLREXITSEPA(SCIPnlhdlrExitsepa)
    607{
    608 assert(scip != NULL);
    609 assert(nlhdlr != NULL);
    610 assert(nlhdlr->enfotime != NULL);
    611
    612 if( nlhdlr->exitsepa != NULL )
    613 {
    615 SCIP_CALL( nlhdlr->exitsepa(scip, nlhdlr, expr, nlhdlrexprdata) );
    617 }
    618
    619 return SCIP_OKAY;
    620}
    621
    622/** call the enforcement callback of a nonlinear handler */
    623SCIP_DECL_NLHDLRENFO(SCIPnlhdlrEnfo)
    624{
    625 assert(scip != NULL);
    626 assert(nlhdlr != NULL);
    627 assert(nlhdlr->enfotime != NULL);
    628 assert(result != NULL);
    629
    630 if( nlhdlr->enfo == NULL )
    631 {
    632 *result = SCIP_DIDNOTRUN;
    633 return SCIP_OKAY;
    634 }
    635
    636#ifndef NDEBUG
    637 /* check that auxvalue is correct by reevaluating */
    638 {
    639 SCIP_Real auxvaluetest;
    640 SCIP_CALL( SCIPnlhdlrEvalaux(scip, nlhdlr, expr, nlhdlrexprdata, &auxvaluetest, sol) );
    641 /* we should get EXACTLY the same value from calling evalaux with the same solution as before */
    642 assert(auxvalue == auxvaluetest); /*lint !e777*/
    643 }
    644#endif
    645
    647 SCIP_CALL( nlhdlr->enfo(scip, conshdlr, cons, nlhdlr, expr, nlhdlrexprdata, sol, auxvalue,
    648 overestimate, allowweakcuts, separated, addbranchscores, branchcandonly, result) );
    650
    651 /* update statistics */
    652 ++nlhdlr->nenfocalls;
    653 switch( *result )
    654 {
    655 case SCIP_SEPARATED :
    656 assert(!branchcandonly);
    657 ++nlhdlr->nseparated;
    658 break;
    659 case SCIP_BRANCHED:
    660 ++nlhdlr->nbranchscores;
    661 break;
    662 case SCIP_CUTOFF:
    663 ++nlhdlr->ncutoffs;
    664 break;
    665 case SCIP_REDUCEDDOM:
    666 assert(!branchcandonly);
    667 ++nlhdlr->ndomreds;
    668 break;
    669 default: ;
    670 } /*lint !e788*/
    671
    672 return SCIP_OKAY;
    673}
    674
    675/** call the estimator callback of a nonlinear handler */
    676SCIP_DECL_NLHDLRESTIMATE(SCIPnlhdlrEstimate)
    677{
    678 assert(scip != NULL);
    679 assert(nlhdlr != NULL);
    680 assert(nlhdlr->enfotime != NULL);
    681 assert(success != NULL);
    682 assert(addedbranchscores != NULL);
    683
    684 if( nlhdlr->estimate == NULL )
    685 {
    686 *success = FALSE;
    687 *addedbranchscores = FALSE;
    688 return SCIP_OKAY;
    689 }
    690
    691#ifndef NDEBUG
    692 /* check that auxvalue is correct by reevaluating */
    693 {
    694 SCIP_Real auxvaluetest;
    695 SCIP_CALL( SCIPnlhdlrEvalaux(scip, nlhdlr, expr, nlhdlrexprdata, &auxvaluetest, sol) );
    696 /* we should get EXACTLY the same value from calling evalaux with the same solution as before */
    697 assert(auxvalue == auxvaluetest); /*lint !e777*/
    698 }
    699#endif
    700
    702 SCIP_CALL( nlhdlr->estimate(scip, conshdlr, nlhdlr, expr, nlhdlrexprdata, sol, auxvalue, overestimate, targetvalue, addbranchscores, rowpreps, success, addedbranchscores) );
    704
    705 /* update statistics */
    706 ++nlhdlr->nenfocalls;
    707
    708 return SCIP_OKAY;
    709}
    710
    711/** call the solution notification callback of a nonlinear handler */
    712SCIP_DECL_NLHDLRSOLLINEARIZE(SCIPnlhdlrSollinearize)
    713{
    714 assert(scip != NULL);
    715 assert(nlhdlr != NULL);
    716
    717 if( nlhdlr->sollinearize == NULL )
    718 return SCIP_OKAY;
    719
    720 SCIP_CALL( nlhdlr->sollinearize(scip, conshdlr, cons, nlhdlr, expr, nlhdlrexprdata, sol, solisbest, overestimate, underestimate) );
    721
    722 return SCIP_OKAY;
    723}
    724
    725/** reset number of detections counter for last round */
    727 SCIP_NLHDLR* nlhdlr /**< nonlinear handler */
    728 )
    729{
    730 assert(nlhdlr != NULL);
    731 nlhdlr->ndetectionslast = 0;
    732}
    733
    734/** increments number of cutoffs in statistics */
    736 SCIP_NLHDLR* nlhdlr /**< nonlinear handler */
    737 )
    738{
    739 assert(nlhdlr != NULL);
    740 ++nlhdlr->ncutoffs;
    741}
    742
    743/** increments number of separations in statistics */
    745 SCIP_NLHDLR* nlhdlr /**< nonlinear handler */
    746 )
    747{
    748 assert(nlhdlr != NULL);
    749 ++nlhdlr->nseparated;
    750}
    751
    752/** print statistics for nonlinear handlers */
    754 SCIP* scip, /**< SCIP data structure */
    755 SCIP_NLHDLR** nlhdlrs, /**< nonlinear handlers */
    756 int nnlhdlrs, /**< number of nonlinear handlers */
    757 FILE* file /**< file handle, or NULL for standard out */
    758 )
    759{
    760 int i;
    761
    762 SCIPinfoMessage(scip, file, "Nlhdlrs : %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s\n",
    763 "Detects", "DetectAll", "DetectTime",
    764 "#IntEval", "IntEvalTi",
    765 "#RevProp", "RevPropTi", "DomReds", "Cutoffs",
    766 "#Enforce", "EnfoTime", "Cuts", "Branching");
    767
    768 for( i = 0; i < nnlhdlrs; ++i )
    769 {
    770 /* skip disabled nlhdlr */
    771 if( !nlhdlrs[i]->enabled )
    772 continue;
    773
    774 SCIPinfoMessage(scip, file, " %-17s:", nlhdlrs[i]->name);
    775 SCIPinfoMessage(scip, file, " %10lld", nlhdlrs[i]->ndetectionslast);
    776 SCIPinfoMessage(scip, file, " %10lld", nlhdlrs[i]->ndetections);
    777 SCIPinfoMessage(scip, file, " %10.2f", SCIPgetClockTime(scip, nlhdlrs[i]->detecttime));
    778
    779 SCIPinfoMessage(scip, file, " %10lld", nlhdlrs[i]->nintevalcalls);
    780 SCIPinfoMessage(scip, file, " %10.2f", SCIPgetClockTime(scip, nlhdlrs[i]->intevaltime));
    781
    782 SCIPinfoMessage(scip, file, " %10lld", nlhdlrs[i]->npropcalls);
    783 SCIPinfoMessage(scip, file, " %10.2f", SCIPgetClockTime(scip, nlhdlrs[i]->proptime));
    784 SCIPinfoMessage(scip, file, " %10lld", nlhdlrs[i]->ndomreds);
    785 SCIPinfoMessage(scip, file, " %10lld", nlhdlrs[i]->ncutoffs);
    786
    787 SCIPinfoMessage(scip, file, " %10lld", nlhdlrs[i]->nenfocalls);
    788 SCIPinfoMessage(scip, file, " %10.2f", SCIPgetClockTime(scip, nlhdlrs[i]->enfotime));
    789 SCIPinfoMessage(scip, file, " %10lld", nlhdlrs[i]->nseparated);
    790 SCIPinfoMessage(scip, file, " %10lld", nlhdlrs[i]->nbranchscores);
    791
    792 SCIPinfoMessage(scip, file, "\n");
    793 }
    794}
    795
    796/** collect statistics for nonlinear handlers */
    798 SCIP* scip, /**< SCIP data structure */
    799 SCIP_NLHDLR** nlhdlrs, /**< nonlinear handlers */
    800 int nnlhdlrs, /**< number of nonlinear handlers */
    801 SCIP_DATATREE* datatree /**< datatree where to add statistics */
    802 )
    803{
    804 SCIP_DATATREE* nlhdlrstree;
    805 int i;
    806
    807 /* create a subtree for Nldhlr statistics */
    808 SCIP_CALL( SCIPcreateDatatreeInTree(scip, datatree, &nlhdlrstree, "plugins", nnlhdlrs) );
    809
    810 for( i = 0; i < nnlhdlrs; ++i )
    811 {
    812 SCIP_DATATREE* nlhdlrstat;
    813
    814 /* skip disabled nlhdlr */
    815 if( !nlhdlrs[i]->enabled )
    816 continue;
    817
    818 SCIP_CALL( SCIPcreateDatatreeInTree(scip, nlhdlrstree, &nlhdlrstat, nlhdlrs[i]->name, 14) );
    819 SCIP_CALL( SCIPinsertDatatreeString(scip, nlhdlrstat, "description", nlhdlrs[i]->desc) );
    820
    821 SCIP_CALL( SCIPinsertDatatreeLong(scip, nlhdlrstat, "ndetects", nlhdlrs[i]->ndetectionslast) );
    822 SCIP_CALL( SCIPinsertDatatreeLong(scip, nlhdlrstat, "ndetectsall", nlhdlrs[i]->ndetections) );
    823 SCIP_CALL( SCIPinsertDatatreeReal(scip, nlhdlrstat, "detecttime", SCIPgetClockTime(scip, nlhdlrs[i]->detecttime)) );
    824
    825 SCIP_CALL( SCIPinsertDatatreeLong(scip, nlhdlrstat, "ninteval", nlhdlrs[i]->nintevalcalls) );
    826 SCIP_CALL( SCIPinsertDatatreeReal(scip, nlhdlrstat, "intevaltime", SCIPgetClockTime(scip, nlhdlrs[i]->intevaltime)) );
    827 SCIP_CALL( SCIPinsertDatatreeLong(scip, nlhdlrstat, "nrevprop", nlhdlrs[i]->npropcalls) );
    828 SCIP_CALL( SCIPinsertDatatreeReal(scip, nlhdlrstat, "revproptime", SCIPgetClockTime(scip, nlhdlrs[i]->proptime)) );
    829 SCIP_CALL( SCIPinsertDatatreeLong(scip, nlhdlrstat, "ndomreds", nlhdlrs[i]->ndomreds) );
    830 SCIP_CALL( SCIPinsertDatatreeLong(scip, nlhdlrstat, "ncutoffs", nlhdlrs[i]->ncutoffs) );
    831
    832 SCIP_CALL( SCIPinsertDatatreeLong(scip, nlhdlrstat, "nenforce", nlhdlrs[i]->nenfocalls) );
    833 SCIP_CALL( SCIPinsertDatatreeReal(scip, nlhdlrstat, "enfotime", SCIPgetClockTime(scip, nlhdlrs[i]->enfotime)) );
    834 SCIP_CALL( SCIPinsertDatatreeLong(scip, nlhdlrstat, "ncuts", nlhdlrs[i]->nseparated) );
    835 SCIP_CALL( SCIPinsertDatatreeLong(scip, nlhdlrstat, "nbranchscores", nlhdlrs[i]->nbranchscores) );
    836 }
    837
    838 return SCIP_OKAY;
    839}
    #define NULL
    Definition: def.h:248
    #define SCIP_MAXSTRLEN
    Definition: def.h:269
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define SCIP_CALL(x)
    Definition: def.h:355
    #define SCIP_CALL_FINALLY(x, y)
    Definition: def.h:397
    void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:208
    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 SCIPcreateDatatreeInTree(SCIP *scip, SCIP_DATATREE *datatree, SCIP_DATATREE **newtree, const char *name, int capacity)
    Definition: scip_datatree.c:61
    SCIP_RETCODE SCIPinsertDatatreeString(SCIP *scip, SCIP_DATATREE *datatree, const char *name, const char *value)
    SCIP_RETCODE SCIPinsertDatatreeLong(SCIP *scip, SCIP_DATATREE *datatree, const char *name, SCIP_Longint value)
    SCIP_RETCODE SCIPinsertDatatreeReal(SCIP *scip, SCIP_DATATREE *datatree, const char *name, SCIP_Real value)
    #define SCIPallocClearBlockMemory(scip, ptr)
    Definition: scip_mem.h:91
    #define SCIPfreeMemoryNull(scip, ptr)
    Definition: scip_mem.h:79
    #define SCIPduplicateMemoryArray(scip, ptr, source, num)
    Definition: scip_mem.h:76
    #define SCIPfreeMemoryArray(scip, ptr)
    Definition: scip_mem.h:80
    #define SCIPfreeMemory(scip, ptr)
    Definition: scip_mem.h:78
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    void SCIPnlhdlrSetCopyHdlr(SCIP_NLHDLR *nlhdlr, SCIP_DECL_NLHDLRCOPYHDLR((*copy)))
    Definition: nlhdlr.c:77
    void SCIPnlhdlrSetFreeExprData(SCIP_NLHDLR *nlhdlr, SCIP_DECL_NLHDLRFREEEXPRDATA((*freeexprdata)))
    Definition: nlhdlr.c:99
    void SCIPnlhdlrSetProp(SCIP_NLHDLR *nlhdlr, SCIP_DECL_NLHDLRINTEVAL((*inteval)), SCIP_DECL_NLHDLRREVERSEPROP((*reverseprop)))
    Definition: nlhdlr.c:124
    const char * SCIPnlhdlrGetDesc(SCIP_NLHDLR *nlhdlr)
    Definition: nlhdlr.c:177
    void SCIPnlhdlrSetSollinearize(SCIP_NLHDLR *nlhdlr, SCIP_DECL_NLHDLRSOLLINEARIZE((*sollinearize)))
    Definition: nlhdlr.c:155
    SCIP_NLHDLRDATA * SCIPnlhdlrGetData(SCIP_NLHDLR *nlhdlr)
    Definition: nlhdlr.c:217
    SCIP_Bool SCIPnlhdlrHasIntEval(SCIP_NLHDLR *nlhdlr)
    Definition: nlhdlr.c:227
    SCIP_Bool SCIPnlhdlrHasEnfo(SCIP_NLHDLR *nlhdlr)
    Definition: nlhdlr.c:267
    int SCIPnlhdlrGetDetectPriority(SCIP_NLHDLR *nlhdlr)
    Definition: nlhdlr.c:187
    void SCIPnlhdlrSetFreeHdlrData(SCIP_NLHDLR *nlhdlr, SCIP_DECL_NLHDLRFREEHDLRDATA((*freehdlrdata)))
    Definition: nlhdlr.c:88
    void SCIPnlhdlrSetSepa(SCIP_NLHDLR *nlhdlr, SCIP_DECL_NLHDLRINITSEPA((*initsepa)), SCIP_DECL_NLHDLRENFO((*enfo)), SCIP_DECL_NLHDLRESTIMATE((*estimate)), SCIP_DECL_NLHDLREXITSEPA((*exitsepa)))
    Definition: nlhdlr.c:137
    SCIP_DECL_SORTPTRCOMP(SCIPnlhdlrComp)
    Definition: nlhdlr.c:300
    void SCIPnlhdlrSetInitExit(SCIP_NLHDLR *nlhdlr, SCIP_DECL_NLHDLRINIT((*init)), SCIP_DECL_NLHDLREXIT((*exit_)))
    Definition: nlhdlr.c:111
    SCIP_Bool SCIPnlhdlrIsEnabled(SCIP_NLHDLR *nlhdlr)
    Definition: nlhdlr.c:207
    SCIP_Bool SCIPnlhdlrHasReverseProp(SCIP_NLHDLR *nlhdlr)
    Definition: nlhdlr.c:237
    const char * SCIPnlhdlrGetName(SCIP_NLHDLR *nlhdlr)
    Definition: nlhdlr.c:167
    SCIP_Bool SCIPnlhdlrHasSollinearize(SCIP_NLHDLR *nlhdlr)
    Definition: nlhdlr.c:287
    SCIP_Bool SCIPnlhdlrHasEstimate(SCIP_NLHDLR *nlhdlr)
    Definition: nlhdlr.c:277
    SCIP_Bool SCIPnlhdlrHasInitSepa(SCIP_NLHDLR *nlhdlr)
    Definition: nlhdlr.c:247
    int SCIPnlhdlrGetEnfoPriority(SCIP_NLHDLR *nlhdlr)
    Definition: nlhdlr.c:197
    SCIP_Bool SCIPnlhdlrHasExitSepa(SCIP_NLHDLR *nlhdlr)
    Definition: nlhdlr.c:257
    SCIP_RETCODE SCIPcreateClock(SCIP *scip, SCIP_CLOCK **clck)
    Definition: scip_timing.c:76
    SCIP_RETCODE SCIPresetClock(SCIP *scip, SCIP_CLOCK *clck)
    Definition: scip_timing.c:144
    SCIP_RETCODE SCIPstopClock(SCIP *scip, SCIP_CLOCK *clck)
    Definition: scip_timing.c:178
    SCIP_RETCODE SCIPfreeClock(SCIP *scip, SCIP_CLOCK **clck)
    Definition: scip_timing.c:127
    SCIP_Real SCIPgetClockTime(SCIP *scip, SCIP_CLOCK *clck)
    Definition: scip_timing.c:319
    SCIP_RETCODE SCIPstartClock(SCIP *scip, SCIP_CLOCK *clck)
    Definition: scip_timing.c:161
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    static const char * paramname[]
    Definition: lpi_msk.c:5172
    SCIP_RETCODE SCIPnlhdlrFree(SCIP *scip, SCIP_NLHDLR **nlhdlr)
    Definition: nlhdlr.c:402
    SCIP_DECL_NLHDLRDETECT(SCIPnlhdlrDetect)
    Definition: nlhdlr.c:499
    SCIP_DECL_NLHDLRINITSEPA(SCIPnlhdlrInitsepa)
    Definition: nlhdlr.c:581
    SCIP_RETCODE SCIPnlhdlrCreate(SCIP *scip, SCIP_NLHDLR **nlhdlr, const char *name, const char *desc, int detectpriority, int enfopriority, SCIP_DECL_NLHDLRDETECT((*detect)), SCIP_DECL_NLHDLREVALAUX((*evalaux)), SCIP_NLHDLRDATA *nlhdlrdata)
    Definition: nlhdlr.c:354
    SCIP_DECL_NLHDLRINIT(SCIPnlhdlrInit)
    Definition: nlhdlr.c:458
    SCIP_DECL_NLHDLRCOPYHDLR(SCIPnlhdlrCopyhdlr)
    Definition: nlhdlr.c:430
    SCIP_DECL_NLHDLRINTEVAL(SCIPnlhdlrInteval)
    Definition: nlhdlr.c:532
    SCIP_DECL_NLHDLRSOLLINEARIZE(SCIPnlhdlrSollinearize)
    Definition: nlhdlr.c:712
    SCIP_DECL_NLHDLREVALAUX(SCIPnlhdlrEvalaux)
    Definition: nlhdlr.c:521
    void SCIPnlhdlrPrintStatistics(SCIP *scip, SCIP_NLHDLR **nlhdlrs, int nnlhdlrs, FILE *file)
    Definition: nlhdlr.c:753
    SCIP_RETCODE SCIPnlhdlrCollectStatistics(SCIP *scip, SCIP_NLHDLR **nlhdlrs, int nnlhdlrs, SCIP_DATATREE *datatree)
    Definition: nlhdlr.c:797
    SCIP_DECL_NLHDLRESTIMATE(SCIPnlhdlrEstimate)
    Definition: nlhdlr.c:676
    SCIP_DECL_NLHDLRREVERSEPROP(SCIPnlhdlrReverseprop)
    Definition: nlhdlr.c:551
    void SCIPnlhdlrResetNDetectionslast(SCIP_NLHDLR *nlhdlr)
    Definition: nlhdlr.c:726
    SCIP_DECL_NLHDLRFREEEXPRDATA(SCIPnlhdlrFreeexprdata)
    Definition: nlhdlr.c:442
    SCIP_DECL_NLHDLREXIT(SCIPnlhdlrExit)
    Definition: nlhdlr.c:486
    SCIP_DECL_NLHDLRENFO(SCIPnlhdlrEnfo)
    Definition: nlhdlr.c:623
    SCIP_DECL_NLHDLREXITSEPA(SCIPnlhdlrExitsepa)
    Definition: nlhdlr.c:606
    void SCIPnlhdlrIncrementNCutoffs(SCIP_NLHDLR *nlhdlr)
    Definition: nlhdlr.c:735
    void SCIPnlhdlrIncrementNSeparated(SCIP_NLHDLR *nlhdlr)
    Definition: nlhdlr.c:744
    private functions of nonlinear handlers of nonlinear constraints
    public methods for message output
    public data structures and miscellaneous methods
    public functions of nonlinear handlers of nonlinear constraints
    public methods for data tree structure
    public methods for memory management
    public methods for message handling
    public methods for SCIP parameter handling
    public methods for timing
    SCIP_Longint ndetections
    Definition: struct_nlhdlr.h:76
    SCIP_CLOCK * proptime
    Definition: struct_nlhdlr.h:82
    SCIP_CLOCK * detecttime
    Definition: struct_nlhdlr.h:80
    SCIP_Bool enabled
    Definition: struct_nlhdlr.h:51
    SCIP_Longint npropcalls
    Definition: struct_nlhdlr.h:72
    SCIP_CLOCK * enfotime
    Definition: struct_nlhdlr.h:81
    SCIP_CLOCK * intevaltime
    Definition: struct_nlhdlr.h:83
    SCIP_NLHDLRDATA * data
    Definition: struct_nlhdlr.h:47
    SCIP_Longint ndetectionslast
    Definition: struct_nlhdlr.h:77
    SCIP_Longint ncutoffs
    Definition: struct_nlhdlr.h:74
    int detectpriority
    Definition: struct_nlhdlr.h:49
    SCIP_Longint nseparated
    Definition: struct_nlhdlr.h:73
    SCIP_Longint nenfocalls
    Definition: struct_nlhdlr.h:70
    SCIP_Longint ndomreds
    Definition: struct_nlhdlr.h:75
    SCIP_Longint nintevalcalls
    Definition: struct_nlhdlr.h:71
    SCIP_Longint nbranchscores
    Definition: struct_nlhdlr.h:78
    structure definitions related to nonlinear handlers of nonlinear constraints
    struct SCIP_NlhdlrData SCIP_NLHDLRDATA
    Definition: type_nlhdlr.h:452
    #define SCIP_NLHDLR_METHOD_NONE
    Definition: type_nlhdlr.h:50
    #define SCIP_DECL_NLHDLRFREEHDLRDATA(x)
    Definition: type_nlhdlr.h:82
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ SCIP_REDUCEDDOM
    Definition: type_result.h:51
    @ SCIP_BRANCHED
    Definition: type_result.h:54
    @ SCIP_SEPARATED
    Definition: type_result.h:49
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63