SCIP Doxygen Documentation
Loading...
Searching...
No Matches
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-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 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 {
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 if( nnlhdlrs == 0 )
808 return SCIP_OKAY;
809
810 /* create a subtree for Nldhlr statistics */
811 SCIP_CALL( SCIPcreateDatatreeInTree(scip, datatree, &nlhdlrstree, "plugins", nnlhdlrs) );
812
813 for( i = 0; i < nnlhdlrs; ++i )
814 {
815 SCIP_DATATREE* nlhdlrstat;
816
817 /* skip disabled nlhdlr */
818 if( !nlhdlrs[i]->enabled )
819 continue;
820
821 SCIP_CALL( SCIPcreateDatatreeInTree(scip, nlhdlrstree, &nlhdlrstat, nlhdlrs[i]->name, 14) );
822 SCIP_CALL( SCIPinsertDatatreeString(scip, nlhdlrstat, "description", nlhdlrs[i]->desc) );
823
824 SCIP_CALL( SCIPinsertDatatreeLong(scip, nlhdlrstat, "ndetects", nlhdlrs[i]->ndetectionslast) );
825 SCIP_CALL( SCIPinsertDatatreeLong(scip, nlhdlrstat, "ndetectsall", nlhdlrs[i]->ndetections) );
826 SCIP_CALL( SCIPinsertDatatreeReal(scip, nlhdlrstat, "detecttime", SCIPgetClockTime(scip, nlhdlrs[i]->detecttime)) );
827
828 SCIP_CALL( SCIPinsertDatatreeLong(scip, nlhdlrstat, "ninteval", nlhdlrs[i]->nintevalcalls) );
829 SCIP_CALL( SCIPinsertDatatreeReal(scip, nlhdlrstat, "intevaltime", SCIPgetClockTime(scip, nlhdlrs[i]->intevaltime)) );
830 SCIP_CALL( SCIPinsertDatatreeLong(scip, nlhdlrstat, "nrevprop", nlhdlrs[i]->npropcalls) );
831 SCIP_CALL( SCIPinsertDatatreeReal(scip, nlhdlrstat, "revproptime", SCIPgetClockTime(scip, nlhdlrs[i]->proptime)) );
832 SCIP_CALL( SCIPinsertDatatreeLong(scip, nlhdlrstat, "ndomreds", nlhdlrs[i]->ndomreds) );
833 SCIP_CALL( SCIPinsertDatatreeLong(scip, nlhdlrstat, "ncutoffs", nlhdlrs[i]->ncutoffs) );
834
835 SCIP_CALL( SCIPinsertDatatreeLong(scip, nlhdlrstat, "nenforce", nlhdlrs[i]->nenfocalls) );
836 SCIP_CALL( SCIPinsertDatatreeReal(scip, nlhdlrstat, "enfotime", SCIPgetClockTime(scip, nlhdlrs[i]->enfotime)) );
837 SCIP_CALL( SCIPinsertDatatreeLong(scip, nlhdlrstat, "ncuts", nlhdlrs[i]->nseparated) );
838 SCIP_CALL( SCIPinsertDatatreeLong(scip, nlhdlrstat, "nbranchscores", nlhdlrs[i]->nbranchscores) );
839 }
840
841 return SCIP_OKAY;
842}
#define NULL
Definition def.h:255
#define SCIP_MAXSTRLEN
Definition def.h:276
#define SCIP_Bool
Definition def.h:98
#define SCIP_Real
Definition def.h:163
#define TRUE
Definition def.h:100
#define FALSE
Definition def.h:101
#define SCIP_CALL(x)
Definition def.h:362
#define SCIP_CALL_FINALLY(x, y)
Definition def.h:404
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
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)
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 SCIPnlhdlrSetInitExit(SCIP_NLHDLR *nlhdlr, SCIP_DECL_NLHDLRINIT((*init)),)
Definition nlhdlr.c:111
const char * SCIPnlhdlrGetDesc(SCIP_NLHDLR *nlhdlr)
Definition nlhdlr.c:177
SCIP_NLHDLRDATA * SCIPnlhdlrGetData(SCIP_NLHDLR *nlhdlr)
Definition nlhdlr.c:217
void SCIPnlhdlrSetFreeExprData(SCIP_NLHDLR *nlhdlr,)
Definition nlhdlr.c:99
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
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
void SCIPnlhdlrSetSollinearize(SCIP_NLHDLR *nlhdlr,)
Definition nlhdlr.c:155
SCIP_Bool SCIPnlhdlrHasEstimate(SCIP_NLHDLR *nlhdlr)
Definition nlhdlr.c:277
void SCIPnlhdlrSetSepa(SCIP_NLHDLR *nlhdlr, SCIP_DECL_NLHDLRINITSEPA((*initsepa)), SCIP_DECL_NLHDLRENFO((*enfo)), SCIP_DECL_NLHDLRESTIMATE((*estimate)),)
Definition nlhdlr.c:137
void SCIPnlhdlrSetFreeHdlrData(SCIP_NLHDLR *nlhdlr,)
Definition nlhdlr.c:88
void SCIPnlhdlrSetCopyHdlr(SCIP_NLHDLR *nlhdlr,)
Definition nlhdlr.c:77
SCIP_Bool SCIPnlhdlrHasInitSepa(SCIP_NLHDLR *nlhdlr)
Definition nlhdlr.c:247
int SCIPnlhdlrGetEnfoPriority(SCIP_NLHDLR *nlhdlr)
Definition nlhdlr.c:197
void SCIPnlhdlrSetProp(SCIP_NLHDLR *nlhdlr, SCIP_DECL_NLHDLRINTEVAL((*inteval)),)
Definition nlhdlr.c:124
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)
SCIP_RETCODE SCIPstopClock(SCIP *scip, SCIP_CLOCK *clck)
SCIP_RETCODE SCIPfreeClock(SCIP *scip, SCIP_CLOCK **clck)
SCIP_Real SCIPgetClockTime(SCIP *scip, SCIP_CLOCK *clck)
SCIP_RETCODE SCIPstartClock(SCIP *scip, SCIP_CLOCK *clck)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition misc.c:10827
return SCIP_OKAY
static SCIP_SOL * sol
assert(minobj< SCIPgetCutoffbound(scip))
static const char * paramname[]
Definition lpi_msk.c:5172
SCIP_RETCODE SCIPnlhdlrFree(SCIP *scip, SCIP_NLHDLR **nlhdlr)
Definition nlhdlr.c:402
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
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
private functions of nonlinear handlers of nonlinear constraints
#define SCIPnlhdlrIncrementNSeparated(nlhdlr)
Definition nlhdlr.h:140
#define SCIPnlhdlrResetNDetectionslast(nlhdlr)
Definition nlhdlr.h:138
#define SCIPnlhdlrIncrementNCutoffs(nlhdlr)
Definition nlhdlr.h:139
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
SCIP_CLOCK * proptime
SCIP_CLOCK * detecttime
SCIP_Bool enabled
SCIP_Longint npropcalls
SCIP_CLOCK * enfotime
SCIP_CLOCK * intevaltime
SCIP_NLHDLRDATA * data
SCIP_Longint ndetectionslast
SCIP_Longint ncutoffs
SCIP_Longint nseparated
SCIP_Longint nenfocalls
SCIP_Longint ndomreds
SCIP_Longint nintevalcalls
SCIP_Longint nbranchscores
structure definitions related to nonlinear handlers of nonlinear constraints
struct SCIP_Datatree SCIP_DATATREE
#define SCIP_DECL_SORTPTRCOMP(x)
Definition type_misc.h:189
#define SCIP_DECL_NLHDLREVALAUX(x)
#define SCIP_DECL_NLHDLRESTIMATE(x)
struct SCIP_NlhdlrData SCIP_NLHDLRDATA
#define SCIP_DECL_NLHDLRCOPYHDLR(x)
Definition type_nlhdlr.h:70
#define SCIP_DECL_NLHDLRINIT(x)
#define SCIP_DECL_NLHDLRSOLLINEARIZE(x)
#define SCIP_DECL_NLHDLREXIT(x)
#define SCIP_DECL_NLHDLRFREEEXPRDATA(x)
Definition type_nlhdlr.h:94
#define SCIP_DECL_NLHDLRDETECT(x)
#define SCIP_NLHDLR_METHOD_NONE
Definition type_nlhdlr.h:50
#define SCIP_DECL_NLHDLREXITSEPA(x)
struct SCIP_Nlhdlr SCIP_NLHDLR
#define SCIP_DECL_NLHDLRINITSEPA(x)
#define SCIP_DECL_NLHDLRFREEHDLRDATA(x)
Definition type_nlhdlr.h:82
#define SCIP_DECL_NLHDLRREVERSEPROP(x)
#define SCIP_DECL_NLHDLRENFO(x)
#define SCIP_DECL_NLHDLRINTEVAL(x)
@ 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
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39