Scippy

SCIP

Solving Constraint Integer Programs

sepa_minor.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 sepa_minor.c
17  * @ingroup DEFPLUGINS_SEPA
18  * @brief principal minor separator
19  * @author Benjamin Mueller
20  *
21  * @todo detect non-principal minors and use them to derive split cuts
22  */
23 
24 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
25 
26 #include <assert.h>
27 #include <string.h>
28 
29 #include "scip/sepa_minor.h"
30 #include "scip/cons_nonlinear.h"
31 #include "scip/nlpi_ipopt.h"
32 
33 #define SEPA_NAME "minor"
34 #define SEPA_DESC "separator to ensure that 2x2 principal minors of X - xx' are positive semi-definite"
35 #define SEPA_PRIORITY 0
36 #define SEPA_FREQ 10
37 #define SEPA_MAXBOUNDDIST 1.0
38 #define SEPA_USESSUBSCIP FALSE /**< does the separator use a secondary SCIP instance? */
39 #define SEPA_DELAY FALSE /**< should separation method be delayed, if other separators found cuts? */
40 
41 #define DEFAULT_MAXMINORSCONST 3000 /**< default constant for the maximum number of minors, i.e., max(const, fac * # quadratic terms) */
42 #define DEFAULT_MAXMINORSFAC 10.0 /**< default factor for the maximum number of minors, i.e., max(const, fac * # quadratic terms) */
43 #define DEFAULT_MINCUTVIOL 1e-4 /**< default minimum required violation of a cut */
44 #define DEFAULT_RANDSEED 157 /**< default random seed */
45 #define DEFAULT_MAXROUNDS 10 /**< maximal number of separation rounds per node (-1: unlimited) */
46 #define DEFAULT_MAXROUNDSROOT -1 /**< maximal number of separation rounds in the root node (-1: unlimited) */
47 #define DEFAULT_IGNOREPACKINGCONSS TRUE /**< default for ignoring circle packing constraints during minor detection */
48 
49 /*
50  * Data structures
51  */
52 
53 /** separator data */
54 struct SCIP_SepaData
55 {
56  SCIP_VAR** minors; /**< variables of 2x2 minors; each minor is stored like (auxvar_x^2,auxvar_y^2,auxvar_xy) */
57  int nminors; /**< total number of minors */
58  int minorssize; /**< size of minors array */
59  int maxminorsconst; /**< constant for the maximum number of minors, i.e., max(const, fac * # quadratic terms) */
60  SCIP_Real maxminorsfac; /**< factor for the maximum number of minors, i.e., max(const, fac * # quadratic terms) */
61  int maxrounds; /**< maximal number of separation rounds per node (-1: unlimited) */
62  int maxroundsroot; /**< maximal number of separation rounds in the root node (-1: unlimited) */
63  SCIP_Bool detectedminors; /**< has minor detection be called? */
64  SCIP_Real mincutviol; /**< minimum required violation of a cut */
65  SCIP_RANDNUMGEN* randnumgen; /**< random number generation */
66  SCIP_Bool ignorepackingconss; /**< whether to ignore circle packing constraints during minor detection */
67 };
68 
69 /*
70  * Local methods
71  */
72 
73 /** helper method to store a 2x2 minor in the separation data */
74 static
76  SCIP* scip, /**< SCIP data structure */
77  SCIP_SEPADATA* sepadata, /**< separator data */
78  SCIP_VAR* x, /**< x variable */
79  SCIP_VAR* y, /**< y variable */
80  SCIP_VAR* auxvarxx, /**< auxiliary variable for x*x */
81  SCIP_VAR* auxvaryy, /**< auxiliary variable for y*y */
82  SCIP_VAR* auxvarxy /**< auxiliary variable for x*y */
83  )
84 {
85  assert(sepadata != NULL);
86  assert(x != NULL);
87  assert(y != NULL);
88  assert(x != y);
89  assert(auxvarxx != NULL);
90  assert(auxvaryy != NULL);
91  assert(auxvarxy != NULL);
92  assert(auxvarxx != auxvaryy);
93  assert(auxvarxx != auxvarxy);
94  assert(auxvaryy != auxvarxy);
95 
96  SCIPdebugMsg(scip, "store 2x2 minor: %s %s %s for x=%s y=%s\n", SCIPvarGetName(auxvarxx), SCIPvarGetName(auxvaryy),
97  SCIPvarGetName(auxvarxy), SCIPvarGetName(x), SCIPvarGetName(y));
98 
99  /* reallocate if necessary */
100  if( sepadata->minorssize < 5 * (sepadata->nminors + 1) )
101  {
102  int newsize = SCIPcalcMemGrowSize(scip, 5 * (sepadata->nminors + 1));
103  assert(newsize > 5 * (sepadata->nminors + 1));
104 
105  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &(sepadata->minors), sepadata->minorssize, newsize) );
106  sepadata->minorssize = newsize;
107  }
108 
109  /* store minor */
110  sepadata->minors[5 * sepadata->nminors] = x;
111  sepadata->minors[5 * sepadata->nminors + 1] = y;
112  sepadata->minors[5 * sepadata->nminors + 2] = auxvarxx;
113  sepadata->minors[5 * sepadata->nminors + 3] = auxvaryy;
114  sepadata->minors[5 * sepadata->nminors + 4] = auxvarxy;
115  ++(sepadata->nminors);
116 
117  /* capture variables */
118  SCIP_CALL( SCIPcaptureVar(scip, x) );
119  SCIP_CALL( SCIPcaptureVar(scip, y) );
120  SCIP_CALL( SCIPcaptureVar(scip, auxvarxx) );
121  SCIP_CALL( SCIPcaptureVar(scip, auxvaryy) );
122  SCIP_CALL( SCIPcaptureVar(scip, auxvarxy) );
123 
124  return SCIP_OKAY;
125 }
126 
127 /** helper method to clear separation data */
128 static
130  SCIP* scip, /**< SCIP data structure */
131  SCIP_SEPADATA* sepadata /**< separator data */
132  )
133 {
134  int i;
135 
136  assert(sepadata != NULL);
137 
138  SCIPdebugMsg(scip, "clear separation data\n");
139 
140  /* release captured variables */
141  for( i = 0; i < 5 * sepadata->nminors; ++i )
142  {
143  assert(sepadata->minors[i] != NULL);
144  SCIP_CALL( SCIPreleaseVar(scip, &sepadata->minors[i]) );
145  }
146 
147  /* free memory */
148  SCIPfreeBlockMemoryArrayNull(scip, &sepadata->minors, sepadata->minorssize);
149 
150  /* reset counters */
151  sepadata->nminors = 0;
152  sepadata->minorssize = 0;
153 
154  return SCIP_OKAY;
155 }
156 
157 /** helper method to identify non-overlapping constraints in circle packing */
158 static
160  SCIP* scip, /**< SCIP data structure */
161  SCIP_CONS* cons /**< nonlinear constraint */
162  )
163 {
164  SCIP_EXPR* root;
165  SCIP_VAR* quadvars[4] = {NULL, NULL, NULL, NULL};
166  SCIP_VAR* bilinvars[4] = {NULL, NULL, NULL, NULL};
167  int nbilinvars = 0;
168  int nquadvars = 0;
169  int nchildren;
170  int i;
171 
172  assert(scip != NULL);
173  assert(cons != NULL);
174 
175  root = SCIPgetExprNonlinear(cons);
176  assert(root != NULL);
177  nchildren = SCIPexprGetNChildren(root);
178 
179  /* non-overlapping constraint has 6 terms (2 bilinear + 4 quadratic) */
180  if( nchildren != 6 || !SCIPisExprSum(scip, root) )
181  return FALSE;
182 
183  for( i = 0; i < nchildren; ++i )
184  {
185  SCIP_EXPR* expr;
186  SCIP_EXPR** children;
187 
188  /* get child */
189  expr = SCIPexprGetChildren(root)[i];
190  assert(expr != NULL);
191  children = SCIPexprGetChildren(expr);
192 
193  /* case: expr = x^2; x is no auxiliary variable */
194  if( SCIPisExprPower(scip, expr) && SCIPgetExponentExprPow(expr) == 2.0
195  && SCIPisExprVar(scip, children[0]) )
196  {
197  SCIP_VAR* x;
198 
199  /* too many quadratic variables -> stop */
200  if( nquadvars > 3 )
201  return FALSE;
202 
203  x = SCIPgetVarExprVar(children[0]);
204  assert(x != NULL);
205 
206  quadvars[nquadvars++] = x;
207  }
208  /* case: expr = x * y; x and y are no auxiliary variables */
209  else if( SCIPisExprProduct(scip, expr) && SCIPexprGetNChildren(expr) == 2
210  && SCIPisExprVar(scip, children[0]) && SCIPisExprVar(scip, children[1]) )
211  {
212  SCIP_VAR* x;
213  SCIP_VAR* y;
214 
215  /* too many bilinear variables -> stop */
216  if( nbilinvars > 2 )
217  return FALSE;
218 
219  x = SCIPgetVarExprVar(children[0]);
220  assert(x != NULL);
221  y = SCIPgetVarExprVar(children[1]);
222  assert(y != NULL);
223  assert(x != y);
224 
225  bilinvars[nbilinvars++] = x;
226  bilinvars[nbilinvars++] = y;
227  }
228  else
229  {
230  return FALSE;
231  }
232  }
233 
234  /* number of bilinear and quadratic terms do not fit */
235  if( nbilinvars != 4 || nquadvars != 4 )
236  return FALSE;
237 
238  /* each quadratic variable has to appear in exactly one bilinear terms */
239  for( i = 0; i < nquadvars; ++i )
240  {
241  int counter = 0;
242  int j;
243 
244  for( j = 0; j < nbilinvars; ++j )
245  {
246  if( quadvars[i] == bilinvars[j] )
247  ++counter;
248  }
249 
250  if( counter != 1 )
251  return FALSE;
252  }
253 
254  return TRUE;
255 }
256 
257 /** helper method to get the variables associated to a minor */
258 static
260  SCIP_SEPADATA* sepadata, /**< separator data */
261  int idx, /**< index of the stored minor */
262  SCIP_VAR** x, /**< pointer to store x variable */
263  SCIP_VAR** y, /**< pointer to store x variable */
264  SCIP_VAR** auxvarxx, /**< pointer to store auxiliary variable for x*x */
265  SCIP_VAR** auxvaryy, /**< pointer to store auxiliary variable for y*y */
266  SCIP_VAR** auxvarxy /**< pointer to store auxiliary variable for x*y */
267  )
268 {
269  assert(sepadata != NULL);
270  assert(idx >= 0 && idx < sepadata->nminors);
271  assert(auxvarxx != NULL);
272  assert(auxvaryy != NULL);
273  assert(auxvarxy != NULL);
274 
275  *x = sepadata->minors[5 * idx];
276  *y = sepadata->minors[5 * idx + 1];
277  *auxvarxx = sepadata->minors[5 * idx + 2];
278  *auxvaryy = sepadata->minors[5 * idx + 3];
279  *auxvarxy = sepadata->minors[5 * idx + 4];
280 
281  return SCIP_OKAY;
282 }
283 
284 /** method to detect and store principal minors */
285 static
287  SCIP* scip, /**< SCIP data structure */
288  SCIP_SEPADATA* sepadata /**< separator data */
289  )
290 {
291  SCIP_CONSHDLR* conshdlr;
292  SCIP_EXPRITER* it;
293  SCIP_HASHMAP* quadmap;
294  SCIP_VAR** xs;
295  SCIP_VAR** ys;
296  SCIP_VAR** auxvars;
297  int* perm = NULL;
298  int nbilinterms = 0;
299  int nquadterms = 0;
300  int maxminors;
301  int c;
302  int i;
303 
304 #ifdef SCIP_STATISTIC
305  SCIP_Real totaltime = -SCIPgetTotalTime(scip);
306 #endif
307 
308  assert(sepadata != NULL);
309 
310  /* check whether minor detection has been called already */
311  if( sepadata->detectedminors )
312  return SCIP_OKAY;
313 
314  assert(sepadata->minors == NULL);
315  assert(sepadata->nminors == 0);
316 
317  /* we assume that the auxiliary variables in the nonlinear constraint handler have been already generated */
318  sepadata->detectedminors = TRUE;
319 
320  /* check whether there are nonlinear constraints available */
321  conshdlr = SCIPfindConshdlr(scip, "nonlinear");
322  if( conshdlr == NULL || SCIPconshdlrGetNConss(conshdlr) == 0 )
323  return SCIP_OKAY;
324 
325  SCIPdebugMsg(scip, "call detectMinors()\n");
326 
327  /* allocate memory */
328  SCIP_CALL( SCIPcreateExpriter(scip, &it) );
329  SCIP_CALL( SCIPhashmapCreate(&quadmap, SCIPblkmem(scip), SCIPgetNVars(scip)) );
330  SCIP_CALL( SCIPallocBufferArray(scip, &xs, SCIPgetNVars(scip)) );
331  SCIP_CALL( SCIPallocBufferArray(scip, &ys, SCIPgetNVars(scip)) );
332  SCIP_CALL( SCIPallocBufferArray(scip, &auxvars, SCIPgetNVars(scip)) );
333 
334  /* initialize iterator */
337 
338  for( c = 0; c < SCIPconshdlrGetNConss(conshdlr); ++c )
339  {
340  SCIP_CONS* cons;
341  SCIP_EXPR* expr;
342  SCIP_EXPR* root;
343 
344  cons = SCIPconshdlrGetConss(conshdlr)[c];
345  assert(cons != NULL);
346  root = SCIPgetExprNonlinear(cons);
347  assert(root != NULL);
348 
349  /* ignore circle packing constraints; the motivation for this is that in circle packing instance not only the SDP
350  * relaxation is weak (see "Packing circles in a square: a theoretical comparison of various convexification
351  * techniques", http://www.optimization-online.org/DB_HTML/2017/03/5911.html), but it also hurts performance
352  */
353  if( sepadata->ignorepackingconss && isPackingCons(scip, cons) )
354  {
355  SCIPdebugMsg(scip, "ignore packing constraints %s\n", SCIPconsGetName(cons));
356  continue;
357  }
358 
359  for( expr = SCIPexpriterRestartDFS(it, root); !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) ) /*lint !e441*/ /*lint !e440*/
360  {
361  SCIP_EXPR** children;
362  SCIP_VAR* auxvar;
363 
364  SCIPdebugMsg(scip, "visit expression %p in constraint %s\n", (void*)expr, SCIPconsGetName(cons));
365 
366  /* check whether the expression has an auxiliary variable */
367  auxvar = SCIPgetExprAuxVarNonlinear(expr);
368  if( auxvar == NULL )
369  {
370  SCIPdebugMsg(scip, "expression has no auxiliary variable -> skip\n");
371  continue;
372  }
373 
374  children = SCIPexprGetChildren(expr);
375 
376  /* check for expr = (x)^2 */
377  if( SCIPexprGetNChildren(expr) == 1 && SCIPisExprPower(scip, expr)
378  && SCIPgetExponentExprPow(expr) == 2.0
379  && SCIPgetExprAuxVarNonlinear(children[0]) != NULL )
380  {
381  SCIP_VAR* quadvar;
382 
383  assert(children[0] != NULL);
384 
385  quadvar = SCIPgetExprAuxVarNonlinear(children[0]);
386  assert(quadvar != NULL);
387  assert(!SCIPhashmapExists(quadmap, (void*)quadvar));
388  SCIPdebugMsg(scip, "found %s = (%s)^2\n", SCIPvarGetName(auxvar), SCIPvarGetName(quadvar));
389 
390  /* hash the quadratic variable to its corresponding auxiliary variable */
391  SCIP_CALL( SCIPhashmapInsert(quadmap, (void*)quadvar, auxvar) );
392  ++nquadterms;
393  }
394  /* check for expr = x * y */
395  else if( SCIPexprGetNChildren(expr) == 2 && SCIPisExprProduct(scip, expr)
396  && SCIPgetExprAuxVarNonlinear(children[0]) != NULL && SCIPgetExprAuxVarNonlinear(children[1]) != NULL )
397  {
398  SCIP_VAR* x;
399  SCIP_VAR* y;
400 
401  assert(children[0] != NULL);
402  assert(children[1] != NULL);
403 
404  x = SCIPgetExprAuxVarNonlinear(children[0]);
405  y = SCIPgetExprAuxVarNonlinear(children[1]);
406 
407  /* ignore binary variables */
408  if( !SCIPvarIsBinary(x) && !SCIPvarIsBinary(y) )
409  {
410  xs[nbilinterms] = SCIPgetExprAuxVarNonlinear(children[0]);
411  ys[nbilinterms] = SCIPgetExprAuxVarNonlinear(children[1]);
412  auxvars[nbilinterms] = auxvar;
413  SCIPdebugMsg(scip, "found %s = %s * %s\n", SCIPvarGetName(auxvar), SCIPvarGetName(xs[nbilinterms]), SCIPvarGetName(ys[nbilinterms]));
414  ++nbilinterms;
415  }
416  }
417  }
418  }
419  assert(nbilinterms < SCIPgetNVars(scip));
420  SCIPdebugMsg(scip, "stored %d bilinear terms in total\n", nbilinterms);
421 
422  /* use max(maxminorsconst, maxminorsfac * # quadratic terms) as a limit for the maximum number of minors */
423  maxminors = (int) MAX(sepadata->maxminorsconst, sepadata->maxminorsfac * nquadterms);
424  SCIPdebugMsg(scip, "maximum number of minors = %d\n", maxminors);
425 
426  /* permute bilinear terms if there are too many of them; the motivation for this is that we don't want to
427  * prioritize variables because of the order in the bilinear terms where they appear; however, variables that
428  * appear more often in bilinear terms might be more important than others so the corresponding bilinear terms
429  * are more likely to be chosen
430  */
431  if( maxminors < nbilinterms && maxminors < SQR(nquadterms) )
432  {
433  SCIP_CALL( SCIPallocBufferArray(scip, &perm, nbilinterms) );
434 
435  for( i = 0; i < nbilinterms; ++i )
436  perm[i] = i;
437 
438  /* permute array */
439  SCIPrandomPermuteIntArray(sepadata->randnumgen, perm, 0, nbilinterms);
440  }
441 
442  /* store 2x2 principal minors */
443  for( i = 0; i < nbilinterms && sepadata->nminors < maxminors; ++i )
444  {
445  SCIP_VAR* x;
446  SCIP_VAR* y;
447  SCIP_VAR* auxvarxy;
448 
449  if( perm == NULL )
450  {
451  x = xs[i];
452  y = ys[i];
453  auxvarxy = auxvars[i];
454  }
455  else
456  {
457  x = xs[perm[i]];
458  y = ys[perm[i]];
459  auxvarxy = auxvars[perm[i]];
460  }
461 
462  assert(x != NULL);
463  assert(y != NULL);
464  assert(auxvarxy != NULL);
465  assert(x != y);
466 
467  if( SCIPhashmapExists(quadmap, (void*)x) && SCIPhashmapExists(quadmap, (void*)y) )
468  {
469  SCIP_VAR* auxvarxx;
470  SCIP_VAR* auxvaryy;
471 
472  auxvarxx = (SCIP_VAR*)SCIPhashmapGetImage(quadmap, (void*)x);
473  assert(auxvarxx != NULL);
474  auxvaryy = (SCIP_VAR*)SCIPhashmapGetImage(quadmap, (void*)y);
475  assert(auxvaryy != NULL);
476 
477  /* store minor into the separation data */
478  SCIP_CALL( sepadataAddMinor(scip, sepadata, x, y, auxvarxx, auxvaryy, auxvarxy) );
479  }
480  }
481  SCIPdebugMsg(scip, "found %d principal minors in total\n", sepadata->nminors);
482 
483  /* free memory */
484  SCIPfreeBufferArrayNull(scip, &perm);
485  SCIPfreeBufferArray(scip, &auxvars);
486  SCIPfreeBufferArray(scip, &ys);
487  SCIPfreeBufferArray(scip, &xs);
488  SCIPhashmapFree(&quadmap);
489  SCIPfreeExpriter(&it);
490 
491 #ifdef SCIP_STATISTIC
492  totaltime += SCIPgetTotalTime(scip);
493  SCIPstatisticMessage("MINOR DETECT %s %f %d %d\n", SCIPgetProbName(scip), totaltime, sepadata->nminors, maxminors);
494 #endif
495 
496  return SCIP_OKAY;
497 }
498 
499 /** helper method to compute eigenvectors and eigenvalues */
500 static
502  SCIP* scip, /**< SCIP data structure */
503  SCIP_Real x, /**< solution value of x */
504  SCIP_Real y, /**< solution value of y */
505  SCIP_Real xx, /**< solution value of x*x */
506  SCIP_Real yy, /**< solution value of y*y */
507  SCIP_Real xy, /**< solution value of x*y */
508  SCIP_Real* eigenvals, /**< array to store eigenvalues (at least of size 3) */
509  SCIP_Real* eigenvecs, /**< array to store eigenvalues (at least of size 9) */
510  SCIP_Bool* success /**< pointer to store whether eigenvalue computation was successful */
511  )
512 {
513  assert(eigenvals != NULL);
514  assert(eigenvecs != NULL);
515  assert(success != NULL);
516 
517  *success = TRUE;
518 
519  /* construct matrix */
520  eigenvecs[0] = 1.0;
521  eigenvecs[1] = x;
522  eigenvecs[2] = y;
523  eigenvecs[3] = x;
524  eigenvecs[4] = xx;
525  eigenvecs[5] = xy;
526  eigenvecs[6] = y;
527  eigenvecs[7] = xy;
528  eigenvecs[8] = yy;
529 
530  /* use LAPACK to compute the eigenvalues and eigenvectors */
531  if( SCIPcallLapackDsyevIpopt(TRUE, 3, eigenvecs, eigenvals) != SCIP_OKAY )
532  {
533  SCIPdebugMsg(scip, "Failed to compute eigenvalues and eigenvectors of augmented quadratic form matrix.\n");
534  *success = FALSE;
535  }
536 
537  return SCIP_OKAY;
538 }
539 
540 /** generate and add a cut */
541 static
543  SCIP* scip, /**< SCIP data structure */
544  SCIP_SEPA* sepa, /**< separator */
545  SCIP_SOL* sol, /**< solution to separate (might be NULL) */
546  SCIP_VAR* x, /**< x variable */
547  SCIP_VAR* y, /**< y variable */
548  SCIP_VAR* xx, /**< auxiliary variable for x*x */
549  SCIP_VAR* yy, /**< auxiliary variable for y*y */
550  SCIP_VAR* xy, /**< auxiliary variable for x*y */
551  SCIP_Real* eigenvec, /**< array containing an eigenvector */
552  SCIP_Real eigenval, /**< eigenvalue */
553  SCIP_Real mincutviol, /**< minimal required violation */
554  SCIP_RESULT* result /**< pointer to update the result */
555  )
556 {
557  SCIP_VAR* vars[5] = {x, y, xx, yy, xy};
558  SCIP_Real coefs[5];
559  SCIP_Real constant;
560  SCIP_ROWPREP* rowprep;
561  SCIP_Bool success;
562 
563  assert(x != NULL);
564  assert(y != NULL);
565  assert(xx != NULL);
566  assert(yy != NULL);
567  assert(xy != NULL);
568  assert(eigenvec != NULL);
569  assert(mincutviol >= 0.0);
570  assert(result != NULL);
571 
572  /* check whether the resulting cut is violated enough */
573  if( !SCIPisFeasLT(scip, eigenval, -mincutviol) )
574  return SCIP_OKAY;
575 
576  /* the resulting cut reads as
577  * (1 x y ) (v0)
578  * (v0 v1 v2) (x xx xy) (v1) >= 0
579  * (y xy yy) (v2)
580  * where v is the eigenvector corresponding to a negative eigenvalue
581  * that is,
582  * v0^2 + 2 v0 v1 * x + 2 v0 v2 * y + v1^2 * xx + v2^2 * yy + 2 v1 v2 * xy >= 0
583  */
584  constant = SQR(eigenvec[0]);
585  coefs[0] = 2.0 * eigenvec[0] * eigenvec[1];
586  coefs[1] = 2.0 * eigenvec[0] * eigenvec[2];
587  coefs[2] = SQR(eigenvec[1]);
588  coefs[3] = SQR(eigenvec[2]);
589  coefs[4] = 2.0 * eigenvec[1] * eigenvec[2];
590 
591  /* create rowprep */
593  SCIP_CALL( SCIPaddRowprepTerms(scip, rowprep, 5, vars, coefs) );
594  SCIProwprepAddConstant(rowprep, constant);
595  SCIPdebug( SCIPprintRowprep(scip, rowprep, NULL) );
596  SCIPdebugMsg(scip, "cut violation %g mincutviol = %g\n", SCIPgetRowprepViolation(scip, rowprep, sol, NULL), mincutviol);
597 
598  /* cleanup coefficient and side, esp treat epsilon to integral values; don't consider scaling up here */
599  SCIP_CALL( SCIPcleanupRowprep(scip, rowprep, NULL, 0.0, NULL, &success) );
600 
601  /* check cut violation */
602  if( success && SCIPgetRowprepViolation(scip, rowprep, sol, NULL) > mincutviol )
603  {
604  SCIP_ROW* row;
605  SCIP_Bool infeasible;
606 
607  /* set name of rowprep */
608  (void) SCIPsnprintf(SCIProwprepGetName(rowprep), SCIP_MAXSTRLEN, "minor_%s_%s_%s_%lld", SCIPvarGetName(xx), SCIPvarGetName(yy),
609  SCIPvarGetName(xy), SCIPgetNLPs(scip));
610 
611  /* create, add, and release row */
612  SCIP_CALL( SCIPgetRowprepRowSepa(scip, &row, rowprep, sepa) );
613  SCIP_CALL( SCIPaddRow(scip, row, FALSE, &infeasible) );
614  SCIP_CALL( SCIPreleaseRow(scip, &row) );
615 
616  /* update result pointer */
617  *result = infeasible ? SCIP_CUTOFF : SCIP_SEPARATED;
618  }
619 
620  /* free rowprep */
621  SCIPfreeRowprep(scip, &rowprep);
622 
623  return SCIP_OKAY;
624 }
625 
626 /** separates cuts for stored principal minors */
627 static
629  SCIP* scip, /**< SCIP data structure */
630  SCIP_SEPA* sepa, /**< separator */
631  SCIP_SOL* sol, /**< primal solution that should be separated, or NULL for LP solution */
632  SCIP_RESULT* result /**< pointer to store the result of the separation call */
633  )
634 {
635  SCIP_SEPADATA* sepadata;
636  int i;
637 
638  assert(sepa != NULL);
639  assert(result != NULL);
640 
641  *result = SCIP_DIDNOTRUN;
642 
643  sepadata = SCIPsepaGetData(sepa);
644  assert(sepadata != NULL);
645 
646  /* check whether there are some minors available */
647  if( sepadata->nminors == 0 )
648  return SCIP_OKAY;
649 
650  *result = SCIP_DIDNOTFIND;
651 
652  for( i = 0; i < sepadata->nminors && (*result != SCIP_CUTOFF); ++i )
653  {
654  SCIP_Real eigenvals[3];
655  SCIP_Real eigenvecs[9];
656  SCIP_VAR* x;
657  SCIP_VAR* y;
658  SCIP_VAR* xx;
659  SCIP_VAR* yy;
660  SCIP_VAR* xy;
661  SCIP_Real solx;
662  SCIP_Real soly;
663  SCIP_Real solxx;
664  SCIP_Real solyy;
665  SCIP_Real solxy;
666  SCIP_Bool success;
667  int k;
668 
669  /* get variables of the i-th minor */
670  SCIP_CALL( getMinorVars(sepadata, i, &x, &y, &xx, &yy, &xy) );
671  assert(x != NULL);
672  assert(y != NULL);
673  assert(xx != NULL);
674  assert(yy != NULL);
675  assert(xy != NULL);
676 
677  /* get current solution values */
678  solx = SCIPgetSolVal(scip, sol, x);
679  soly = SCIPgetSolVal(scip, sol, y);
680  solxx = SCIPgetSolVal(scip, sol, xx);
681  solyy = SCIPgetSolVal(scip, sol, yy);
682  solxy = SCIPgetSolVal(scip, sol, xy);
683  SCIPdebugMsg(scip, "solution values (x,y,xx,yy,xy)=(%g,%g,%g,%g,%g)\n", solx, soly, solxx, solyy, solxy);
684 
685  /* compute eigenvalues and eigenvectors */
686  SCIP_CALL( getEigenValues(scip, solx, soly, solxx, solyy, solxy, eigenvals, eigenvecs, &success) );
687  if( !success )
688  continue;
689 
690  /* try to generate a cut for each negative eigenvalue */
691  for( k = 0; k < 3 && (*result != SCIP_CUTOFF); ++k )
692  {
693  SCIPdebugMsg(scip, "eigenvalue = %g eigenvector = (%g,%g,%g)\n", eigenvals[k], eigenvecs[3*k], eigenvecs[3*k + 1], eigenvecs[3*k + 2]);
694  SCIP_CALL( addCut(scip, sepa, sol, x, y, xx, yy, xy, &eigenvecs[3*k], eigenvals[k], sepadata->mincutviol, result) );
695  SCIPdebugMsg(scip, "result: %d\n", *result);
696  }
697  }
698 
699  return SCIP_OKAY;
700 }
701 
702 /*
703  * Callback methods of separator
704  */
705 
706 /** copy method for separator plugins (called when SCIP copies plugins) */
707 static
708 SCIP_DECL_SEPACOPY(sepaCopyMinor)
709 { /*lint --e{715}*/
710  assert(scip != NULL);
711  assert(sepa != NULL);
712  assert(strcmp(SCIPsepaGetName(sepa), SEPA_NAME) == 0);
713 
714  /* call inclusion method of constraint handler */
716 
717  return SCIP_OKAY;
718 }
719 
720 
721 /** destructor of separator to free user data (called when SCIP is exiting) */
722 static
723 SCIP_DECL_SEPAFREE(sepaFreeMinor)
724 { /*lint --e{715}*/
725  SCIP_SEPADATA* sepadata;
726 
727  sepadata = SCIPsepaGetData(sepa);
728  assert(sepadata != NULL);
729  assert(sepadata->minors == NULL);
730  assert(sepadata->nminors == 0);
731  assert(sepadata->minorssize == 0);
732 
733  /* free separator data */
734  SCIPfreeBlockMemory(scip, &sepadata);
735  SCIPsepaSetData(sepa, NULL);
736 
737  return SCIP_OKAY;
738 }
739 
740 
741 /** initialization method of separator (called after problem was transformed) */
742 static
743 SCIP_DECL_SEPAINIT(sepaInitMinor)
744 { /*lint --e{715}*/
745  SCIP_SEPADATA* sepadata;
746 
747  /* get separator data */
748  sepadata = SCIPsepaGetData(sepa);
749  assert(sepadata != NULL);
750  assert(sepadata->randnumgen == NULL);
751 
752  /* create random number generator */
753  SCIP_CALL( SCIPcreateRandom(scip, &sepadata->randnumgen, DEFAULT_RANDSEED, TRUE) );
754 
755  return SCIP_OKAY;
756 }
757 
758 
759 /** deinitialization method of separator (called before transformed problem is freed) */
760 static
761 SCIP_DECL_SEPAEXIT(sepaExitMinor)
762 { /*lint --e{715}*/
763  SCIP_SEPADATA* sepadata;
764 
765  /* get separator data */
766  sepadata = SCIPsepaGetData(sepa);
767  assert(sepadata != NULL);
768  assert(sepadata->randnumgen != NULL);
769 
770  /* free random number generator */
771  SCIPfreeRandom(scip, &sepadata->randnumgen);
772 
773  return SCIP_OKAY;
774 }
775 
776 
777 /** solving process initialization method of separator (called when branch and bound process is about to begin) */
778 static
779 SCIP_DECL_SEPAINITSOL(sepaInitsolMinor)
780 { /*lint --e{715}*/
781  return SCIP_OKAY;
782 }
783 
784 
785 /** solving process deinitialization method of separator (called before branch and bound process data is freed) */
786 static
787 SCIP_DECL_SEPAEXITSOL(sepaExitsolMinor)
788 { /*lint --e{715}*/
789  SCIP_SEPADATA* sepadata;
790 
791  sepadata = SCIPsepaGetData(sepa);
792  assert(sepadata != NULL);
793 
794  /* clear separation data */
795  SCIP_CALL( sepadataClear(scip, sepadata) );
796 
797  return SCIP_OKAY;
798 }
799 
800 
801 /** LP solution separation method of separator */
802 static
803 SCIP_DECL_SEPAEXECLP(sepaExeclpMinor)
804 { /*lint --e{715}*/
805  SCIP_SEPADATA* sepadata;
806  int ncalls;
807 
808  /* need routine to compute eigenvalues/eigenvectors */
810  return SCIP_OKAY;
811 
812  sepadata = SCIPsepaGetData(sepa);
813  assert(sepadata != NULL);
814  ncalls = SCIPsepaGetNCallsAtNode(sepa);
815 
816  /* only call the separator a given number of times at each node */
817  if( (depth == 0 && sepadata->maxroundsroot >= 0 && ncalls >= sepadata->maxroundsroot)
818  || (depth > 0 && sepadata->maxrounds >= 0 && ncalls >= sepadata->maxrounds) )
819  {
820  SCIPdebugMsg(scip, "reached round limit for node\n");
821  return SCIP_OKAY;
822  }
823 
824  /* try to detect minors */
825  SCIP_CALL( detectMinors(scip, sepadata) );
826 
827  /* call separation method */
828  SCIP_CALL( separatePoint(scip, sepa, NULL, result) );
829 
830  return SCIP_OKAY;
831 }
832 
833 
834 /** arbitrary primal solution separation method of separator */
835 static
836 SCIP_DECL_SEPAEXECSOL(sepaExecsolMinor)
837 { /*lint --e{715}*/
838  SCIP_SEPADATA* sepadata;
839  int ncalls;
840 
841  /* need routine to compute eigenvalues/eigenvectors */
843  return SCIP_OKAY;
844 
845  sepadata = SCIPsepaGetData(sepa);
846  assert(sepadata != NULL);
847  ncalls = SCIPsepaGetNCallsAtNode(sepa);
848 
849  /* only call the separator a given number of times at each node */
850  if( (depth == 0 && sepadata->maxroundsroot >= 0 && ncalls >= sepadata->maxroundsroot)
851  || (depth > 0 && sepadata->maxrounds >= 0 && ncalls >= sepadata->maxrounds) )
852  {
853  SCIPdebugMsg(scip, "reached round limit for node\n");
854  return SCIP_OKAY;
855  }
856 
857  /* try to detect minors */
859 
860  /* call separation method */
861  SCIP_CALL( separatePoint(scip, sepa, sol, result) );
862 
863  return SCIP_OKAY;
864 }
865 
866 /*
867  * separator specific interface methods
868  */
869 
870 /** creates the minor separator and includes it in SCIP */
872  SCIP* scip /**< SCIP data structure */
873  )
874 {
875  SCIP_SEPADATA* sepadata = NULL;
876  SCIP_SEPA* sepa = NULL;
877 
878  /* create minor separator data */
879  SCIP_CALL( SCIPallocBlockMemory(scip, &sepadata) );
880  BMSclearMemory(sepadata);
881 
882  /* include separator */
885  sepaExeclpMinor, sepaExecsolMinor,
886  sepadata) );
887 
888  assert(sepa != NULL);
889 
890  /* set non fundamental callbacks via setter functions */
891  SCIP_CALL( SCIPsetSepaCopy(scip, sepa, sepaCopyMinor) );
892  SCIP_CALL( SCIPsetSepaFree(scip, sepa, sepaFreeMinor) );
893  SCIP_CALL( SCIPsetSepaInit(scip, sepa, sepaInitMinor) );
894  SCIP_CALL( SCIPsetSepaExit(scip, sepa, sepaExitMinor) );
895  SCIP_CALL( SCIPsetSepaInitsol(scip, sepa, sepaInitsolMinor) );
896  SCIP_CALL( SCIPsetSepaExitsol(scip, sepa, sepaExitsolMinor) );
897 
898  /* add minor separator parameters */
900  "separating/" SEPA_NAME "/maxminorsconst",
901  "constant for the maximum number of minors, i.e., max(const, fac * # quadratic terms)",
902  &sepadata->maxminorsconst, FALSE, DEFAULT_MAXMINORSCONST, 0, INT_MAX, NULL, NULL) );
903 
905  "separating/" SEPA_NAME "/maxminorsfac",
906  "factor for the maximum number of minors, i.e., max(const, fac * # quadratic terms)",
907  &sepadata->maxminorsfac, FALSE, DEFAULT_MAXMINORSFAC, 0.0, SCIP_REAL_MAX, NULL, NULL) );
908 
910  "separating/" SEPA_NAME "/mincutviol",
911  "minimum required violation of a cut",
912  &sepadata->mincutviol, FALSE, DEFAULT_MINCUTVIOL, 0.0, SCIP_REAL_MAX, NULL, NULL) );
913 
915  "separating/" SEPA_NAME "/maxrounds",
916  "maximal number of separation rounds per node (-1: unlimited)",
917  &sepadata->maxrounds, FALSE, DEFAULT_MAXROUNDS, -1, INT_MAX, NULL, NULL) );
918 
920  "separating/" SEPA_NAME "/maxroundsroot",
921  "maximal number of separation rounds in the root node (-1: unlimited)",
922  &sepadata->maxroundsroot, FALSE, DEFAULT_MAXROUNDSROOT, -1, INT_MAX, NULL, NULL) );
923 
925  "separating/" SEPA_NAME "/ignorepackingconss",
926  "whether to ignore circle packing constraints during minor detection",
927  &sepadata->ignorepackingconss, FALSE, DEFAULT_IGNOREPACKINGCONSS, NULL, NULL) );
928 
929  return SCIP_OKAY;
930 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
void SCIPfreeRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen)
#define DEFAULT_MINCUTVIOL
Definition: sepa_minor.c:43
SCIP_Bool SCIPisIpoptAvailableIpopt(void)
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip_mem.h:90
SCIP_RETCODE SCIPexpriterInit(SCIP_EXPRITER *iterator, SCIP_EXPR *expr, SCIP_EXPRITER_TYPE type, SCIP_Bool allowrevisit)
Definition: expriter.c:491
#define SEPA_MAXBOUNDDIST
Definition: sepa_minor.c:37
static SCIP_DECL_SEPAINITSOL(sepaInitsolMinor)
Definition: sepa_minor.c:779
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define SEPA_USESSUBSCIP
Definition: sepa_minor.c:38
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:877
int SCIPexprGetNChildren(SCIP_EXPR *expr)
Definition: expr.c:3798
static SCIP_DECL_SEPAEXECSOL(sepaExecsolMinor)
Definition: sepa_minor.c:836
#define SCIP_MAXSTRLEN
Definition: def.h:293
static SCIP_RETCODE separatePoint(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_RESULT *result)
Definition: sepa_minor.c:628
static SCIP_RETCODE detectMinors(SCIP *scip, SCIP_SEPADATA *sepadata)
Definition: sepa_minor.c:286
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:130
#define SEPA_FREQ
Definition: sepa_minor.c:36
static SCIP_DECL_SEPAEXITSOL(sepaExitsolMinor)
Definition: sepa_minor.c:787
void SCIPprintRowprep(SCIP *scip, SCIP_ROWPREP *rowprep, FILE *file)
Definition: misc_rowprep.c:769
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1245
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17431
SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4547
SCIP_RETCODE SCIPcallLapackDsyevIpopt(SCIP_Bool computeeigenvectors, int N, SCIP_Real *a, SCIP_Real *w)
#define FALSE
Definition: def.h:87
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3014
SCIP_RETCODE SCIPgetRowprepRowSepa(SCIP *scip, SCIP_ROW **row, SCIP_ROWPREP *rowprep, SCIP_SEPA *sepa)
char * SCIProwprepGetName(SCIP_ROWPREP *rowprep)
Definition: misc_rowprep.c:664
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10755
SCIP_Real SCIPgetExponentExprPow(SCIP_EXPR *expr)
Definition: expr_pow.c:3343
#define TRUE
Definition: def.h:86
#define DEFAULT_MAXMINORSFAC
Definition: sepa_minor.c:42
#define SCIPdebug(x)
Definition: pub_message.h:84
const char * SCIPsepaGetName(SCIP_SEPA *sepa)
Definition: sepa.c:720
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
#define SCIPstatisticMessage
Definition: pub_message.h:114
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:99
static SCIP_DECL_SEPACOPY(sepaCopyMinor)
Definition: sepa_minor.c:708
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3201
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:127
SCIP_RETCODE SCIPsetSepaCopy(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPACOPY((*sepacopy)))
Definition: scip_sepa.c:142
#define SCIP_EXPRITER_ENTEREXPR
Definition: type_expr.h:667
#define SCIPdebugMsg
Definition: scip_message.h:69
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:74
SCIP_VAR ** x
Definition: circlepacking.c:54
SCIP_Bool SCIPisExprProduct(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1454
SCIP_SEPADATA * SCIPsepaGetData(SCIP_SEPA *sepa)
Definition: sepa.c:610
const char * SCIPgetProbName(SCIP *scip)
Definition: scip_prob.c:1066
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3363
SCIP_RETCODE SCIPincludeSepaMinor(SCIP *scip)
Definition: sepa_minor.c:871
SCIP_EXPR ** SCIPexprGetChildren(SCIP_EXPR *expr)
Definition: expr.c:3808
#define DEFAULT_MAXMINORSCONST
Definition: sepa_minor.c:41
principal minor separator
SCIP_RETCODE SCIPsetSepaExit(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAEXIT((*sepaexit)))
Definition: scip_sepa.c:190
SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
Definition: expr_var.c:407
static SCIP_DECL_SEPAEXECLP(sepaExeclpMinor)
Definition: sepa_minor.c:803
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip_mem.h:128
int SCIPsepaGetNCallsAtNode(SCIP_SEPA *sepa)
Definition: sepa.c:847
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:48
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8085
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17251
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3048
void SCIPsepaSetData(SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata)
Definition: sepa.c:620
SCIP_EXPR * SCIPgetExprNonlinear(SCIP_CONS *cons)
static SCIP_DECL_SEPAEXIT(sepaExitMinor)
Definition: sepa_minor.c:761
#define NULL
Definition: lpi_spx1.cpp:155
SCIP_RETCODE SCIPsetSepaInitsol(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAINITSOL((*sepainitsol)))
Definition: scip_sepa.c:206
SCIP_Bool SCIPisExprSum(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1443
void SCIPfreeRowprep(SCIP *scip, SCIP_ROWPREP **rowprep)
Definition: misc_rowprep.c:558
static SCIP_RETCODE addCut(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_VAR *x, SCIP_VAR *y, SCIP_VAR *xx, SCIP_VAR *yy, SCIP_VAR *xy, SCIP_Real *eigenvec, SCIP_Real eigenval, SCIP_Real mincutviol, SCIP_RESULT *result)
Definition: sepa_minor.c:542
#define SCIP_CALL(x)
Definition: def.h:384
static SCIP_RETCODE sepadataAddMinor(SCIP *scip, SCIP_SEPADATA *sepadata, SCIP_VAR *x, SCIP_VAR *y, SCIP_VAR *auxvarxx, SCIP_VAR *auxvaryy, SCIP_VAR *auxvarxy)
Definition: sepa_minor.c:75
SCIP_Real SCIPgetRowprepViolation(SCIP *scip, SCIP_ROWPREP *rowprep, SCIP_SOL *sol, SCIP_Bool *reliable)
Definition: misc_rowprep.c:940
SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
Definition: scip_cut.c:241
int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4590
SCIP_RETCODE SCIPcreateExpriter(SCIP *scip, SCIP_EXPRITER **iterator)
Definition: scip_expr.c:2300
static SCIP_Bool isPackingCons(SCIP *scip, SCIP_CONS *cons)
Definition: sepa_minor.c:159
SCIP_RETCODE SCIPincludeSepaBasic(SCIP *scip, SCIP_SEPA **sepa, const char *name, const char *desc, int priority, int freq, SCIP_Real maxbounddist, SCIP_Bool usessubscip, SCIP_Bool delay, SCIP_DECL_SEPAEXECLP((*sepaexeclp)), SCIP_DECL_SEPAEXECSOL((*sepaexecsol)), SCIP_SEPADATA *sepadata)
Definition: scip_sepa.c:100
SCIP_RETCODE SCIPcreateRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen, unsigned int initialseed, SCIP_Bool useglobalseed)
Ipopt NLP interface.
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:115
SCIP_RETCODE SCIPsetSepaExitsol(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAEXITSOL((*sepaexitsol)))
Definition: scip_sepa.c:222
#define SCIP_Bool
Definition: def.h:84
SCIP_EXPR * SCIPexpriterRestartDFS(SCIP_EXPRITER *iterator, SCIP_EXPR *expr)
Definition: expriter.c:620
void SCIProwprepAddConstant(SCIP_ROWPREP *rowprep, SCIP_Real constant)
Definition: misc_rowprep.c:728
constraint handler for nonlinear constraints specified by algebraic expressions
#define DEFAULT_MAXROUNDSROOT
Definition: sepa_minor.c:46
void SCIPrandomPermuteIntArray(SCIP_RANDNUMGEN *randnumgen, int *array, int begin, int end)
Definition: misc.c:10044
#define MAX(x, y)
Definition: tclique_def.h:83
SCIP_EXPR * SCIPexpriterGetNext(SCIP_EXPRITER *iterator)
Definition: expriter.c:848
#define SEPA_PRIORITY
Definition: sepa_minor.c:35
static SCIP_DECL_SEPAFREE(sepaFreeMinor)
Definition: sepa_minor.c:723
SCIP_Bool SCIPisExprPower(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1465
#define BMSclearMemory(ptr)
Definition: memory.h:122
#define SEPA_DESC
Definition: sepa_minor.c:34
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:1991
#define SCIP_REAL_MAX
Definition: def.h:178
void SCIPexpriterSetStagesDFS(SCIP_EXPRITER *iterator, SCIP_EXPRITER_STAGE stopstages)
Definition: expriter.c:654
void SCIPfreeExpriter(SCIP_EXPRITER **iterator)
Definition: scip_expr.c:2314
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
Definition: scip_lp.c:1553
SCIP_RETCODE SCIPsetSepaFree(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAFREE((*sepafree)))
Definition: scip_sepa.c:158
SCIP_RETCODE SCIPsetSepaInit(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAINIT((*sepainit)))
Definition: scip_sepa.c:174
static SCIP_RETCODE getEigenValues(SCIP *scip, SCIP_Real x, SCIP_Real y, SCIP_Real xx, SCIP_Real yy, SCIP_Real xy, SCIP_Real *eigenvals, SCIP_Real *eigenvecs, SCIP_Bool *success)
Definition: sepa_minor.c:501
SCIP_Bool SCIPisExprVar(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1421
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1211
#define SCIP_Real
Definition: def.h:177
SCIP_VAR ** y
Definition: circlepacking.c:55
static SCIP_DECL_SEPAINIT(sepaInitMinor)
Definition: sepa_minor.c:743
#define SEPA_NAME
Definition: sepa_minor.c:33
#define SEPA_DELAY
Definition: sepa_minor.c:39
SCIP_Real SCIPgetTotalTime(SCIP *scip)
Definition: scip_timing.c:342
SCIP_RETCODE SCIPcreateRowprep(SCIP *scip, SCIP_ROWPREP **rowprep, SCIP_SIDETYPE sidetype, SCIP_Bool local)
Definition: misc_rowprep.c:538
static SCIP_RETCODE sepadataClear(SCIP *scip, SCIP_SEPADATA *sepadata)
Definition: sepa_minor.c:129
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip_mem.h:102
SCIP_RETCODE SCIPcleanupRowprep(SCIP *scip, SCIP_ROWPREP *rowprep, SCIP_SOL *sol, SCIP_Real minviol, SCIP_Real *viol, SCIP_Bool *success)
static SCIP_RETCODE getMinorVars(SCIP_SEPADATA *sepadata, int idx, SCIP_VAR **x, SCIP_VAR **y, SCIP_VAR **auxvarxx, SCIP_VAR **auxvaryy, SCIP_VAR **auxvarxy)
Definition: sepa_minor.c:259
SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:3096
SCIP_VAR * SCIPgetExprAuxVarNonlinear(SCIP_EXPR *expr)
SCIP_Bool SCIPexpriterIsEnd(SCIP_EXPRITER *iterator)
Definition: expriter.c:959
SCIPallocBlockMemory(scip, subsol))
SCIP_RETCODE SCIPaddRowprepTerms(SCIP *scip, SCIP_ROWPREP *rowprep, int nvars, SCIP_VAR **vars, SCIP_Real *coefs)
Definition: misc_rowprep.c:906
SCIP_Longint SCIPgetNLPs(SCIP *scip)
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1352
#define DEFAULT_MAXROUNDS
Definition: sepa_minor.c:45
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:130
#define DEFAULT_IGNOREPACKINGCONSS
Definition: sepa_minor.c:47
struct SCIP_SepaData SCIP_SEPADATA
Definition: type_sepa.h:43
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
#define DEFAULT_RANDSEED
Definition: sepa_minor.c:44