SCIP-SDP  3.1.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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-2019 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-2019 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 };
83 
84 
85 /*
86  * Local methods
87  */
88 
89 /* the current bugfix branch (3.2.1) does not have SCIPsolveProbingRelax() -> do nothing */
90 #if ( (SCIP_VERSION > 321 || SCIP_SUBVERSION > 0) )
91 static
92 SCIP_RETCODE addObjCutoff(
93  SCIP* scip
94  )
95 {
96  SCIP_ROW* row;
97  SCIP_VAR** vars;
98  char rowname[SCIP_MAXSTRLEN];
99  int nvars;
100  int v;
101 
102  assert( scip != NULL );
103  assert( SCIPinProbing(scip) );
104 
105  SCIPdebugMsg(scip, "create objective cutoff and add it to the LP-constraints\n");
106 
107  nvars = SCIPgetNVars(scip);
108  vars = SCIPgetVars(scip);
109 
110  /* create objective cutoff row; set local flag to FALSE since primal cutoff is globally valid */
111  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "obbtsdp_objcutoff");
112  SCIP_CALL( SCIPcreateEmptyRowUnspec(scip, &row, rowname, -SCIPinfinity(scip), SCIPgetCutoffbound(scip), FALSE, FALSE, FALSE) );
113  SCIP_CALL( SCIPcacheRowExtensions(scip, row) );
114 
115  for( v = 0; v < nvars; v++ )
116  {
117  SCIP_CALL( SCIPaddVarToRow(scip, row, vars[v], SCIPvarGetObj(vars[v])) );
118  }
119  SCIP_CALL( SCIPflushRowExtensions(scip, row) );
120 
121  /* add row to the LP-constraints */
122  SCIP_CALL( SCIPaddRowProbing(scip, row) );
123 
124  SCIP_CALL( SCIPreleaseRow(scip, &row) );
125 
126  return SCIP_OKAY;
127 }
128 #endif
129 
130 /*
131  * Callback methods of propagator
132  */
133 
134 
136 static
137 SCIP_DECL_PROPCOPY(propCopySdpObbt)
138 { /*lint --e{715}*/
139  assert( scip != NULL );
140  assert( prop != NULL );
141  assert( strcmp(SCIPpropGetName(prop), PROP_NAME) == 0 );
142 
143  /* call inclusion method of constraint handler */
144  SCIP_CALL( SCIPincludePropSdpObbt(scip) );
145 
146  return SCIP_OKAY;
147 }
148 
149 
151 static
152 SCIP_DECL_PROPFREE(propFreeSdpObbt)
153 { /*lint --e{715}*/
154  SCIP_PROPDATA* propdata;
155 
156  propdata = SCIPpropGetData(prop);
157  assert(propdata != NULL);
158 
159  SCIPfreeMemory(scip, &propdata);
160  SCIPpropSetData(prop, NULL);
161 
162  return SCIP_OKAY;
163 }
164 
166 static
167 SCIP_DECL_PROPEXIT(propExitSdpObbt)
168 { /*lint --e{715}*/
169  SCIP_PROPDATA* propdata;
170 
171  assert( prop != NULL );
172 
173  propdata = SCIPpropGetData(prop);
174 
175  propdata->lastnode = -1; /* we reset this to be able to run again if a new problem is read */
176 
177  return SCIP_OKAY;
178 }
179 
181 static
182 SCIP_DECL_PROPINITSOL(propInitsolSdpObbt)
183 { /*lint --e{715}*/
184  SCIP_PROPDATA* propdata;
185 
186  assert( prop != NULL );
187 
188  propdata = SCIPpropGetData(prop);
189 
190  SCIP_CALL( SCIPgetRealParam(scip, "relaxing/SDP/sdpsolvergaptol", &(propdata->sdpsolvergaptol)) );
191 
192  return SCIP_OKAY;
193 }
194 
196 static
197 SCIP_DECL_PROPEXEC(propExecSdpObbt)
198 { /*lint --e{715}*/
199  /* the current bugfix branch (3.2.1) does not have SCIPsolveProbingRelax() -> do nothing */
200 #if ( (SCIP_VERSION > 321 || SCIP_SUBVERSION > 0) )
201  int nvars;
202  SCIP_VAR** vars;
203  int v;
204  SCIP_PROPDATA* propdata;
205  SCIP_Real relaxval;
206  SCIP_Bool cutoff;
207  SCIP_Bool oldobjlimitparam;
208  SCIP_Real probingval;
209  SCIP_Bool success;
210  SCIP_RELAX* relaxsdp;
211  /* newbounds and newboundinds save the bound tightenings that should be inserted after probing ends, newboundinds saves the bounds the entries of newbounds
212  * 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 */
213  SCIP_Real* newbounds;
214  int* newboundinds;
215  int nnewbounds;
216  int i;
217 
218  assert( scip != NULL );
219  assert( prop != NULL );
220  assert( result != NULL );
221 
222  propdata = SCIPpropGetData(prop);
223 
224  assert( propdata != NULL );
225 
226  *result = SCIP_DIDNOTRUN;
227 
228  SCIPdebugMsg(scip, "Executing propExecSdpObbt! \n");
229 
230  /* do not run in: presolving, repropagation, probing mode, subscips, if no objective propagation is allowed */
231  if ( SCIPgetStage(scip) != SCIP_STAGE_SOLVING || SCIPinRepropagation(scip) || SCIPinProbing(scip) || !SCIPallowObjProp(scip) || (SCIPgetSubscipDepth(scip) > 0) )
232  {
233  SCIPdebugMsg(scip, "Aborting propExecSdpObbt because we are in presolving, repropagation, probing mode, a subscip or no objective "
234  "propagation is allowed!\n");
235  return SCIP_OKAY;
236  }
237 
238  /* delay if cutoffbound is infinite or no relaxation solution exists */
239  if ( SCIPisInfinity(scip, SCIPgetCutoffbound(scip)) || (! SCIPisRelaxSolValid(scip)) )
240  {
241  /* if we already delayed in the last call, abort to prevent an infinite loop */
242  if ( propdata->delayed )
243  {
244  SCIPdebugMsg(scip, "Aborting propExecSdpObbt since still cutoffbound is infinite or no relaxation solution exists\n");
245  return SCIP_OKAY;
246  }
247  *result = SCIP_DELAYED;
248  propdata->delayed = TRUE;
249  SCIPdebugMsg(scip, "Delaying propExecSdpObbt since cutoffbound is infinite or no relaxation solution exists\n");
250  return SCIP_OKAY;
251  }
252 
253  /* 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 */
254  if ( (SCIPgetBestSol(scip) == NULL) || ((SCIPsolGetHeur(SCIPgetBestSol(scip)) != NULL) && (strcmp(SCIPheurGetName(SCIPsolGetHeur(SCIPgetBestSol(scip))), "trivial") == 0)) )
255  {
256  /* if we already delayed in the last call, abort to prevent an infinite loop */
257  if ( propdata->delayed )
258  {
259  SCIPdebugMsg(scip, "Aborting propExecSdpObbt since still best solution was found by trivial heuristic or simple objective propagation, which will not be good enough\n");
260  return SCIP_OKAY;
261  }
262  *result = SCIP_DELAYED;
263  propdata->delayed = TRUE;
264  SCIPdebugMsg(scip, "Delaying propExecSdpObbt since best solution was found by trivial heuristic or simple objective propagation, which will not be good enough\n");
265  return SCIP_OKAY;
266  }
267 
268  if ( (SCIPnodeGetNumber(SCIPgetCurrentNode(scip)) == propdata->lastnode) && (SCIPisEQ(scip, SCIPgetCutoffbound(scip), propdata->lastcufoffbound)) )
269  {
270  SCIPdebugMsg(scip, "Not running again for node %lld with cutoffbound &f!\n", propdata->lastnode, propdata->lastcufoffbound);
271  return SCIP_OKAY;
272  }
273  else
274  {
275  propdata->lastnode = SCIPnodeGetNumber(SCIPgetCurrentNode(scip));
276  propdata->lastcufoffbound = SCIPgetCutoffbound(scip);
277  }
278 
279  propdata->delayed = FALSE;
280 
281  vars = SCIPgetVars(scip);
282  nvars = SCIPgetNVars(scip);
283 
284  /* start probing */
285  SCIP_CALL( SCIPstartProbing(scip) );
286  SCIPdebugMsg(scip, "start probing\n");
287 
288  SCIP_CALL( addObjCutoff(scip) );
289 
290  /* make sure that we don't use the objective cutoff for the changed objective */
291  SCIP_CALL( SCIPgetBoolParam(scip, "relaxing/SDP/objlimit", &oldobjlimitparam) );
292  SCIP_CALL( SCIPsetBoolParam(scip, "relaxing/SDP/objlimit", FALSE) );
293 
294  /* allocate memory to save bounds */
295  SCIP_CALL( SCIPallocBufferArray(scip, &newbounds, 2*nvars) );/*lint !e647*/
296  SCIP_CALL( SCIPallocBufferArray(scip, &newboundinds, 2*nvars) );/*lint !e647*/
297 
298  *result = SCIP_DIDNOTFIND;
299 
300  /* set objective coefficients to zero */
301  for( v = 0; v < nvars; ++v )
302  {
303  SCIP_CALL( SCIPchgVarObjProbing(scip, vars[v], 0.0) );
304  }
305 
306  nnewbounds = 0;
307 
308  for (v = 0; v < nvars; v++)
309  {
310  /* do not propagate binary or continous variables if the corresponding flag is set to false */
311  if ( (( ! propdata->propbin ) && SCIPvarIsBinary(vars[v])) || (( ! propdata->propcont ) && ( ! SCIPvarIsIntegral(vars[v]))) )
312  {
313 #ifdef SCIP_MORE_DEBUG
314  if ( SCIPvarIsBinary(vars[v]) )
315  {
316  SCIPdebugMsg(scip, "Skipping binary variable %s\n", SCIPvarGetName(vars[v]));
317  }
318  else
319  {
320  SCIPdebugMsg(scip, "Skipping continuous variable %s\n", SCIPvarGetName(vars[v]));
321  }
322 #endif
323  continue;
324  }
325 
326  /* get the value of this variable for the current relaxation */
327  relaxval = SCIPgetRelaxSolVal(scip, vars[v]);
328 
329  /* only try obbt for the lower bound if it is not tight for the current relaxation's solution */
330  if ( SCIPisFeasGT(scip, relaxval, SCIPvarGetLbLocal(vars[v])) )
331  {
332  /* set the objective to minimize y_v */
333  SCIP_CALL( SCIPchgVarObjProbing(scip, vars[v], 1.0) );
334 
335  /* solve the probing problem */
336  SCIP_CALL( SCIPsolveProbingRelax(scip, &cutoff) );
337 
338  /* 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
339  * probably not get better for the other variables as we only change the objective */
340  relaxsdp = SCIPfindRelax(scip, "SDP");
341 
342  if (! SCIPrelaxSdpSolvedProbing(relaxsdp))
343  {
344  SCIPdebugMsg(scip, "Aborting sdp-obbt, as we were unable to solve a probing sdp!\n");
345  if ( *result != SCIP_REDUCEDDOM )
346  *result = SCIP_DIDNOTRUN;
347  break;
348  }
349 
350  /* if the problem is infeasible, return with cutoff */
351  if ( ! SCIPrelaxSdpIsFeasible(relaxsdp) )
352  {
353  SCIPdebugMsg(scip, "Probing sdp infeasible, so there can't be a better solution for this problem!\n");
354  *result = SCIP_CUTOFF;
355  break;
356  }
357 
358  /* only check objective value if problem was bounded */
359  if ( ! SCIPrelaxSdpIsUnbounded(relaxsdp) )
360  {
361  /* check if we managed to tighten the bound */
362  success = FALSE; /* this will be ignored, we check solvedProbing instead */
363  SCIP_CALL( SCIPrelaxSdpRelaxVal(relaxsdp, &success, &probingval) );
364 
365  /* only update if we improved the bound by at least gaptol, everything else might be inexactness of the solver */
366  if ( SCIPisGT(scip, probingval - TOLERANCE_FACTOR * propdata->sdpsolvergaptol, SCIPvarGetLbLocal(vars[v])) )
367  {
368  /* update bound */
369  SCIPdebugMsg(scip, "Obbt-Sdp tightened lower bound of variable %s from %f to %f !\n",
370  SCIPvarGetName(vars[v]), SCIPvarGetLbLocal(vars[v]), probingval - propdata->sdpsolvergaptol);
371 
372  newbounds[nnewbounds] = probingval;
373  newboundinds[nnewbounds] = -1 * (v+1);
374  nnewbounds++;
375  *result = SCIP_REDUCEDDOM;
376  }
377  #ifdef SCIP_MORE_DEBUG
378  else
379  {
380  SCIPdebugMsg(scip, "Obbt-Sdp found lower bound of %f for variable %s, worse than old bound %f !\n",
381  probingval, SCIPvarGetName(vars[v]), SCIPvarGetLbLocal(vars[v]));
382  }
383  #endif
384  }
385 #ifdef SCIP_MORE_DEBUG
386  else
387  {
388  SCIPdebugMsg(scip, "Obbt-Sdp problem unbounded for variable %s!\n", SCIPvarGetName(vars[v]));
389  }
390 #endif
391  }
392 #ifdef SCIP_MORE_DEBUG
393  else
394  {
395  SCIPdebugMsg(scip, "Skipping obbt for lower bound %f of variable %s, as current relaxation's solution is tight.\n",
396  SCIPvarGetLbLocal(vars[v]), SCIPvarGetName(vars[v]));
397  }
398 #endif
399 
400  /* only try obbt for the upper bound if it is not tight for the current relaxation's solution */
401  if ( SCIPisFeasLT(scip, relaxval, SCIPvarGetUbLocal(vars[v])) )
402  {
403  /* set the objective to maximize y_v (minimize -y_v) */
404  SCIP_CALL( SCIPchgVarObjProbing(scip, vars[v], -1.0) );
405 
406  /* solve the probing problem */
407  SCIP_CALL( SCIPsolveProbingRelax(scip, &cutoff) );
408 
409  /* 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
410  * probably not get better for the other variables as we only change the objective */
411  relaxsdp = SCIPfindRelax(scip, "SDP");
412 
413  if (! SCIPrelaxSdpSolvedProbing(relaxsdp))
414  {
415  SCIPdebugMsg(scip, "Aborting sdp-obbt, as we were unable to solve a probing sdp!\n");
416  if ( *result != SCIP_REDUCEDDOM )
417  *result = SCIP_DIDNOTRUN;
418  goto ENDPROBING;
419  }
420 
421  /* if the problem is infeasible, return with cutoff */
422  if ( ! SCIPrelaxSdpIsFeasible(relaxsdp) )
423  {
424  SCIPdebugMsg(scip, "Probing sdp infeasible, so there can't be a better solution for this problem!\n");
425  *result = SCIP_CUTOFF;
426  nnewbounds = 0;
427  goto ENDPROBING;
428  }
429 
430  /* only check objective value if problem was bounded */
431  if ( ! SCIPrelaxSdpIsUnbounded(relaxsdp) )
432  {
433  /* check if we managed to tighten the bound */
434  success = FALSE; /* this will be ignored, we check solvedProbing instead */
435  SCIP_CALL( SCIPrelaxSdpRelaxVal(relaxsdp, &success, &probingval) );
436 
437  /* only update if we improved the bound by at least gaptol, everything else might be inexactness of the solver */
438  if ( SCIPisLT(scip, -probingval + TOLERANCE_FACTOR * propdata->sdpsolvergaptol, SCIPvarGetUbLocal(vars[v])) )
439  {
440  SCIPdebugMsg(scip, "Obbt-Sdp tightened upper bound of variable %s from %f to %f !\n",
441  SCIPvarGetName(vars[v]), SCIPvarGetUbLocal(vars[v]), -probingval + propdata->sdpsolvergaptol);
442 
443  newbounds[nnewbounds] = -probingval;
444  newboundinds[nnewbounds] = v + 1;
445  nnewbounds++;
446  }
447  #ifdef SCIP_MORE_DEBUG
448  else
449  {
450  SCIPdebugMsg(scip, "Obbt-Sdp found upper bound of %f for variable %s, worse than old bound %f !\n",
451  -probingval, SCIPvarGetName(vars[v]), SCIPvarGetUbLocal(vars[v]));
452  }
453  #endif
454  }
455 #ifdef SCIP_MORE_DEBUG
456  else
457  {
458  SCIPdebugMsg(scip, "Obbt-Sdp problem unbounded for variable %s!\n", SCIPvarGetName(vars[v]));
459  }
460 #endif
461  }
462 #ifdef SCIP_MORE_DEBUG
463  else
464  {
465  SCIPdebugMsg(scip, "Skipping obbt for upper bound %f of variable %s, as current relaxation's solution is tight.\n",
466  SCIPvarGetUbLocal(vars[v]), SCIPvarGetName(vars[v]));
467  }
468 #endif
469 
470  /* reset the objective coefficient to zero for the next variable */
471  SCIP_CALL( SCIPchgVarObjProbing(scip, vars[v], 0.0) );
472  }
473 
474  ENDPROBING:
475  SCIP_CALL( SCIPendProbing(scip) );
476  SCIPdebugMsg(scip, "end probing\n");
477  SCIP_CALL( SCIPsetBoolParam(scip, "relaxing/SDP/objlimit", oldobjlimitparam) );
478 
479  for (i = 0; i < nnewbounds; i++)
480  {
481  if ( newboundinds[i] < 0)
482  {
483  SCIP_CALL( SCIPchgVarLb(scip, vars[-1 * newboundinds[i] - 1], newbounds[i]) ); /*lint !e679*/
484  *result = SCIP_REDUCEDDOM;
485  }
486  else
487  {
488  /* Check if the (rounded) new upper bound is smaller than the updated lower bound, in that case return cutoff.
489  * Note that this can only happen for integer variables, since by construction the lower bound computed by obbt
490  * has to be smaller than the upper bound, but it can happen through rounding. */
491  if ( SCIPvarIsBinary(vars[newboundinds[i] - 1]) && SCIPisLT(scip, SCIPfeasFloor(scip, newbounds[i]),
492  SCIPvarGetLbLocal(vars[newboundinds[i] - 1]) ))
493  {
494  SCIPdebugMsg(scip, "Probing sdp founded conflicting bounds for integer variable %s -> cutoff!\n",
495  SCIPvarGetName(vars[newboundinds[i] - 1]));
496  *result = SCIP_CUTOFF;
497  break;
498  }
499  SCIP_CALL( SCIPchgVarUb(scip, vars[newboundinds[i] - 1], newbounds[i]) );
500  *result = SCIP_REDUCEDDOM;
501  }
502  }
503 
504  SCIPfreeBufferArray(scip, &newboundinds);
505  SCIPfreeBufferArray(scip, &newbounds);
506 
507  return SCIP_OKAY;
508 
509 #else
510  *result = SCIP_DIDNOTRUN;
511 
512  return SCIP_OKAY;
513 #endif
514 }
515 
516 
517 
518 /*
519  * propagator specific interface methods
520  */
521 
524  SCIP* scip
525  )
526 {
527  SCIP_PROPDATA* propdata;
528  SCIP_PROP* prop;
529 
530  /* create SdpObbt propagator data */
531  propdata = NULL;
532  SCIP_CALL( SCIPallocMemory(scip, &propdata) );
533  propdata->lastnode = -1;
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:523
#define PROP_NAME
Definition: prop_sdpobbt.c:53
static SCIP_DECL_PROPEXIT(propExitSdpObbt)
Definition: prop_sdpobbt.c:167
static SCIP_DECL_PROPEXEC(propExecSdpObbt)
Definition: prop_sdpobbt.c:197
static SCIP_DECL_PROPCOPY(propCopySdpObbt)
Definition: prop_sdpobbt.c:137
SDP-relaxator.
#define PROP_DESC
Definition: prop_sdpobbt.c:54
optimization-based bound tightening propagator for semidefinite programs
SCIP_RETCODE SCIPrelaxSdpRelaxVal(SCIP_RELAX *relax, SCIP_Bool *success, SCIP_Real *objval)
Definition: relax_sdp.c:5188
static SCIP_DECL_PROPINITSOL(propInitsolSdpObbt)
Definition: prop_sdpobbt.c:182
#define PROP_FREQ
Definition: prop_sdpobbt.c:56
static SCIP_DECL_PROPFREE(propFreeSdpObbt)
Definition: prop_sdpobbt.c:152
#define TOLERANCE_FACTOR
Definition: prop_sdpobbt.c:64
SCIP_Bool SCIPrelaxSdpSolvedProbing(SCIP_RELAX *relax)
Definition: relax_sdp.c:5271
#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:5288
SCIP_Bool SCIPrelaxSdpIsUnbounded(SCIP_RELAX *relax)
Definition: relax_sdp.c:5299