Scippy

SCIP

Solving Constraint Integer Programs

scip_nonlinear.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-2018 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 scip_nonlinear.c
17  * @brief public methods for nonlinear functions
18  * @author Tobias Achterberg
19  * @author Timo Berthold
20  * @author Gerald Gamrath
21  * @author Robert Lion Gottwald
22  * @author Stefan Heinz
23  * @author Gregor Hendel
24  * @author Thorsten Koch
25  * @author Alexander Martin
26  * @author Marc Pfetsch
27  * @author Michael Winkler
28  * @author Kati Wolter
29  *
30  * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
31  */
32 
33 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
34 
35 #include <ctype.h>
36 #include <stdarg.h>
37 #include <assert.h>
38 #include <string.h>
39 #if defined(_WIN32) || defined(_WIN64)
40 #else
41 #include <strings.h> /*lint --e{766}*/
42 #endif
43 
44 
45 #include "lpi/lpi.h"
46 #include "nlpi/exprinterpret.h"
47 #include "nlpi/nlpi.h"
48 #include "scip/benders.h"
49 #include "scip/benderscut.h"
50 #include "scip/branch.h"
51 #include "scip/branch_nodereopt.h"
52 #include "scip/clock.h"
53 #include "scip/compr.h"
54 #include "scip/concsolver.h"
55 #include "scip/concurrent.h"
56 #include "scip/conflict.h"
57 #include "scip/conflictstore.h"
58 #include "scip/cons.h"
59 #include "scip/cons_linear.h"
60 #include "scip/cutpool.h"
61 #include "scip/cuts.h"
62 #include "scip/debug.h"
63 #include "scip/def.h"
64 #include "scip/dialog.h"
65 #include "scip/dialog_default.h"
66 #include "scip/disp.h"
67 #include "scip/event.h"
68 #include "scip/heur.h"
69 #include "scip/heur_ofins.h"
70 #include "scip/heur_reoptsols.h"
72 #include "scip/heuristics.h"
73 #include "scip/history.h"
74 #include "scip/implics.h"
75 #include "scip/interrupt.h"
76 #include "scip/lp.h"
77 #include "scip/mem.h"
78 #include "scip/message_default.h"
79 #include "scip/misc.h"
80 #include "scip/nlp.h"
81 #include "scip/nodesel.h"
82 #include "scip/paramset.h"
83 #include "scip/presol.h"
84 #include "scip/presolve.h"
85 #include "scip/pricer.h"
86 #include "scip/pricestore.h"
87 #include "scip/primal.h"
88 #include "scip/prob.h"
89 #include "scip/prop.h"
90 #include "scip/reader.h"
91 #include "scip/relax.h"
92 #include "scip/reopt.h"
93 #include "scip/retcode.h"
94 #include "scip/scipbuildflags.h"
95 #include "scip/scipcoreplugins.h"
96 #include "scip/scipgithash.h"
97 #include "scip/sepa.h"
98 #include "scip/sepastore.h"
99 #include "scip/set.h"
100 #include "scip/sol.h"
101 #include "scip/solve.h"
102 #include "scip/stat.h"
103 #include "scip/syncstore.h"
104 #include "scip/table.h"
105 #include "scip/tree.h"
106 #include "scip/var.h"
107 #include "scip/visual.h"
108 #include "xml/xml.h"
109 
110 #include "scip/scip_mem.h"
111 #include "scip/scip_message.h"
112 #include "scip/scip_nonlinear.h"
113 #include "scip/scip_numerics.h"
114 #include "scip/scip_prob.h"
115 
116 #include "scip/pub_lp.h"
117 #include "scip/pub_message.h"
118 #include "scip/pub_misc.h"
119 #include "scip/pub_nlp.h"
120 #include "scip/pub_var.h"
121 
122 
123 /* In debug mode, we include the SCIP's structure in scip.c, such that no one can access
124  * this structure except the interface methods in scip.c.
125  * In optimized mode, the structure is included in scip.h, because some of the methods
126  * are implemented as defines for performance reasons (e.g. the numerical comparisons)
127  */
128 #ifndef NDEBUG
129 #include "scip/struct_scip.h"
130 #endif
131 
132 /** computes coefficients of linearization of a square term in a reference point */
134  SCIP* scip, /**< SCIP data structure */
135  SCIP_Real sqrcoef, /**< coefficient of square term */
136  SCIP_Real refpoint, /**< point where to linearize */
137  SCIP_Bool isint, /**< whether corresponding variable is a discrete variable, and thus linearization could be moved */
138  SCIP_Real* lincoef, /**< buffer to add coefficient of linearization */
139  SCIP_Real* linconstant, /**< buffer to add constant of linearization */
140  SCIP_Bool* success /**< buffer to set to FALSE if linearization has failed due to large numbers */
141  )
142 {
143  assert(scip != NULL);
144  assert(lincoef != NULL);
145  assert(linconstant != NULL);
146  assert(success != NULL);
147 
148  if( sqrcoef == 0.0 )
149  return;
150 
151  if( SCIPisInfinity(scip, REALABS(refpoint)) )
152  {
153  *success = FALSE;
154  return;
155  }
156 
157  if( !isint || SCIPisIntegral(scip, refpoint) )
158  {
159  SCIP_Real tmp;
160 
161  /* sqrcoef * x^2 -> tangent in refpoint = sqrcoef * 2 * refpoint * (x - refpoint) */
162 
163  tmp = sqrcoef * refpoint;
164 
165  if( SCIPisInfinity(scip, 2.0 * REALABS(tmp)) )
166  {
167  *success = FALSE;
168  return;
169  }
170 
171  *lincoef += 2.0 * tmp;
172  tmp *= refpoint;
173  *linconstant -= tmp;
174  }
175  else
176  {
177  /* sqrcoef * x^2 -> secant between f=floor(refpoint) and f+1 = sqrcoef * (f^2 + ((f+1)^2 - f^2) * (x-f))
178  * = sqrcoef * (-f*(f+1) + (2*f+1)*x)
179  */
180  SCIP_Real f;
181  SCIP_Real coef;
182  SCIP_Real constant;
183 
184  f = SCIPfloor(scip, refpoint);
185 
186  coef = sqrcoef * (2.0 * f + 1.0);
187  constant = -sqrcoef * f * (f + 1.0);
188 
189  if( SCIPisInfinity(scip, REALABS(coef)) || SCIPisInfinity(scip, REALABS(constant)) )
190  {
191  *success = FALSE;
192  return;
193  }
194 
195  *lincoef += coef;
196  *linconstant += constant;
197  }
198 }
199 
200 /** computes coefficients of secant of a square term */
202  SCIP* scip, /**< SCIP data structure */
203  SCIP_Real sqrcoef, /**< coefficient of square term */
204  SCIP_Real lb, /**< lower bound on variable */
205  SCIP_Real ub, /**< upper bound on variable */
206  SCIP_Real refpoint, /**< point for which to compute value of linearization */
207  SCIP_Real* lincoef, /**< buffer to add coefficient of secant */
208  SCIP_Real* linconstant, /**< buffer to add constant of secant */
209  SCIP_Bool* success /**< buffer to set to FALSE if secant has failed due to large numbers or unboundedness */
210  )
211 {
212  SCIP_Real coef;
213  SCIP_Real constant;
214 
215  assert(scip != NULL);
216  assert(!SCIPisInfinity(scip, lb));
217  assert(!SCIPisInfinity(scip, -ub));
218  assert(SCIPisLE(scip, lb, ub));
219  assert(SCIPisLE(scip, lb, refpoint));
220  assert(SCIPisGE(scip, ub, refpoint));
221  assert(lincoef != NULL);
222  assert(linconstant != NULL);
223  assert(success != NULL);
224 
225  if( sqrcoef == 0.0 )
226  return;
227 
228  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
229  {
230  /* unboundedness */
231  *success = FALSE;
232  return;
233  }
234 
235  /* sqrcoef * x^2 -> sqrcoef * (lb * lb + (ub*ub - lb*lb)/(ub-lb) * (x-lb)) = sqrcoef * (lb*lb + (ub+lb)*(x-lb))
236  * = sqrcoef * ((lb+ub)*x - lb*ub)
237  */
238  coef = sqrcoef * (lb + ub);
239  constant = -sqrcoef * lb * ub;
240  if( SCIPisInfinity(scip, REALABS(coef)) || SCIPisInfinity(scip, REALABS(constant)) )
241  {
242  *success = FALSE;
243  return;
244  }
245 
246  *lincoef += coef;
247  *linconstant += constant;
248 }
249 
250 /** computes coefficients of linearization of a bilinear term in a reference point */
252  SCIP* scip, /**< SCIP data structure */
253  SCIP_Real bilincoef, /**< coefficient of bilinear term */
254  SCIP_Real refpointx, /**< point where to linearize first variable */
255  SCIP_Real refpointy, /**< point where to linearize second variable */
256  SCIP_Real* lincoefx, /**< buffer to add coefficient of first variable in linearization */
257  SCIP_Real* lincoefy, /**< buffer to add coefficient of second variable in linearization */
258  SCIP_Real* linconstant, /**< buffer to add constant of linearization */
259  SCIP_Bool* success /**< buffer to set to FALSE if linearization has failed due to large numbers */
260  )
261 {
262  SCIP_Real constant;
263 
264  assert(scip != NULL);
265  assert(lincoefx != NULL);
266  assert(lincoefy != NULL);
267  assert(linconstant != NULL);
268  assert(success != NULL);
269 
270  if( bilincoef == 0.0 )
271  return;
272 
273  if( SCIPisInfinity(scip, REALABS(refpointx)) || SCIPisInfinity(scip, REALABS(refpointy)) )
274  {
275  *success = FALSE;
276  return;
277  }
278 
279  /* bilincoef * x * y -> bilincoef * (refpointx * refpointy + refpointy * (x - refpointx) + refpointx * (y - refpointy))
280  * = -bilincoef * refpointx * refpointy + bilincoef * refpointy * x + bilincoef * refpointx * y
281  */
282 
283  constant = -bilincoef * refpointx * refpointy;
284 
285  if( SCIPisInfinity(scip, REALABS(bilincoef * refpointx)) || SCIPisInfinity(scip, REALABS(bilincoef * refpointy))
286  || SCIPisInfinity(scip, REALABS(constant)) )
287  {
288  *success = FALSE;
289  return;
290  }
291 
292  *lincoefx += bilincoef * refpointy;
293  *lincoefy += bilincoef * refpointx;
294  *linconstant += constant;
295 }
296 
297 /** computes coefficients of McCormick under- or overestimation of a bilinear term */
299  SCIP* scip, /**< SCIP data structure */
300  SCIP_Real bilincoef, /**< coefficient of bilinear term */
301  SCIP_Real lbx, /**< lower bound on first variable */
302  SCIP_Real ubx, /**< upper bound on first variable */
303  SCIP_Real refpointx, /**< reference point for first variable */
304  SCIP_Real lby, /**< lower bound on second variable */
305  SCIP_Real uby, /**< upper bound on second variable */
306  SCIP_Real refpointy, /**< reference point for second variable */
307  SCIP_Bool overestimate, /**< whether to compute an overestimator instead of an underestimator */
308  SCIP_Real* lincoefx, /**< buffer to add coefficient of first variable in linearization */
309  SCIP_Real* lincoefy, /**< buffer to add coefficient of second variable in linearization */
310  SCIP_Real* linconstant, /**< buffer to add constant of linearization */
311  SCIP_Bool* success /**< buffer to set to FALSE if linearization has failed due to large numbers */
312  )
313 {
314  SCIP_Real constant;
315  SCIP_Real coefx;
316  SCIP_Real coefy;
317 
318  assert(scip != NULL);
319  assert(!SCIPisInfinity(scip, lbx));
320  assert(!SCIPisInfinity(scip, -ubx));
321  assert(!SCIPisInfinity(scip, lby));
322  assert(!SCIPisInfinity(scip, -uby));
323  assert(SCIPisLE(scip, lbx, ubx));
324  assert(SCIPisLE(scip, lby, uby));
325  assert(SCIPisLE(scip, lbx, refpointx));
326  assert(SCIPisGE(scip, ubx, refpointx));
327  assert(SCIPisLE(scip, lby, refpointy));
328  assert(SCIPisGE(scip, uby, refpointy));
329  assert(lincoefx != NULL);
330  assert(lincoefy != NULL);
331  assert(linconstant != NULL);
332  assert(success != NULL);
333 
334  if( bilincoef == 0.0 )
335  return;
336 
337  if( overestimate )
338  bilincoef = -bilincoef;
339 
340  if( SCIPisRelEQ(scip, lbx, ubx) && SCIPisRelEQ(scip, lby, uby) )
341  {
342  /* both x and y are mostly fixed */
343  SCIP_Real cand1;
344  SCIP_Real cand2;
345  SCIP_Real cand3;
346  SCIP_Real cand4;
347 
348  coefx = 0.0;
349  coefy = 0.0;
350 
351  /* estimate x * y by constant */
352  cand1 = lbx * lby;
353  cand2 = lbx * uby;
354  cand3 = ubx * lby;
355  cand4 = ubx * uby;
356 
357  /* take most conservative value for underestimator */
358  if( bilincoef < 0.0 )
359  constant = bilincoef * MAX( MAX(cand1, cand2), MAX(cand3, cand4) );
360  else
361  constant = bilincoef * MIN( MIN(cand1, cand2), MIN(cand3, cand4) );
362  }
363  else if( bilincoef > 0.0 )
364  {
365  /* either x or y is not fixed and coef > 0.0 */
366  if( !SCIPisInfinity(scip, -lbx) && !SCIPisInfinity(scip, -lby) &&
367  (SCIPisInfinity(scip, ubx) || SCIPisInfinity(scip, uby)
368  || (uby - refpointy) * (ubx - refpointx) >= (refpointy - lby) * (refpointx - lbx)) )
369  {
370  if( SCIPisRelEQ(scip, lbx, ubx) )
371  {
372  /* x*y = lbx * y + (x-lbx) * y >= lbx * y + (x-lbx) * lby >= lbx * y + min{(ubx-lbx) * lby, 0 * lby} */
373  coefx = 0.0;
374  coefy = bilincoef * lbx;
375  constant = bilincoef * (lby < 0.0 ? (ubx-lbx) * lby : 0.0);
376  }
377  else if( SCIPisRelEQ(scip, lby, uby) )
378  {
379  /* x*y = lby * x + (y-lby) * x >= lby * x + (y-lby) * lbx >= lby * x + min{(uby-lby) * lbx, 0 * lbx} */
380  coefx = bilincoef * lby;
381  coefy = 0.0;
382  constant = bilincoef * (lbx < 0.0 ? (uby-lby) * lbx : 0.0);
383  }
384  else
385  {
386  coefx = bilincoef * lby;
387  coefy = bilincoef * lbx;
388  constant = -bilincoef * lbx * lby;
389  }
390  }
391  else if( !SCIPisInfinity(scip, ubx) && !SCIPisInfinity(scip, uby) )
392  {
393  if( SCIPisRelEQ(scip, lbx, ubx) )
394  {
395  /* x*y = ubx * y + (x-ubx) * y >= ubx * y + (x-ubx) * uby >= ubx * y + min{(lbx-ubx) * uby, 0 * uby} */
396  coefx = 0.0;
397  coefy = bilincoef * ubx;
398  constant = bilincoef * (uby > 0.0 ? (lbx - ubx) * uby : 0.0);
399  }
400  else if( SCIPisRelEQ(scip, lby, uby) )
401  {
402  /* x*y = uby * x + (y-uby) * x >= uby * x + (y-uby) * ubx >= uby * x + min{(lby-uby) * ubx, 0 * ubx} */
403  coefx = bilincoef * uby;
404  coefy = 0.0;
405  constant = bilincoef * (ubx > 0.0 ? (lby - uby) * ubx : 0.0);
406  }
407  else
408  {
409  coefx = bilincoef * uby;
410  coefy = bilincoef * ubx;
411  constant = -bilincoef * ubx * uby;
412  }
413  }
414  else
415  {
416  *success = FALSE;
417  return;
418  }
419  }
420  else
421  {
422  /* either x or y is not fixed and coef < 0.0 */
423  if( !SCIPisInfinity(scip, ubx) && !SCIPisInfinity(scip, -lby) &&
424  (SCIPisInfinity(scip, -lbx) || SCIPisInfinity(scip, uby)
425  || (ubx - lbx) * (refpointy - lby) <= (uby - lby) * (refpointx - lbx)) )
426  {
427  if( SCIPisRelEQ(scip, lbx, ubx) )
428  {
429  /* x*y = ubx * y + (x-ubx) * y <= ubx * y + (x-ubx) * lby <= ubx * y + max{(lbx-ubx) * lby, 0 * lby} */
430  coefx = 0.0;
431  coefy = bilincoef * ubx;
432  constant = bilincoef * (lby < 0.0 ? (lbx - ubx) * lby : 0.0);
433  }
434  else if( SCIPisRelEQ(scip, lby, uby) )
435  {
436  /* x*y = lby * x + (y-lby) * x <= lby * x + (y-lby) * ubx <= lby * x + max{(uby-lby) * ubx, 0 * ubx} */
437  coefx = bilincoef * lby;
438  coefy = 0.0;
439  constant = bilincoef * (ubx > 0.0 ? (uby - lby) * ubx : 0.0);
440  }
441  else
442  {
443  coefx = bilincoef * lby;
444  coefy = bilincoef * ubx;
445  constant = -bilincoef * ubx * lby;
446  }
447  }
448  else if( !SCIPisInfinity(scip, -lbx) && !SCIPisInfinity(scip, uby) )
449  {
450  if( SCIPisRelEQ(scip, lbx, ubx) )
451  {
452  /* x*y = lbx * y + (x-lbx) * y <= lbx * y + (x-lbx) * uby <= lbx * y + max{(ubx-lbx) * uby, 0 * uby} */
453  coefx = 0.0;
454  coefy = bilincoef * lbx;
455  constant = bilincoef * (uby > 0.0 ? (ubx - lbx) * uby : 0.0);
456  }
457  else if( SCIPisRelEQ(scip, lby, uby) )
458  {
459  /* x*y = uby * x + (y-uby) * x <= uby * x + (y-uby) * lbx <= uby * x + max{(lby-uby) * lbx, 0 * lbx} */
460  coefx = bilincoef * uby;
461  coefy = 0.0;
462  constant = bilincoef * (lbx < 0.0 ? (lby - uby) * lbx : 0.0);
463  }
464  else
465  {
466  coefx = bilincoef * uby;
467  coefy = bilincoef * lbx;
468  constant = -bilincoef * lbx * uby;
469  }
470  }
471  else
472  {
473  *success = FALSE;
474  return;
475  }
476  }
477 
478  if( SCIPisInfinity(scip, REALABS(coefx)) || SCIPisInfinity(scip, REALABS(coefy))
479  || SCIPisInfinity(scip, REALABS(constant)) )
480  {
481  *success = FALSE;
482  return;
483  }
484 
485  if( overestimate )
486  {
487  coefx = -coefx;
488  coefy = -coefy;
489  constant = -constant;
490  }
491 
492  SCIPdebugMsg(scip, "%.20g * x[%.20g,%.20g] * y[%.20g,%.20g] %c= %.20g * x %+.20g * y %+.20g\n", bilincoef, lbx, ubx,
493  lby, uby, overestimate ? '<' : '>', coefx, coefy, constant);
494 
495  *lincoefx += coefx;
496  *lincoefy += coefy;
497  *linconstant += constant;
498 }
499 
500 
501 /** computes coefficients of linearization of a bilinear term in a reference point when given a linear inequality
502  * involving only the variables of the bilinear term
503  *
504  * @note the formulas are extracted from "Convex envelopes of bivariate functions through the solution of KKT systems"
505  * by Marco Locatelli
506  */
508  SCIP* scip, /**< SCIP data structure */
509  SCIP_Real bilincoef, /**< coefficient of bilinear term */
510  SCIP_Real lbx, /**< lower bound on first variable */
511  SCIP_Real ubx, /**< upper bound on first variable */
512  SCIP_Real refpointx, /**< reference point for first variable */
513  SCIP_Real lby, /**< lower bound on second variable */
514  SCIP_Real uby, /**< upper bound on second variable */
515  SCIP_Real refpointy, /**< reference point for second variable */
516  SCIP_Bool overestimate, /**< whether to compute an overestimator instead of an underestimator */
517  SCIP_Real xcoef, /**< x coefficient of linear inequality; must be in {-1,0,1} */
518  SCIP_Real ycoef, /**< y coefficient of linear inequality */
519  SCIP_Real constant, /**< constant of linear inequality */
520  SCIP_Real* RESTRICT lincoefx, /**< buffer to store coefficient of first variable in linearization */
521  SCIP_Real* RESTRICT lincoefy, /**< buffer to store coefficient of second variable in linearization */
522  SCIP_Real* RESTRICT linconstant, /**< buffer to store constant of linearization */
523  SCIP_Bool* RESTRICT success /**< buffer to store whether linearization was successful */
524  )
525 {
526  SCIP_Real xs[2] = {lbx, ubx};
527  SCIP_Real ys[2] = {lby, uby};
528  SCIP_Real minx;
529  SCIP_Real maxx;
530  SCIP_Real miny;
531  SCIP_Real maxy;
532  SCIP_Real tmp;
533  SCIP_Real mj;
534  SCIP_Real qj;
535  SCIP_Real xj;
536  SCIP_Real yj;
537  SCIP_Real vx;
538  SCIP_Real vy;
539  int n;
540  int i;
541 
542  assert(scip != NULL);
543  assert(!SCIPisInfinity(scip, lbx));
544  assert(!SCIPisInfinity(scip, -ubx));
545  assert(!SCIPisInfinity(scip, lby));
546  assert(!SCIPisInfinity(scip, -uby));
547  assert(SCIPisLE(scip, lbx, ubx));
548  assert(SCIPisLE(scip, lby, uby));
549  assert(SCIPisLE(scip, lbx, refpointx));
550  assert(SCIPisGE(scip, ubx, refpointx));
551  assert(SCIPisLE(scip, lby, refpointy));
552  assert(SCIPisGE(scip, uby, refpointy));
553  assert(lincoefx != NULL);
554  assert(lincoefy != NULL);
555  assert(linconstant != NULL);
556  assert(success != NULL);
557  assert(xcoef == 0.0 || xcoef == -1.0 || xcoef == 1.0); /*lint !e777*/
558  assert(ycoef != SCIP_INVALID && ycoef != 0.0); /*lint !e777*/
559  assert(constant != SCIP_INVALID); /*lint !e777*/
560 
561  *success = FALSE;
562  *lincoefx = SCIP_INVALID;
563  *lincoefy = SCIP_INVALID;
564  *linconstant = SCIP_INVALID;
565 
566  /* reference point does not satisfy linear inequality */
567  if( SCIPisFeasGT(scip, xcoef * refpointx - ycoef * refpointy - constant, 0.0) )
568  return;
569 
570  /* compute minimal and maximal bounds on x and y for accepting the reference point */
571  minx = lbx + 0.01 * (ubx-lbx);
572  maxx = ubx - 0.01 * (ubx-lbx);
573  miny = lby + 0.01 * (uby-lby);
574  maxy = uby - 0.01 * (uby-lby);
575 
576  /* check whether the reference point is in [minx,maxx]x[miny,maxy] */
577  if( SCIPisLE(scip, refpointx, minx) || SCIPisGE(scip, refpointx, maxx)
578  || SCIPisLE(scip, refpointy, miny) || SCIPisGE(scip, refpointy, maxy) )
579  return;
580 
581  /* always consider xy without the bilinear coefficient */
582  if( bilincoef < 0.0 )
583  overestimate = !overestimate;
584 
585  /* we use same notation as in "Convex envelopes of bivariate functions through the solution of KKT systems", 2016 */
586  mj = xcoef / ycoef;
587  qj = -constant / ycoef;
588 
589  /* mj > 0 => underestimate; mj < 0 => overestimate */
590  if( SCIPisNegative(scip, mj) != overestimate )
591  return;
592 
593  /* get the corner point that satisfies the linear inequality xcoef*x <= ycoef*y + constant */
594  if( !overestimate )
595  {
596  ys[0] = uby;
597  ys[1] = lby;
598  }
599 
600  vx = SCIP_INVALID;
601  vy = SCIP_INVALID;
602  n = 0;
603  for( i = 0; i < 2; ++i )
604  {
605  SCIP_Real activity = xcoef * xs[i] - ycoef * ys[i] - constant;
606  if( SCIPisLE(scip, activity, 0.0) )
607  {
608  /* corner point is satisfies inequality */
609  vx = xs[i];
610  vy = ys[i];
611  }
612  else if( SCIPisFeasGT(scip, activity, 0.0) )
613  /* corner point is clearly cut off */
614  ++n;
615  }
616 
617  /* skip if no corner point satisfies the inequality or if no corner point is cut off (that is, all corner points satisfy the inequality almost [1e-9..1e-6]) */
618  if( n != 1 || vx == SCIP_INVALID || vy == SCIP_INVALID ) /*lint !e777*/
619  return;
620 
621  tmp = mj*(refpointx - vx) + vy - refpointy;
622  if( SCIPisZero(scip, tmp) )
623  return;
624 
625  /* (xj,yj) is the projection onto the line xcoef*x = ycoef*y + constant */
626  xj = (refpointx*(vy - qj) - vx*(refpointy - qj)) / tmp;
627  yj = mj * xj + qj;
628 
629  assert(SCIPisFeasEQ(scip, xcoef*xj - ycoef*yj - constant, 0.0));
630 
631  /* check whether the projection is in [minx,maxx] x [miny,maxy]; this avoids numerical difficulties when the
632  * projection is close to the variable bounds
633  */
634  if( SCIPisLE(scip, xj, minx) || SCIPisGE(scip, xj, maxx) || SCIPisLE(scip, yj, miny) || SCIPisGE(scip, yj, maxy) )
635  return;
636 
637  assert(vy - mj*vx - qj != 0.0);
638 
639  *lincoefy = (mj*SQR(xj) - 2.0*mj*vx*xj - qj*vx + vx*vy) / (vy - mj*vx - qj);
640  *lincoefx = 2.0*mj*xj + qj - mj*(*lincoefy);
641  *linconstant = -mj*SQR(xj) - (*lincoefy)*qj;
642 
643  /* consider the bilinear coefficient */
644  *lincoefx *= bilincoef;
645  *lincoefy *= bilincoef;
646  *linconstant *= bilincoef;
647 
648  /* cut needs to be tight at (vx,vy) and (xj,yj); otherwise we consider the cut to be numerically bad */
649  *success = SCIPisFeasEQ(scip, (*lincoefx)*vx + (*lincoefy)*vy + (*linconstant), bilincoef*vx*vy)
650  && SCIPisFeasEQ(scip, (*lincoefx)*xj + (*lincoefy)*yj + (*linconstant), bilincoef*xj*yj);
651 
652 #ifndef NDEBUG
653  {
654  SCIP_Real activity = (*lincoefx)*refpointx + (*lincoefy)*refpointy + (*linconstant);
655 
656  /* cut needs to under- or overestimate the bilinear term at the reference point */
657  if( bilincoef < 0.0 )
658  overestimate = !overestimate;
659 
660  if( overestimate )
661  assert(SCIPisFeasGE(scip, activity, bilincoef*refpointx*refpointy));
662  else
663  assert(SCIPisFeasLE(scip, activity, bilincoef*refpointx*refpointy));
664  }
665 #endif
666 }
667 
668 /** helper function to compute the convex envelope of a bilinear term when two linear inequalities are given; we
669  * use the same notation and formulas as in Locatelli 2016
670  */
671 static
673  SCIP* scip, /**< SCIP data structure */
674  SCIP_Real x, /**< reference point for x */
675  SCIP_Real y, /**< reference point for y */
676  SCIP_Real mi, /**< coefficient of x in the first linear inequality */
677  SCIP_Real qi, /**< constant in the first linear inequality */
678  SCIP_Real mj, /**< coefficient of x in the second linear inequality */
679  SCIP_Real qj, /**< constant in the second linear inequality */
680  SCIP_Real* RESTRICT xi, /**< buffer to store x coordinate of the first point */
681  SCIP_Real* RESTRICT yi, /**< buffer to store y coordinate of the first point */
682  SCIP_Real* RESTRICT xj, /**< buffer to store x coordinate of the second point */
683  SCIP_Real* RESTRICT yj, /**< buffer to store y coordinate of the second point */
684  SCIP_Real* RESTRICT xcoef, /**< buffer to store the x coefficient of the envelope */
685  SCIP_Real* RESTRICT ycoef, /**< buffer to store the y coefficient of the envelope */
686  SCIP_Real* RESTRICT constant /**< buffer to store the constant of the envelope */
687  )
688 {
689  assert(xi != NULL);
690  assert(yi != NULL);
691  assert(xj != NULL);
692  assert(yj != NULL);
693  assert(xcoef != NULL);
694  assert(ycoef != NULL);
695  assert(constant != NULL);
696 
697  if( SCIPisEQ(scip, mi, mj) )
698  {
699  *xi = (x + mi * y - qi) / (2.0*mi);
700  *yi = mi*(*xi) + qi;
701  *xj = (*xi) + (qi - qj)/ (2.0*mi);
702  *yj = mj * (*xj) + qj;
703  *ycoef = (*xi) + (qi - qj) / (4.0*mi); /* note that this is wrong in Locatelli 2016 */
704  *xcoef = 2.0*mi*(*xi) - mi * (*ycoef) + qi;
705  *constant = -mj*SQR(*xj) - (*ycoef) * qj;
706  }
707  else if( mi > 0.0 )
708  {
709  assert(mj > 0.0);
710 
711  *xi = (y + SQRT(mi*mj)*x - qi) / (REALABS(mi) + SQRT(mi*mj));
712  *yi = mi*(*xi) + qi;
713  *xj = (y + SQRT(mi*mj)*x - qj) / (REALABS(mj) + SQRT(mi*mj));
714  *yj = mj*(*xj) + qj;
715  *ycoef = (2.0*mj*(*xj) + qj - 2.0*mi*(*xi) - qi) / (mj - mi);
716  *xcoef = 2.0*mj*(*xj) + qj - mj*(*ycoef);
717  *constant = -mj*SQR(*xj) - (*ycoef) * qj;
718  }
719  else
720  {
721  assert(mi < 0.0 && mj < 0.0);
722 
723  /* apply variable transformation x = -x in case for overestimation */
724  computeBilinEnvelope2(scip, -x, y, -mi, qi, -mj, qj, xi, yi, xj, yj, xcoef, ycoef, constant);
725 
726  /* revert transformation; multiply cut by -1 and change -x by x */
727  *xi = -(*xi);
728  *xj = -(*xj);
729  *ycoef = -(*ycoef);
730  *constant = -(*constant);
731  }
732 }
733 
734 /** computes coefficients of linearization of a bilinear term in a reference point when given two linear inequality
735  * involving only the variables of the bilinear term
736  *
737  * @note the formulas are extracted from "Convex envelopes of bivariate functions through the solution of KKT systems"
738  * by Marco Locatelli
739  *
740  */
742  SCIP* scip, /**< SCIP data structure */
743  SCIP_Real bilincoef, /**< coefficient of bilinear term */
744  SCIP_Real lbx, /**< lower bound on first variable */
745  SCIP_Real ubx, /**< upper bound on first variable */
746  SCIP_Real refpointx, /**< reference point for first variable */
747  SCIP_Real lby, /**< lower bound on second variable */
748  SCIP_Real uby, /**< upper bound on second variable */
749  SCIP_Real refpointy, /**< reference point for second variable */
750  SCIP_Bool overestimate, /**< whether to compute an overestimator instead of an underestimator */
751  SCIP_Real xcoef1, /**< x coefficient of linear inequality; must be in {-1,0,1} */
752  SCIP_Real ycoef1, /**< y coefficient of linear inequality */
753  SCIP_Real constant1, /**< constant of linear inequality */
754  SCIP_Real xcoef2, /**< x coefficient of linear inequality; must be in {-1,0,1} */
755  SCIP_Real ycoef2, /**< y coefficient of linear inequality */
756  SCIP_Real constant2, /**< constant of linear inequality */
757  SCIP_Real* RESTRICT lincoefx, /**< buffer to store coefficient of first variable in linearization */
758  SCIP_Real* RESTRICT lincoefy, /**< buffer to store coefficient of second variable in linearization */
759  SCIP_Real* RESTRICT linconstant, /**< buffer to store constant of linearization */
760  SCIP_Bool* RESTRICT success /**< buffer to store whether linearization was successful */
761  )
762 {
763  SCIP_Real mi, mj, qi, qj, xi, xj, yi, yj;
764  SCIP_Real xcoef, ycoef, constant;
765  SCIP_Real minx, maxx, miny, maxy;
766 
767  assert(scip != NULL);
768  assert(!SCIPisInfinity(scip, lbx));
769  assert(!SCIPisInfinity(scip, -ubx));
770  assert(!SCIPisInfinity(scip, lby));
771  assert(!SCIPisInfinity(scip, -uby));
772  assert(SCIPisLE(scip, lbx, ubx));
773  assert(SCIPisLE(scip, lby, uby));
774  assert(SCIPisLE(scip, lbx, refpointx));
775  assert(SCIPisGE(scip, ubx, refpointx));
776  assert(SCIPisLE(scip, lby, refpointy));
777  assert(SCIPisGE(scip, uby, refpointy));
778  assert(lincoefx != NULL);
779  assert(lincoefy != NULL);
780  assert(linconstant != NULL);
781  assert(success != NULL);
782  assert(xcoef1 != 0.0 && xcoef1 != SCIP_INVALID); /*lint !e777*/
783  assert(ycoef1 != SCIP_INVALID && ycoef1 != 0.0); /*lint !e777*/
784  assert(constant1 != SCIP_INVALID); /*lint !e777*/
785  assert(xcoef2 != 0.0 && xcoef2 != SCIP_INVALID); /*lint !e777*/
786  assert(ycoef2 != SCIP_INVALID && ycoef2 != 0.0); /*lint !e777*/
787  assert(constant2 != SCIP_INVALID); /*lint !e777*/
788 
789  *success = FALSE;
790  *lincoefx = SCIP_INVALID;
791  *lincoefy = SCIP_INVALID;
792  *linconstant = SCIP_INVALID;
793 
794  /* reference point does not satisfy linear inequalities */
795  if( SCIPisFeasGT(scip, xcoef1 * refpointx - ycoef1 * refpointy - constant1, 0.0)
796  || SCIPisFeasGT(scip, xcoef2 * refpointx - ycoef2 * refpointy - constant2, 0.0) )
797  return;
798 
799  /* compute minimal and maximal bounds on x and y for accepting the reference point */
800  minx = lbx + 0.01 * (ubx-lbx);
801  maxx = ubx - 0.01 * (ubx-lbx);
802  miny = lby + 0.01 * (uby-lby);
803  maxy = uby - 0.01 * (uby-lby);
804 
805  /* check the reference point is in the interior of the domain */
806  if( SCIPisLE(scip, refpointx, minx) || SCIPisGE(scip, refpointx, maxx)
807  || SCIPisLE(scip, refpointy, miny) || SCIPisFeasGE(scip, refpointy, maxy) )
808  return;
809 
810  /* the sign of the x-coefficients of the two inequalities must be different; otherwise the convex or concave
811  * envelope can be computed via SCIPcomputeBilinEnvelope1 for each inequality separately
812  */
813  if( (xcoef1 > 0) == (xcoef2 > 0) )
814  return;
815 
816  /* always consider xy without the bilinear coefficient */
817  if( bilincoef < 0.0 )
818  overestimate = !overestimate;
819 
820  /* we use same notation as in "Convex envelopes of bivariate functions through the solution of KKT systems", 2016 */
821  mi = xcoef1 / ycoef1;
822  qi = -constant1 / ycoef1;
823  mj = xcoef2 / ycoef2;
824  qj = -constant2 / ycoef2;
825 
826  /* mi, mj > 0 => underestimate; mi, mj < 0 => overestimate */
827  if( SCIPisNegative(scip, mi) != overestimate || SCIPisNegative(scip, mj) != overestimate )
828  return;
829 
830  /* compute cut according to Locatelli 2016 */
831  computeBilinEnvelope2(scip, refpointx, refpointy, mi, qi, mj, qj, &xi, &yi, &xj, &yj, &xcoef, &ycoef, &constant);
832  assert(SCIPisEQ(scip, mi*xi + qi, yi));
833  assert(SCIPisEQ(scip, mj*xj + qj, yj));
834 
835  /* it might happen that (xi,yi) = (xj,yj) if the two lines intersect */
836  if( SCIPisEQ(scip, xi, xj) && SCIPisEQ(scip, yi, yj) )
837  return;
838 
839  /* check whether projected points are in the interior */
840  if( SCIPisLE(scip, xi, minx) || SCIPisGE(scip, xi, maxx) || SCIPisLE(scip, yi, miny) || SCIPisGE(scip, yi, maxy) )
841  return;
842  if( SCIPisLE(scip, xj, minx) || SCIPisGE(scip, xj, maxx) || SCIPisLE(scip, yj, miny) || SCIPisGE(scip, yj, maxy) )
843  return;
844 
845  *lincoefx = bilincoef * xcoef;
846  *lincoefy = bilincoef * ycoef;
847  *linconstant = bilincoef * constant;
848 
849  /* cut needs to be tight at (vx,vy) and (xj,yj) */
850  *success = SCIPisFeasEQ(scip, (*lincoefx)*xi + (*lincoefy)*yi + (*linconstant), bilincoef*xi*yi)
851  && SCIPisFeasEQ(scip, (*lincoefx)*xj + (*lincoefy)*yj + (*linconstant), bilincoef*xj*yj);
852 
853 #ifndef NDEBUG
854  {
855  SCIP_Real activity = (*lincoefx)*refpointx + (*lincoefy)*refpointy + (*linconstant);
856 
857  /* cut needs to under- or overestimate the bilinear term at the reference point */
858  if( bilincoef < 0.0 )
859  overestimate = !overestimate;
860 
861  if( overestimate )
862  assert(SCIPisFeasGE(scip, activity, bilincoef*refpointx*refpointy));
863  else
864  assert(SCIPisFeasLE(scip, activity, bilincoef*refpointx*refpointy));
865  }
866 #endif
867 }
868 
869 /** creates an NLP relaxation and stores it in a given NLPI problem; the function computes for each variable which the
870  * number of non-linearly occurrences and stores it in the nlscore array
871  *
872  * @note the first row corresponds always to the cutoff row (even if cutoffbound is SCIPinfinity(scip))
873  **/
875  SCIP* scip, /**< SCIP data structure */
876  SCIP_NLPI* nlpi, /**< interface to NLP solver */
877  SCIP_NLROW** nlrows, /**< nonlinear rows */
878  int nnlrows, /**< total number of nonlinear rows */
879  SCIP_NLPIPROBLEM* nlpiprob, /**< empty nlpi problem */
880  SCIP_HASHMAP* var2idx, /**< empty hash map to store mapping between variables and indices in nlpi
881  * problem */
882  SCIP_Real* nlscore, /**< array to store the score of each nonlinear variable (NULL if not
883  * needed) */
884  SCIP_Real cutoffbound, /**< cutoff bound */
885  SCIP_Bool setobj, /**< should the objective function be set? */
886  SCIP_Bool onlyconvex /**< filter only for convex constraints */
887  )
888 {
889  SCIP_EXPRTREE** exprtrees;
890  int** exprvaridxs;
891  SCIP_QUADELEM** quadelems;
892  int* nquadelems;
893  SCIP_Real** linvals;
894  int** lininds;
895  int* nlininds;
896  SCIP_Real* lhss;
897  SCIP_Real* rhss;
898  const char** names;
899  SCIP_VAR** vars;
900  int nvars;
901  SCIP_Real* lbs;
902  SCIP_Real* ubs;
903  SCIP_Real* objvals = NULL;
904  int* objinds = NULL;
905  const char** varnames;
906  int nobjinds;
907  int nconss;
908  int i;
909 
910  assert(nlpiprob != NULL);
911  assert(var2idx != NULL);
912  assert(nlrows != NULL);
913  assert(nnlrows > 0);
914  assert(nlpi != NULL);
915 
916  SCIPdebugMsg(scip, "call SCIPcreateConvexNlpNlobbt() with cutoffbound %g\n", cutoffbound);
917 
918  if( nlscore != NULL )
919  {
920  BMSclearMemoryArray(nlscore, SCIPgetNVars(scip));
921  }
922  vars = SCIPgetVars(scip);
923  nvars = SCIPgetNVars(scip);
924  nconss = 0;
925 
926  SCIP_CALL( SCIPallocBufferArray(scip, &exprtrees, nnlrows + 1) );
927  SCIP_CALL( SCIPallocBufferArray(scip, &exprvaridxs, nnlrows + 1) );
928  SCIP_CALL( SCIPallocBufferArray(scip, &quadelems, nnlrows + 1) );
929  SCIP_CALL( SCIPallocBufferArray(scip, &nquadelems, nnlrows + 1) );
930  SCIP_CALL( SCIPallocBufferArray(scip, &linvals, nnlrows + 1) );
931  SCIP_CALL( SCIPallocBufferArray(scip, &lininds, nnlrows + 1) );
932  SCIP_CALL( SCIPallocBufferArray(scip, &nlininds, nnlrows + 1) );
933  SCIP_CALL( SCIPallocBufferArray(scip, &names, nnlrows + 1) );
934  SCIP_CALL( SCIPallocBufferArray(scip, &lhss, nnlrows + 1) );
935  SCIP_CALL( SCIPallocBufferArray(scip, &rhss, nnlrows + 1) );
936 
937  if( setobj )
938  {
939  SCIP_CALL( SCIPallocBufferArray(scip, &objvals, nvars) );
940  SCIP_CALL( SCIPallocBufferArray(scip, &objinds, nvars) );
941  }
942 
943  SCIP_CALL( SCIPallocBufferArray(scip, &lbs, nvars) );
944  SCIP_CALL( SCIPallocBufferArray(scip, &ubs, nvars) );
945  SCIP_CALL( SCIPallocBufferArray(scip, &varnames, nvars) );
946 
947  /* create a unique mapping between variables and {0,..,nvars-1} */
948  nobjinds = 0;
949  for( i = 0; i < nvars; ++i )
950  {
951  assert(vars[i] != NULL);
952  SCIP_CALL( SCIPhashmapInsert(var2idx, (void*)vars[i], (void*)(size_t)i) );
953 
954  lbs[i] = SCIPvarGetLbLocal(vars[i]);
955  ubs[i] = SCIPvarGetUbLocal(vars[i]);
956  varnames[i] = SCIPvarGetName(vars[i]);
957 
958  /* collect non-zero objective coefficients */
959  if( setobj && !SCIPisZero(scip, SCIPvarGetObj(vars[i])) )
960  {
961  assert(objvals != NULL);
962  assert(objinds != NULL);
963 
964  objvals[nobjinds] = SCIPvarGetObj(vars[i]);
965  objinds[nobjinds] = i;
966  ++nobjinds;
967  }
968  }
969 
970  /* add variables */
971  SCIP_CALL( SCIPnlpiAddVars(nlpi, nlpiprob, nvars, lbs, ubs, varnames) );
972  SCIPfreeBufferArray(scip, &varnames);
973  SCIPfreeBufferArray(scip, &ubs);
974  SCIPfreeBufferArray(scip, &lbs);
975 
976  /* set the objective function */
977  if( setobj )
978  {
979  if( nobjinds > 0 )
980  {
981  SCIP_CALL( SCIPnlpiSetObjective(nlpi, nlpiprob, nobjinds, objinds, objvals, 0, NULL, NULL, NULL, 0.0) );
982  }
983 
984  SCIPfreeBufferArray(scip, &objinds);
985  SCIPfreeBufferArray(scip, &objvals);
986  }
987 
988  /* add row for cutoff bound even if cutoffbound == SCIPinfinity() */
989  lhss[nconss] = -SCIPinfinity(scip);
990  rhss[nconss] = cutoffbound;
991  names[nconss] = "objcutoff";
992  lininds[nconss] = NULL;
993  linvals[nconss] = NULL;
994  nlininds[nconss] = 0;
995  nquadelems[nconss] = 0;
996  quadelems[nconss] = NULL;
997  exprtrees[nconss] = NULL;
998  exprvaridxs[nconss] = NULL;
999 
1000  SCIP_CALL( SCIPallocBufferArray(scip, &lininds[nconss], nvars) ); /*lint !e866*/
1001  SCIP_CALL( SCIPallocBufferArray(scip, &linvals[nconss], nvars) ); /*lint !e866*/
1002 
1003  for( i = 0; i < nvars; ++i )
1004  {
1005  if( !SCIPisZero(scip, SCIPvarGetObj(vars[i])) )
1006  {
1007  linvals[nconss][nlininds[nconss]] = SCIPvarGetObj(vars[i]);
1008  lininds[nconss][nlininds[nconss]] = i;
1009  ++nlininds[nconss];
1010  }
1011  }
1012  ++nconss;
1013 
1014  /* add convex nonlinear rows to NLPI problem */
1015  for( i = 0; i < nnlrows; ++i )
1016  {
1017  SCIP_Bool userhs;
1018  SCIP_Bool uselhs;
1019  int k;
1020 
1021  assert(nlrows[i] != NULL);
1022 
1023  uselhs = FALSE;
1024  userhs = FALSE;
1025 
1026  /* check curvature together with constraint sides of a nonlinear row */
1027  if( SCIPnlrowGetNQuadElems(nlrows[i]) == 0 && SCIPnlrowGetExprtree(nlrows[i]) == NULL )
1028  {
1029  uselhs = TRUE;
1030  userhs = TRUE;
1031  }
1032  else
1033  {
1034  if( (!onlyconvex || SCIPnlrowGetCurvature(nlrows[i]) == SCIP_EXPRCURV_CONVEX)
1035  && !SCIPisInfinity(scip, SCIPnlrowGetRhs(nlrows[i])) )
1036  userhs = TRUE;
1037  if( (!onlyconvex || SCIPnlrowGetCurvature(nlrows[i]) == SCIP_EXPRCURV_CONCAVE)
1038  && !SCIPisInfinity(scip, SCIPnlrowGetLhs(nlrows[i])) )
1039  uselhs = TRUE;
1040  }
1041 
1042  if( !uselhs && !userhs )
1043  continue;
1044 
1045  lhss[nconss] = uselhs ? SCIPnlrowGetLhs(nlrows[i]) - SCIPnlrowGetConstant(nlrows[i]) : -SCIPinfinity(scip);
1046  rhss[nconss] = userhs ? SCIPnlrowGetRhs(nlrows[i]) - SCIPnlrowGetConstant(nlrows[i]) : SCIPinfinity(scip);
1047  names[nconss] = SCIPnlrowGetName(nlrows[i]);
1048  nlininds[nconss] = 0;
1049  lininds[nconss] = NULL;
1050  linvals[nconss] = NULL;
1051  nquadelems[nconss] = 0;
1052  quadelems[nconss] = NULL;
1053  exprtrees[nconss] = NULL;
1054  exprvaridxs[nconss] = NULL;
1055 
1056  /* copy linear part */
1057  if( SCIPnlrowGetNLinearVars(nlrows[i]) > 0 )
1058  {
1059  SCIP_VAR* var;
1060 
1061  nlininds[nconss] = SCIPnlrowGetNLinearVars(nlrows[i]);
1062 
1063  SCIP_CALL( SCIPallocBufferArray(scip, &lininds[nconss], nlininds[nconss]) ); /*lint !e866*/
1064  SCIP_CALL( SCIPallocBufferArray(scip, &linvals[nconss], nlininds[nconss]) ); /*lint !e866*/
1065 
1066  for( k = 0; k < nlininds[nconss]; ++k )
1067  {
1068  var = SCIPnlrowGetLinearVars(nlrows[i])[k];
1069  assert(var != NULL);
1070  assert(SCIPhashmapExists(var2idx, (void*)var));
1071 
1072  lininds[nconss][k] = (int)(size_t)SCIPhashmapGetImage(var2idx, (void*)var);
1073  assert(var == vars[lininds[nconss][k]]);
1074  linvals[nconss][k] = SCIPnlrowGetLinearCoefs(nlrows[i])[k];
1075  }
1076  }
1077 
1078  /* copy quadratic part */
1079  if( SCIPnlrowGetNQuadElems(nlrows[i]) > 0 )
1080  {
1081  SCIP_QUADELEM quadelem;
1082  SCIP_VAR* var1;
1083  SCIP_VAR* var2;
1084 
1085  nquadelems[nconss] = SCIPnlrowGetNQuadElems(nlrows[i]);
1086  SCIP_CALL( SCIPallocBufferArray(scip, &quadelems[nconss], nquadelems[nconss]) ); /*lint !e866*/
1087 
1088  for( k = 0; k < nquadelems[nconss]; ++k )
1089  {
1090  quadelem = SCIPnlrowGetQuadElems(nlrows[i])[k];
1091 
1092  var1 = SCIPnlrowGetQuadVars(nlrows[i])[quadelem.idx1];
1093  assert(var1 != NULL);
1094  assert(SCIPhashmapExists(var2idx, (void*)var1));
1095 
1096  var2 = SCIPnlrowGetQuadVars(nlrows[i])[quadelem.idx2];
1097  assert(var2 != NULL);
1098  assert(SCIPhashmapExists(var2idx, (void*)var2));
1099 
1100  quadelems[nconss][k].coef = quadelem.coef;
1101  quadelems[nconss][k].idx1 = (int)(size_t)SCIPhashmapGetImage(var2idx, (void*)var1);
1102  quadelems[nconss][k].idx2 = (int)(size_t)SCIPhashmapGetImage(var2idx, (void*)var2);
1103 
1104  /* expr.c assumes that the indices are ordered */
1105  if( quadelems[nconss][k].idx1 > quadelems[nconss][k].idx2 )
1106  {
1107  SCIPswapInts(&quadelems[nconss][k].idx1, &quadelems[nconss][k].idx2);
1108  }
1109  assert(quadelems[nconss][k].idx1 <= quadelems[nconss][k].idx2);
1110 
1111  /* update nlscore */
1112  if( nlscore != NULL )
1113  {
1114  ++nlscore[quadelems[nconss][k].idx1];
1115  if( quadelems[nconss][k].idx1 != quadelems[nconss][k].idx2 )
1116  ++nlscore[quadelems[nconss][k].idx2];
1117  }
1118  }
1119  }
1120 
1121  /* copy expression tree */
1122  if( SCIPnlrowGetExprtree(nlrows[i]) != NULL )
1123  {
1124  SCIP_VAR* var;
1125 
1126  /* note that we don't need to copy the expression tree here since only the mapping between variables in the
1127  * tree and the corresponding indices change; this mapping is stored in the exprvaridxs array
1128  */
1129  exprtrees[nconss] = SCIPnlrowGetExprtree(nlrows[i]);
1130 
1131  SCIP_CALL( SCIPallocBufferArray(scip, &exprvaridxs[nconss], SCIPexprtreeGetNVars(exprtrees[nconss])) ); /*lint !e866*/
1132 
1133  for( k = 0; k < SCIPexprtreeGetNVars(exprtrees[nconss]); ++k )
1134  {
1135  var = SCIPexprtreeGetVars(exprtrees[nconss])[k];
1136  assert(var != NULL);
1137  assert(SCIPhashmapExists(var2idx, (void*)var));
1138 
1139  exprvaridxs[nconss][k] = (int)(size_t)SCIPhashmapGetImage(var2idx, (void*)var);
1140 
1141  /* update nlscore */
1142  if( nlscore != NULL )
1143  ++nlscore[exprvaridxs[nconss][k]];
1144  }
1145  }
1146 
1147  ++nconss;
1148  }
1149  assert(nconss > 0);
1150 
1151  /* pass all constraint information to nlpi */
1152  SCIP_CALL( SCIPnlpiAddConstraints(nlpi, nlpiprob, nconss, lhss, rhss, nlininds, lininds, linvals, nquadelems,
1153  quadelems, exprvaridxs, exprtrees, names) );
1154 
1155  /* free memory */
1156  for( i = nconss - 1; i > 0; --i )
1157  {
1158  if( exprtrees[i] != NULL )
1159  {
1160  assert(exprvaridxs[i] != NULL);
1161  SCIPfreeBufferArray(scip, &exprvaridxs[i]);
1162  }
1163 
1164  if( nquadelems[i] > 0 )
1165  {
1166  assert(quadelems[i] != NULL);
1167  SCIPfreeBufferArray(scip, &quadelems[i]);
1168  }
1169 
1170  if( nlininds[i] > 0 )
1171  {
1172  assert(linvals[i] != NULL);
1173  assert(lininds[i] != NULL);
1174  SCIPfreeBufferArray(scip, &linvals[i]);
1175  SCIPfreeBufferArray(scip, &lininds[i]);
1176  }
1177  }
1178  /* free row for cutoff bound even if objective is 0 */
1179  SCIPfreeBufferArray(scip, &linvals[i]);
1180  SCIPfreeBufferArray(scip, &lininds[i]);
1181 
1182  SCIPfreeBufferArray(scip, &rhss);
1183  SCIPfreeBufferArray(scip, &lhss);
1184  SCIPfreeBufferArray(scip, &names);
1185  SCIPfreeBufferArray(scip, &nlininds);
1186  SCIPfreeBufferArray(scip, &lininds);
1187  SCIPfreeBufferArray(scip, &linvals);
1188  SCIPfreeBufferArray(scip, &nquadelems);
1189  SCIPfreeBufferArray(scip, &quadelems);
1190  SCIPfreeBufferArray(scip, &exprvaridxs);
1191  SCIPfreeBufferArray(scip, &exprtrees);
1192 
1193  return SCIP_OKAY;
1194 }
1195 
1196 /** updates bounds of each variable and the cutoff row in the nlpiproblem */
1198  SCIP* scip, /**< SCIP data structure */
1199  SCIP_NLPI* nlpi, /**< interface to NLP solver */
1200  SCIP_NLPIPROBLEM* nlpiprob, /**< nlpi problem representing the convex NLP relaxation */
1201  SCIP_HASHMAP* var2nlpiidx, /**< mapping between variables and nlpi indices */
1202  SCIP_VAR** nlpivars, /**< array containing all variables of the nlpi */
1203  int nlpinvars, /**< total number of nlpi variables */
1204  SCIP_Real cutoffbound /**< new cutoff bound */
1205  )
1206 {
1207  SCIP_Real* lbs;
1208  SCIP_Real* ubs;
1209  SCIP_Real lhs;
1210  SCIP_Real rhs;
1211  int* inds;
1212  int i;
1213 
1214  SCIPdebugMsg(scip, "call SCIPupdateConvexNlpNlobbt()\n");
1215 
1216  /* update variable bounds */
1217  SCIP_CALL( SCIPallocBufferArray(scip, &lbs, nlpinvars) );
1218  SCIP_CALL( SCIPallocBufferArray(scip, &ubs, nlpinvars) );
1219  SCIP_CALL( SCIPallocBufferArray(scip, &inds, nlpinvars) );
1220 
1221  for( i = 0; i < nlpinvars; ++i )
1222  {
1223  assert(nlpivars[i] != NULL);
1224  assert(SCIPhashmapExists(var2nlpiidx, (void*)nlpivars[i]));
1225 
1226  lbs[i] = SCIPvarGetLbLocal(nlpivars[i]);
1227  ubs[i] = SCIPvarGetUbLocal(nlpivars[i]);
1228  inds[i] = (int)(uintptr_t)SCIPhashmapGetImage(var2nlpiidx, (void*)nlpivars[i]);
1229  assert(inds[i] >= 0 && inds[i] < nlpinvars);
1230  }
1231 
1232  SCIP_CALL( SCIPnlpiChgVarBounds(nlpi, nlpiprob, nlpinvars, inds, lbs, ubs) );
1233 
1234  SCIPfreeBufferArray(scip, &inds);
1235  SCIPfreeBufferArray(scip, &ubs);
1236  SCIPfreeBufferArray(scip, &lbs);
1237 
1238  /* update cutoff row */
1239  lhs = -SCIPinfinity(scip);
1240  rhs = cutoffbound;
1241  i = 0;
1242 
1243  SCIP_CALL( SCIPnlpiChgConsSides(nlpi, nlpiprob, 1, &i, &lhs, &rhs) );
1244 
1245  return SCIP_OKAY;
1246 }
1247 
1248 /** adds linear rows to the NLP relaxation */
1250  SCIP* scip, /**< SCIP data structure */
1251  SCIP_NLPI* nlpi, /**< interface to NLP solver */
1252  SCIP_NLPIPROBLEM* nlpiprob, /**< nlpi problem */
1253  SCIP_HASHMAP* var2idx, /**< empty hash map to store mapping between variables and indices in nlpi
1254  * problem */
1255  SCIP_ROW** rows, /**< rows to add */
1256  int nrows /**< total number of rows to add */
1257  )
1258 {
1259  const char** names;
1260  SCIP_Real* lhss;
1261  SCIP_Real* rhss;
1262  SCIP_Real** linvals;
1263  int** lininds;
1264  int* nlininds;
1265  int i;
1266 
1267  assert(nlpi != NULL);
1268  assert(nlpiprob != NULL);
1269  assert(var2idx != NULL);
1270  assert(nrows == 0 || rows != NULL);
1271 
1272  SCIPdebugMsg(scip, "call SCIPaddConvexNlpRowsNlobbt() with %d rows\n", nrows);
1273 
1274  if( nrows <= 0 )
1275  return SCIP_OKAY;
1276 
1277  SCIP_CALL( SCIPallocBufferArray(scip, &names, nrows) );
1278  SCIP_CALL( SCIPallocBufferArray(scip, &lhss, nrows) );
1279  SCIP_CALL( SCIPallocBufferArray(scip, &rhss, nrows) );
1280  SCIP_CALL( SCIPallocBufferArray(scip, &linvals, nrows) );
1281  SCIP_CALL( SCIPallocBufferArray(scip, &lininds, nrows) );
1282  SCIP_CALL( SCIPallocBufferArray(scip, &nlininds, nrows) );
1283 
1284  for( i = 0; i < nrows; ++i )
1285  {
1286  int k;
1287 
1288  assert(rows[i] != NULL);
1289  assert(SCIProwGetNNonz(rows[i]) <= SCIPgetNVars(scip));
1290 
1291  names[i] = SCIProwGetName(rows[i]);
1292  lhss[i] = SCIProwGetLhs(rows[i]) - SCIProwGetConstant(rows[i]);
1293  rhss[i] = SCIProwGetRhs(rows[i]) - SCIProwGetConstant(rows[i]);
1294  nlininds[i] = SCIProwGetNNonz(rows[i]);
1295  linvals[i] = SCIProwGetVals(rows[i]);
1296  lininds[i] = NULL;
1297 
1298  SCIP_CALL( SCIPallocBufferArray(scip, &lininds[i], SCIProwGetNNonz(rows[i])) ); /*lint !e866*/
1299 
1300  for( k = 0; k < SCIProwGetNNonz(rows[i]); ++k )
1301  {
1302  SCIP_VAR* var;
1303 
1304  var = SCIPcolGetVar(SCIProwGetCols(rows[i])[k]);
1305  assert(var != NULL);
1306  assert(SCIPhashmapExists(var2idx, (void*)var));
1307 
1308  lininds[i][k] = (int)(size_t)SCIPhashmapGetImage(var2idx, (void*)var);
1309  assert(lininds[i][k] >= 0 && lininds[i][k] < SCIPgetNVars(scip));
1310  }
1311  }
1312 
1313  /* pass all linear rows to the nlpi */
1314  SCIP_CALL( SCIPnlpiAddConstraints(nlpi, nlpiprob, nrows, lhss, rhss, nlininds, lininds, linvals, NULL,
1315  NULL, NULL, NULL, names) );
1316 
1317  /* free memory */
1318  for( i = nrows - 1; i >= 0; --i )
1319  {
1320  SCIPfreeBufferArray(scip, &lininds[i]);
1321  }
1322  SCIPfreeBufferArray(scip, &nlininds);
1323  SCIPfreeBufferArray(scip, &lininds);
1324  SCIPfreeBufferArray(scip, &linvals);
1325  SCIPfreeBufferArray(scip, &rhss);
1326  SCIPfreeBufferArray(scip, &lhss);
1327  SCIPfreeBufferArray(scip, &names);
1328 
1329  return SCIP_OKAY;
1330 }
internal methods for separators
#define NULL
Definition: def.h:239
internal methods for managing events
default message handler
trivialnegation primal heuristic
internal methods for storing primal CIP solutions
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
methods to interpret (evaluate) an expression tree "fast"
internal methods for branch and bound tree
SCIP_Bool SCIPisRelEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
public methods for memory management
SCIP_RETCODE SCIPcreateNlpiProb(SCIP *scip, SCIP_NLPI *nlpi, SCIP_NLROW **nlrows, int nnlrows, SCIP_NLPIPROBLEM *nlpiprob, SCIP_HASHMAP *var2idx, SCIP_Real *nlscore, SCIP_Real cutoffbound, SCIP_Bool setobj, SCIP_Bool onlyconvex)
methods for implications, variable bounds, and cliques
internal methods for clocks and timing issues
int SCIProwGetNNonz(SCIP_ROW *row)
Definition: lp.c:16790
#define SQR(x)
Definition: def.h:191
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17399
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
internal methods for NLPI solver interfaces
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:16928
interface methods for specific LP solvers
internal methods for displaying statistics tables
#define RESTRICT
Definition: def.h:251
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:16869
#define FALSE
Definition: def.h:65
methods for the aggregation rows
SCIP_RETCODE SCIPnlpiAddConstraints(SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int nconss, const SCIP_Real *lhss, const SCIP_Real *rhss, const int *nlininds, int *const *lininds, SCIP_Real *const *linvals, const int *nquadelems, SCIP_QUADELEM *const *quadelems, int *const *exprvaridxs, SCIP_EXPRTREE *const *exprtrees, const char **names)
Definition: nlpi.c:268
internal methods for Benders&#39; decomposition
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
#define TRUE
Definition: def.h:64
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
methods commonly used by primal heuristics
SCIP_Real SCIPnlrowGetRhs(SCIP_NLROW *nlrow)
Definition: nlp.c:3384
internal methods for branching rules and branching candidate storage
datastructures for concurrent solvers
int SCIPnlrowGetNLinearVars(SCIP_NLROW *nlrow)
Definition: nlp.c:3246
public methods for problem variables
static void computeBilinEnvelope2(SCIP *scip, SCIP_Real x, SCIP_Real y, SCIP_Real mi, SCIP_Real qi, SCIP_Real mj, SCIP_Real qj, SCIP_Real *RESTRICT xi, SCIP_Real *RESTRICT yi, SCIP_Real *RESTRICT xj, SCIP_Real *RESTRICT yj, SCIP_Real *RESTRICT xcoef, SCIP_Real *RESTRICT ycoef, SCIP_Real *RESTRICT constant)
void SCIPaddBilinLinearization(SCIP *scip, SCIP_Real bilincoef, SCIP_Real refpointx, SCIP_Real refpointy, SCIP_Real *lincoefx, SCIP_Real *lincoefy, SCIP_Real *linconstant, SCIP_Bool *success)
SCIP_EXPRCURV SCIPnlrowGetCurvature(SCIP_NLROW *nlrow)
Definition: nlp.c:3394
SCIP_RETCODE SCIPnlpiChgVarBounds(SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int nvars, const int *indices, const SCIP_Real *lbs, const SCIP_Real *ubs)
Definition: nlpi.c:325
internal methods for handling parameter settings
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:2931
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
methods for creating output for visualization tools (VBC, BAK)
nodereopt branching rule
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:142
void SCIPcomputeBilinEnvelope2(SCIP *scip, SCIP_Real bilincoef, SCIP_Real lbx, SCIP_Real ubx, SCIP_Real refpointx, SCIP_Real lby, SCIP_Real uby, SCIP_Real refpointy, SCIP_Bool overestimate, SCIP_Real xcoef1, SCIP_Real ycoef1, SCIP_Real constant1, SCIP_Real xcoef2, SCIP_Real ycoef2, SCIP_Real constant2, SCIP_Real *RESTRICT lincoefx, SCIP_Real *RESTRICT lincoefy, SCIP_Real *RESTRICT linconstant, SCIP_Bool *RESTRICT success)
#define SCIPdebugMsg
Definition: scip_message.h:88
internal methods for LP management
SCIP_VAR ** x
Definition: circlepacking.c:54
SCIP_VAR ** SCIPexprtreeGetVars(SCIP_EXPRTREE *tree)
Definition: nlp.c:102
internal methods for branching and inference history
public methods for numerical tolerances
internal methods for collecting primal CIP solutions and primal informations
int SCIPnlrowGetNQuadElems(SCIP_NLROW *nlrow)
Definition: nlp.c:3323
internal methods for propagators
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3025
SCIP_RETCODE SCIPnlpiAddVars(SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int nvars, const SCIP_Real *lbs, const SCIP_Real *ubs, const char **varnames)
Definition: nlpi.c:250
void SCIPcomputeBilinEnvelope1(SCIP *scip, SCIP_Real bilincoef, SCIP_Real lbx, SCIP_Real ubx, SCIP_Real refpointx, SCIP_Real lby, SCIP_Real uby, SCIP_Real refpointy, SCIP_Bool overestimate, SCIP_Real xcoef, SCIP_Real ycoef, SCIP_Real constant, SCIP_Real *RESTRICT lincoefx, SCIP_Real *RESTRICT lincoefy, SCIP_Real *RESTRICT linconstant, SCIP_Bool *RESTRICT success)
SCIP_Real coef
Definition: type_expr.h:104
SCIP_VAR ** SCIPnlrowGetQuadVars(SCIP_NLROW *nlrow)
Definition: nlp.c:3286
git hash methods
void SCIPaddBilinMcCormick(SCIP *scip, SCIP_Real bilincoef, SCIP_Real lbx, SCIP_Real ubx, SCIP_Real refpointx, SCIP_Real lby, SCIP_Real uby, SCIP_Real refpointy, SCIP_Bool overestimate, SCIP_Real *lincoefx, SCIP_Real *lincoefy, SCIP_Real *linconstant, SCIP_Bool *success)
internal methods for storing and manipulating the main problem
methods for block memory pools and memory buffers
public methods for nonlinear functions
register additional core functionality that is designed as plugins
internal methods for presolvers
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16729
internal methods for NLP management
SCIP_RETCODE SCIPaddNlpiProbRows(SCIP *scip, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *nlpiprob, SCIP_HASHMAP *var2idx, SCIP_ROW **rows, int nrows)
internal miscellaneous methods
#define REALABS(x)
Definition: def.h:174
int SCIPexprtreeGetNVars(SCIP_EXPRTREE *tree)
Definition: expr.c:8612
SCIP_RETCODE SCIPnlpiChgConsSides(SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int nconss, const int *indices, const SCIP_Real *lhss, const SCIP_Real *rhss)
Definition: nlpi.c:343
internal methods for node selectors and node priority queues
internal methods for variable pricers
SCIP_QUADELEM * SCIPnlrowGetQuadElems(SCIP_NLROW *nlrow)
Definition: nlp.c:3333
internal methods for global SCIP settings
internal methods for storing conflicts
#define SCIP_CALL(x)
Definition: def.h:351
SCIP main data structure.
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition: lp.c:16879
internal methods for storing priced variables
internal methods for relaxators
internal methods for storing separated cuts
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
Definition: lp.c:16815
SCIP_RETCODE SCIPnlpiSetObjective(SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int nlins, const int *lininds, const SCIP_Real *linvals, int nquadelems, const SCIP_QUADELEM *quadelems, const int *exprvaridxs, const SCIP_EXPRTREE *exprtree, const SCIP_Real constant)
Definition: nlpi.c:300
void SCIPaddSquareSecant(SCIP *scip, SCIP_Real sqrcoef, SCIP_Real lb, SCIP_Real ub, SCIP_Real refpoint, SCIP_Real *lincoef, SCIP_Real *linconstant, SCIP_Bool *success)
public methods for NLP management
methods commonly used for presolving
methods for catching the user CTRL-C interrupt
internal methods for problem variables
data structures and methods for collecting reoptimization information
the function declarations for the synchronization store
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:130
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
Definition: lp.c:16825
public data structures and miscellaneous methods
internal methods for user interface dialog
#define SCIP_Bool
Definition: def.h:62
SCIP_RETCODE SCIPupdateNlpiProb(SCIP *scip, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *nlpiprob, SCIP_HASHMAP *var2nlpiidx, SCIP_VAR **nlpivars, int nlpinvars, SCIP_Real cutoffbound)
internal methods for input file readers
#define MIN(x, y)
Definition: def.h:209
methods for debugging
public methods for LP management
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17191
reoptsols primal heuristic
internal methods for storing cuts in a cut pool
Constraint handler for linear constraints in their most general form, .
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
helper functions for concurrent scip solvers
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:2044
SCIP_EXPRTREE * SCIPnlrowGetExprtree(SCIP_NLROW *nlrow)
Definition: nlp.c:3364
internal methods for return codes for SCIP methods
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition: lp.c:16835
#define SQRT(x)
Definition: def.h:192
#define MAX(x, y)
Definition: def.h:208
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:16639
internal methods for conflict analysis
internal methods for tree compressions
internal methods for main solving loop and node processing
public methods for message output
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:1999
default user interface dialog
#define SCIP_Real
Definition: def.h:150
internal methods for problem statistics
SCIP_VAR ** y
Definition: circlepacking.c:55
public methods for message handling
#define SCIP_INVALID
Definition: def.h:170
internal methods for constraints and constraint handlers
declarations for XML parsing
build flags methods
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real * SCIPnlrowGetLinearCoefs(SCIP_NLROW *nlrow)
Definition: nlp.c:3266
const char * SCIPnlrowGetName(SCIP_NLROW *nlrow)
Definition: nlp.c:3413
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17409
SCIP_VAR ** SCIPnlrowGetLinearVars(SCIP_NLROW *nlrow)
Definition: nlp.c:3256
SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:2874
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:112
common defines and data types used in all packages of SCIP
void SCIPswapInts(int *value1, int *value2)
Definition: misc.c:9619
SCIP_Real SCIPnlrowGetConstant(SCIP_NLROW *nlrow)
Definition: nlp.c:3236
internal methods for primal heuristics
SCIP_Real SCIPnlrowGetLhs(SCIP_NLROW *nlrow)
Definition: nlp.c:3374
public methods for global and local (sub)problems
internal methods for Benders&#39; decomposition cuts
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
void SCIPaddSquareLinearization(SCIP *scip, SCIP_Real sqrcoef, SCIP_Real refpoint, SCIP_Bool isint, SCIP_Real *lincoef, SCIP_Real *linconstant, SCIP_Bool *success)
internal methods for displaying runtime statistics
OFINS - Objective Function Induced Neighborhood Search - a primal heuristic for reoptimization.