SCIP-SDP  4.0.0
prop_sdpobbt.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of SCIPSDP - a solving framework for mixed-integer */
4 /* semidefinite programs based on SCIP. */
5 /* */
6 /* Copyright (C) 2011-2013 Discrete Optimization, TU Darmstadt */
7 /* EDOM, FAU Erlangen-Nürnberg */
8 /* 2014-2021 Discrete Optimization, TU Darmstadt */
9 /* */
10 /* */
11 /* This program is free software; you can redistribute it and/or */
12 /* modify it under the terms of the GNU Lesser General Public License */
13 /* as published by the Free Software Foundation; either version 3 */
14 /* of the License, or (at your option) any later version. */
15 /* */
16 /* This program is distributed in the hope that it will be useful, */
17 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
18 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
19 /* GNU Lesser General Public License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with this program; if not, write to the Free Software */
23 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.*/
24 /* */
25 /* */
26 /* Based on SCIP - Solving Constraint Integer Programs */
27 /* Copyright (C) 2002-2021 Zuse Institute Berlin */
28 /* SCIP is distributed under the terms of the SCIP Academic Licence, */
29 /* see file COPYING in the SCIP distribution. */
30 /* */
31 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
32 
38 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
39 
40 /*#define SCIP_DEBUG*/
41 /*#define SCIP_MORE_DEBUG*/
42 
43 #include <assert.h>
44 #include <string.h>
45 
46 #include "prop_sdpobbt.h"
47 #include "relax_sdp.h"
48 
49 /* turn off lint warnings for whole file: */
50 /*lint --e{788,818}*/
51 
52 /* fundamental propagator properties */
53 #define PROP_NAME "sdp-obbt"
54 #define PROP_DESC "optimization-based bound tightening for SDPs"
55 #define PROP_PRIORITY -1100000
56 #define PROP_FREQ -1
57 #define PROP_DELAY FALSE
58 #define PROP_TIMING SCIP_PROPTIMING_AFTERLPLOOP
60 #define DEFAULT_PROPBIN FALSE
61 #define DEFAULT_PROPCONT TRUE
63 /* TODO: maybe make this a parameter and/or have different values for integral and continuous variables */
64 #define TOLERANCE_FACTOR 2000
66 /* TODO: fix memory error */
67 
68 
69 /*
70  * Data structures
71  */
72 
74 struct SCIP_PropData
75 {
76  SCIP_Bool propbin;
77  SCIP_Bool propcont;
78  SCIP_Bool delayed;
79  long long int lastnode;
80  SCIP_Real lastcufoffbound;
81  SCIP_Real sdpsolvergaptol;
82  SCIP_Bool propenabled;
83 };
84 
85 
86 /*
87  * Local methods
88  */
89 
90 static
91 SCIP_RETCODE addObjCutoff(
92  SCIP* scip
93  )
94 {
95  SCIP_ROW* row;
96  SCIP_VAR** vars;
97  char rowname[SCIP_MAXSTRLEN];
98  int nvars;
99  int v;
100 
101  assert( scip != NULL );
102  assert( SCIPinProbing(scip) );
103 
104  SCIPdebugMsg(scip, "create objective cutoff and add it to the LP-constraints\n");
105 
106  nvars = SCIPgetNVars(scip);
107  vars = SCIPgetVars(scip);
108 
109  /* create objective cutoff row; set local flag to FALSE since primal cutoff is globally valid */
110  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "obbtsdp_objcutoff");
111  SCIP_CALL( SCIPcreateEmptyRowUnspec(scip, &row, rowname, -SCIPinfinity(scip), SCIPgetCutoffbound(scip), FALSE, FALSE, FALSE) );
112  SCIP_CALL( SCIPcacheRowExtensions(scip, row) );
113 
114  for( v = 0; v < nvars; v++ )
115  {
116  SCIP_CALL( SCIPaddVarToRow(scip, row, vars[v], SCIPvarGetObj(vars[v])) );
117  }
118  SCIP_CALL( SCIPflushRowExtensions(scip, row) );
119 
120  /* add row to the LP-constraints */
121  SCIP_CALL( SCIPaddRowProbing(scip, row) );
122 
123  SCIP_CALL( SCIPreleaseRow(scip, &row) );
124 
125  return SCIP_OKAY;
126 }
127 
128 /*
129  * Callback methods of propagator
130  */
131 
132 
134 static
135 SCIP_DECL_PROPCOPY(propCopySdpObbt)
136 { /*lint --e{715}*/
137  assert( scip != NULL );
138  assert( prop != NULL );
139  assert( strcmp(SCIPpropGetName(prop), PROP_NAME) == 0 );
140 
141  /* call inclusion method of constraint handler */
142  SCIP_CALL( SCIPincludePropSdpObbt(scip) );
143 
144  return SCIP_OKAY;
145 }
146 
147 
149 static
150 SCIP_DECL_PROPFREE(propFreeSdpObbt)
151 { /*lint --e{715}*/
152  SCIP_PROPDATA* propdata;
153 
154  propdata = SCIPpropGetData(prop);
155  assert(propdata != NULL);
156 
157  SCIPfreeMemory(scip, &propdata);
158  SCIPpropSetData(prop, NULL);
159 
160  return SCIP_OKAY;
161 }
162 
164 static
165 SCIP_DECL_PROPEXIT(propExitSdpObbt)
166 { /*lint --e{715}*/
167  SCIP_PROPDATA* propdata;
168 
169  assert( prop != NULL );
170 
171  propdata = SCIPpropGetData(prop);
172 
173  propdata->lastnode = -1; /* we reset this to be able to run again if a new problem is read */
174 
175  return SCIP_OKAY;
176 }
177 
179 static
180 SCIP_DECL_PROPINITSOL(propInitsolSdpObbt)
181 { /*lint --e{715}*/
182  SCIP_PROPDATA* propdata;
183 
184  assert( prop != NULL );
185 
186  propdata = SCIPpropGetData(prop);
187 
188  if ( SCIPfindRelax(scip, "SDP") == NULL )
189  propdata->propenabled = FALSE;
190  else
191  {
192  propdata->propenabled = TRUE;
193  SCIP_CALL( SCIPgetRealParam(scip, "relaxing/SDP/sdpsolvergaptol", &(propdata->sdpsolvergaptol)) );
194  }
195 
196  return SCIP_OKAY;
197 }
198 
200 static
201 SCIP_DECL_PROPEXEC(propExecSdpObbt)
202 { /*lint --e{715}*/
203  int nvars;
204  SCIP_VAR** vars;
205  int v;
206  SCIP_PROPDATA* propdata;
207  SCIP_Real relaxval;
208  SCIP_Bool cutoff;
209  SCIP_Bool oldobjlimitparam;
210  SCIP_Real probingval;
211  SCIP_Bool success;
212  SCIP_RELAX* relaxsdp;
213  /* newbounds and newboundinds save the bound tightenings that should be inserted after probing ends, newboundinds saves the bounds the entries of newbounds
214  * belong to, for this the variables are sorted 1 to nvars (and entry i means vars[i-1]), with negative entry for the lower bound and positive for the upper */
215  SCIP_Real* newbounds;
216  int* newboundinds;
217  int nnewbounds;
218  int i;
219 
220  assert( scip != NULL );
221  assert( prop != NULL );
222  assert( result != NULL );
223 
224  propdata = SCIPpropGetData(prop);
225 
226  assert( propdata != NULL );
227 
228  *result = SCIP_DIDNOTRUN;
229 
230  if ( ! propdata->propenabled )
231  return SCIP_OKAY;
232 
233  SCIPdebugMsg(scip, "Executing propExecSdpObbt! \n");
234 
235  /* do not run in: presolving, repropagation, probing mode, subscips, if no objective propagation is allowed */
236  if ( SCIPgetStage(scip) != SCIP_STAGE_SOLVING || SCIPinRepropagation(scip) || SCIPinProbing(scip) || !SCIPallowWeakDualReds(scip) || (SCIPgetSubscipDepth(scip) > 0) )
237  {
238  SCIPdebugMsg(scip, "Aborting propExecSdpObbt because we are in presolving, repropagation, probing mode, a subscip or no objective "
239  "propagation is allowed!\n");
240  return SCIP_OKAY;
241  }
242 
243  /* delay if cutoffbound is infinite or no relaxation solution exists */
244  if ( SCIPisInfinity(scip, SCIPgetCutoffbound(scip)) || (! SCIPisRelaxSolValid(scip)) )
245  {
246  /* if we already delayed in the last call, abort to prevent an infinite loop */
247  if ( propdata->delayed )
248  {
249  SCIPdebugMsg(scip, "Aborting propExecSdpObbt since still cutoffbound is infinite or no relaxation solution exists\n");
250  return SCIP_OKAY;
251  }
252  *result = SCIP_DELAYED;
253  propdata->delayed = TRUE;
254  SCIPdebugMsg(scip, "Delaying propExecSdpObbt since cutoffbound is infinite or no relaxation solution exists\n");
255  return SCIP_OKAY;
256  }
257 
258  /* delay if best solution was found by trivial heuristic (since in this case the cutoffbound will generally not be good enough) or objective propagation onky */
259  if ( (SCIPgetBestSol(scip) == NULL) || ((SCIPsolGetHeur(SCIPgetBestSol(scip)) != NULL) && (strcmp(SCIPheurGetName(SCIPsolGetHeur(SCIPgetBestSol(scip))), "trivial") == 0)) )
260  {
261  /* if we already delayed in the last call, abort to prevent an infinite loop */
262  if ( propdata->delayed )
263  {
264  SCIPdebugMsg(scip, "Aborting propExecSdpObbt since still best solution was found by trivial heuristic or simple objective propagation, which will not be good enough\n");
265  return SCIP_OKAY;
266  }
267  *result = SCIP_DELAYED;
268  propdata->delayed = TRUE;
269  SCIPdebugMsg(scip, "Delaying propExecSdpObbt since best solution was found by trivial heuristic or simple objective propagation, which will not be good enough\n");
270  return SCIP_OKAY;
271  }
272 
273  if ( (SCIPnodeGetNumber(SCIPgetCurrentNode(scip)) == propdata->lastnode) && (SCIPisEQ(scip, SCIPgetCutoffbound(scip), propdata->lastcufoffbound)) )
274  {
275  SCIPdebugMsg(scip, "Not running again for node %" SCIP_LONGINT_FORMAT " with cutoffbound %g!\n", propdata->lastnode, propdata->lastcufoffbound);
276  return SCIP_OKAY;
277  }
278  else
279  {
280  propdata->lastnode = SCIPnodeGetNumber(SCIPgetCurrentNode(scip));
281  propdata->lastcufoffbound = SCIPgetCutoffbound(scip);
282  }
283 
284  propdata->delayed = FALSE;
285 
286  vars = SCIPgetVars(scip);
287  nvars = SCIPgetNVars(scip);
288 
289  /* start probing */
290  SCIP_CALL( SCIPstartProbing(scip) );
291  SCIPdebugMsg(scip, "start probing\n");
292 
293  SCIP_CALL( addObjCutoff(scip) );
294 
295  /* make sure that we don't use the objective cutoff for the changed objective */
296  SCIP_CALL( SCIPgetBoolParam(scip, "relaxing/SDP/objlimit", &oldobjlimitparam) );
297  SCIP_CALL( SCIPsetBoolParam(scip, "relaxing/SDP/objlimit", FALSE) );
298 
299  /* allocate memory to save bounds */
300  SCIP_CALL( SCIPallocBufferArray(scip, &newbounds, 2*nvars) );/*lint !e647*/
301  SCIP_CALL( SCIPallocBufferArray(scip, &newboundinds, 2*nvars) );/*lint !e647*/
302 
303  *result = SCIP_DIDNOTFIND;
304 
305  /* set objective coefficients to zero */
306  for( v = 0; v < nvars; ++v )
307  {
308  SCIP_CALL( SCIPchgVarObjProbing(scip, vars[v], 0.0) );
309  }
310 
311  nnewbounds = 0;
312 
313  for (v = 0; v < nvars; v++)
314  {
315  /* do not propagate binary or continous variables if the corresponding flag is set to false */
316  if ( (( ! propdata->propbin ) && SCIPvarIsBinary(vars[v])) || (( ! propdata->propcont ) && ( ! SCIPvarIsIntegral(vars[v]))) )
317  {
318 #ifdef SCIP_MORE_DEBUG
319  if ( SCIPvarIsBinary(vars[v]) )
320  {
321  SCIPdebugMsg(scip, "Skipping binary variable %s\n", SCIPvarGetName(vars[v]));
322  }
323  else
324  {
325  SCIPdebugMsg(scip, "Skipping continuous variable %s\n", SCIPvarGetName(vars[v]));
326  }
327 #endif
328  continue;
329  }
330 
331  /* get the value of this variable for the current relaxation */
332  relaxval = SCIPgetRelaxSolVal(scip, vars[v]);
333 
334  /* only try obbt for the lower bound if it is not tight for the current relaxation's solution */
335  if ( SCIPisFeasGT(scip, relaxval, SCIPvarGetLbLocal(vars[v])) )
336  {
337  /* set the objective to minimize y_v */
338  SCIP_CALL( SCIPchgVarObjProbing(scip, vars[v], 1.0) );
339 
340  /* solve the probing problem */
341  SCIP_CALL( SCIPsolveProbingRelax(scip, &cutoff) );
342 
343  /* as cutoff doesn't work for relax sdp, we have to check ourselves, if we didn't manage to solve successfully, we abort (as this will
344  * probably not get better for the other variables as we only change the objective */
345  relaxsdp = SCIPfindRelax(scip, "SDP");
346 
347  if (! SCIPrelaxSdpSolvedProbing(relaxsdp))
348  {
349  SCIPdebugMsg(scip, "Aborting sdp-obbt, as we were unable to solve a probing sdp!\n");
350  if ( *result != SCIP_REDUCEDDOM )
351  *result = SCIP_DIDNOTRUN;
352  break;
353  }
354 
355  /* if the problem is infeasible, return with cutoff */
356  if ( ! SCIPrelaxSdpIsFeasible(relaxsdp) )
357  {
358  SCIPdebugMsg(scip, "Probing sdp infeasible, so there can't be a better solution for this problem!\n");
359  *result = SCIP_CUTOFF;
360  break;
361  }
362 
363  /* only check objective value if problem was bounded */
364  if ( ! SCIPrelaxSdpIsUnbounded(relaxsdp) )
365  {
366  /* check if we managed to tighten the bound */
367  success = FALSE; /* this will be ignored, we check solvedProbing instead */
368  SCIP_CALL( SCIPrelaxSdpRelaxVal(relaxsdp, &success, &probingval) );
369 
370  /* only update if we improved the bound by at least gaptol, everything else might be inexactness of the solver */
371  if ( SCIPisGT(scip, probingval - TOLERANCE_FACTOR * propdata->sdpsolvergaptol, SCIPvarGetLbLocal(vars[v])) )
372  {
373  /* update bound */
374  SCIPdebugMsg(scip, "Obbt-Sdp tightened lower bound of variable %s from %f to %f !\n",
375  SCIPvarGetName(vars[v]), SCIPvarGetLbLocal(vars[v]), probingval - propdata->sdpsolvergaptol);
376 
377  newbounds[nnewbounds] = probingval;
378  newboundinds[nnewbounds] = -1 * (v+1);
379  nnewbounds++;
380  *result = SCIP_REDUCEDDOM;
381  }
382 #ifdef SCIP_MORE_DEBUG
383  else
384  {
385  SCIPdebugMsg(scip, "Obbt-Sdp found lower bound of %f for variable %s, worse than old bound %f !\n",
386  probingval, SCIPvarGetName(vars[v]), SCIPvarGetLbLocal(vars[v]));
387  }
388  #endif
389  }
390 #ifdef SCIP_MORE_DEBUG
391  else
392  {
393  SCIPdebugMsg(scip, "Obbt-Sdp problem unbounded for variable %s!\n", SCIPvarGetName(vars[v]));
394  }
395 #endif
396  }
397 #ifdef SCIP_MORE_DEBUG
398  else
399  {
400  SCIPdebugMsg(scip, "Skipping obbt for lower bound %f of variable %s, as current relaxation's solution is tight.\n",
401  SCIPvarGetLbLocal(vars[v]), SCIPvarGetName(vars[v]));
402  }
403 #endif
404 
405  /* only try obbt for the upper bound if it is not tight for the current relaxation's solution */
406  if ( SCIPisFeasLT(scip, relaxval, SCIPvarGetUbLocal(vars[v])) )
407  {
408  /* set the objective to maximize y_v (minimize -y_v) */
409  SCIP_CALL( SCIPchgVarObjProbing(scip, vars[v], -1.0) );
410 
411  /* solve the probing problem */
412  SCIP_CALL( SCIPsolveProbingRelax(scip, &cutoff) );
413 
414  /* as cutoff doesn't work for relax sdp, we have to check ourselves, if we didn't manage to solve successfully, we abort (as this will
415  * probably not get better for the other variables as we only change the objective */
416  relaxsdp = SCIPfindRelax(scip, "SDP");
417 
418  if (! SCIPrelaxSdpSolvedProbing(relaxsdp))
419  {
420  SCIPdebugMsg(scip, "Aborting sdp-obbt, as we were unable to solve a probing sdp!\n");
421  if ( *result != SCIP_REDUCEDDOM )
422  *result = SCIP_DIDNOTRUN;
423  goto ENDPROBING;
424  }
425 
426  /* if the problem is infeasible, return with cutoff */
427  if ( ! SCIPrelaxSdpIsFeasible(relaxsdp) )
428  {
429  SCIPdebugMsg(scip, "Probing sdp infeasible, so there can't be a better solution for this problem!\n");
430  *result = SCIP_CUTOFF;
431  nnewbounds = 0;
432  goto ENDPROBING;
433  }
434 
435  /* only check objective value if problem was bounded */
436  if ( ! SCIPrelaxSdpIsUnbounded(relaxsdp) )
437  {
438  /* check if we managed to tighten the bound */
439  success = FALSE; /* this will be ignored, we check solvedProbing instead */
440  SCIP_CALL( SCIPrelaxSdpRelaxVal(relaxsdp, &success, &probingval) );
441 
442  /* only update if we improved the bound by at least gaptol, everything else might be inexactness of the solver */
443  if ( SCIPisLT(scip, -probingval + TOLERANCE_FACTOR * propdata->sdpsolvergaptol, SCIPvarGetUbLocal(vars[v])) )
444  {
445  SCIPdebugMsg(scip, "Obbt-Sdp tightened upper bound of variable %s from %f to %f !\n",
446  SCIPvarGetName(vars[v]), SCIPvarGetUbLocal(vars[v]), -probingval + propdata->sdpsolvergaptol);
447 
448  newbounds[nnewbounds] = -probingval;
449  newboundinds[nnewbounds] = v + 1;
450  nnewbounds++;
451  }
452 #ifdef SCIP_MORE_DEBUG
453  else
454  {
455  SCIPdebugMsg(scip, "Obbt-Sdp found upper bound of %f for variable %s, worse than old bound %f !\n",
456  -probingval, SCIPvarGetName(vars[v]), SCIPvarGetUbLocal(vars[v]));
457  }
458  #endif
459  }
460 #ifdef SCIP_MORE_DEBUG
461  else
462  {
463  SCIPdebugMsg(scip, "Obbt-Sdp problem unbounded for variable %s!\n", SCIPvarGetName(vars[v]));
464  }
465 #endif
466  }
467 #ifdef SCIP_MORE_DEBUG
468  else
469  {
470  SCIPdebugMsg(scip, "Skipping obbt for upper bound %f of variable %s, as current relaxation's solution is tight.\n",
471  SCIPvarGetUbLocal(vars[v]), SCIPvarGetName(vars[v]));
472  }
473 #endif
474 
475  /* reset the objective coefficient to zero for the next variable */
476  SCIP_CALL( SCIPchgVarObjProbing(scip, vars[v], 0.0) );
477  }
478 
479  ENDPROBING:
480  SCIP_CALL( SCIPendProbing(scip) );
481  SCIPdebugMsg(scip, "end probing\n");
482  SCIP_CALL( SCIPsetBoolParam(scip, "relaxing/SDP/objlimit", oldobjlimitparam) );
483 
484  for (i = 0; i < nnewbounds; i++)
485  {
486  if ( newboundinds[i] < 0)
487  {
488  SCIP_CALL( SCIPchgVarLb(scip, vars[-1 * newboundinds[i] - 1], newbounds[i]) ); /*lint !e679*/
489  *result = SCIP_REDUCEDDOM;
490  }
491  else
492  {
493  /* Check if the (rounded) new upper bound is smaller than the updated lower bound, in that case return cutoff.
494  * Note that this can only happen for integer variables, since by construction the lower bound computed by obbt
495  * has to be smaller than the upper bound, but it can happen through rounding. */
496  if ( SCIPvarIsBinary(vars[newboundinds[i] - 1]) && SCIPisLT(scip, SCIPfeasFloor(scip, newbounds[i]),
497  SCIPvarGetLbLocal(vars[newboundinds[i] - 1]) ))
498  {
499  SCIPdebugMsg(scip, "Probing sdp founded conflicting bounds for integer variable %s -> cutoff!\n",
500  SCIPvarGetName(vars[newboundinds[i] - 1]));
501  *result = SCIP_CUTOFF;
502  break;
503  }
504  SCIP_CALL( SCIPchgVarUb(scip, vars[newboundinds[i] - 1], newbounds[i]) );
505  *result = SCIP_REDUCEDDOM;
506  }
507  }
508 
509  SCIPfreeBufferArray(scip, &newboundinds);
510  SCIPfreeBufferArray(scip, &newbounds);
511 
512  return SCIP_OKAY;
513 }
514 
515 
516 
517 /*
518  * propagator specific interface methods
519  */
520 
523  SCIP* scip
524  )
525 {
526  SCIP_PROPDATA* propdata;
527  SCIP_PROP* prop;
528 
529  /* create SdpObbt propagator data */
530  propdata = NULL;
531  SCIP_CALL( SCIPallocMemory(scip, &propdata) );
532  propdata->lastnode = -1;
533  propdata->propenabled = TRUE;
534 
535  /* include propagator */
536  /* use SCIPincludePropBasic() plus setter functions if you want to set callbacks one-by-one and your code should
537  * compile independent of new callbacks being added in future SCIP versions
538  */
539  SCIP_CALL( SCIPincludePropBasic(scip, &prop, PROP_NAME, PROP_DESC, PROP_PRIORITY, PROP_FREQ, PROP_DELAY, PROP_TIMING,
540  propExecSdpObbt, propdata) );
541 
542  assert(prop != NULL);
543 
544  /* set optional callbacks via setter functions */
545  SCIP_CALL( SCIPsetPropCopy(scip, prop, propCopySdpObbt) );
546  SCIP_CALL( SCIPsetPropFree(scip, prop, propFreeSdpObbt) );
547  SCIP_CALL( SCIPsetPropExit(scip, prop, propExitSdpObbt) );
548  SCIP_CALL( SCIPsetPropInitsol(scip, prop, propInitsolSdpObbt) );
549 
550  /* add SdpObbt propagator parameters */
551  SCIP_CALL( SCIPaddBoolParam(scip, "propagating/" PROP_NAME "/propbin",
552  "Should optimization-based bound tightening be performed for binary variables?",
553  &propdata->propbin, TRUE, DEFAULT_PROPBIN, NULL, NULL) );
554 
555  SCIP_CALL( SCIPaddBoolParam(scip, "propagating/" PROP_NAME "/propcont",
556  "Should optimization-based bound tightening be performed for continuous variables?",
557  &propdata->propcont, TRUE, DEFAULT_PROPCONT, NULL, NULL) );
558 
559  return SCIP_OKAY;
560 }
#define PROP_TIMING
Definition: prop_sdpobbt.c:58
SCIP_RETCODE SCIPincludePropSdpObbt(SCIP *scip)
Definition: prop_sdpobbt.c:522
#define PROP_NAME
Definition: prop_sdpobbt.c:53
static SCIP_DECL_PROPEXIT(propExitSdpObbt)
Definition: prop_sdpobbt.c:165
static SCIP_DECL_PROPEXEC(propExecSdpObbt)
Definition: prop_sdpobbt.c:201
static SCIP_DECL_PROPCOPY(propCopySdpObbt)
Definition: prop_sdpobbt.c:135
SDP-relaxator.
#define PROP_DESC
Definition: prop_sdpobbt.c:54
optimization-based bound tightening propagator for semidefinite programs
static SCIP_RETCODE addObjCutoff(SCIP *scip)
Definition: prop_sdpobbt.c:91
SCIP_RETCODE SCIPrelaxSdpRelaxVal(SCIP_RELAX *relax, SCIP_Bool *success, SCIP_Real *objval)
Definition: relax_sdp.c:5496
static SCIP_DECL_PROPINITSOL(propInitsolSdpObbt)
Definition: prop_sdpobbt.c:180
#define PROP_FREQ
Definition: prop_sdpobbt.c:56
static SCIP_DECL_PROPFREE(propFreeSdpObbt)
Definition: prop_sdpobbt.c:150
#define TOLERANCE_FACTOR
Definition: prop_sdpobbt.c:64
SCIP_Bool SCIPrelaxSdpSolvedProbing(SCIP_RELAX *relax)
Definition: relax_sdp.c:5579
#define DEFAULT_PROPBIN
Definition: prop_sdpobbt.c:60
#define DEFAULT_PROPCONT
Definition: prop_sdpobbt.c:61
#define PROP_PRIORITY
Definition: prop_sdpobbt.c:55
#define PROP_DELAY
Definition: prop_sdpobbt.c:57
SCIP_Bool SCIPrelaxSdpIsFeasible(SCIP_RELAX *relax)
Definition: relax_sdp.c:5596
SCIP_Bool SCIPrelaxSdpIsUnbounded(SCIP_RELAX *relax)
Definition: relax_sdp.c:5607