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