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