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