SCIP-SDP  2.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
relax_sdp.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 programms based on SCIP. */
5 /* */
6 /* Copyright (C) 2011-2013 Discrete Optimization, TU Darmstadt */
7 /* EDOM, FAU Erlangen-Nürnberg */
8 /* 2014-2015 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-2015 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 
40 /* #define SCIP_DEBUG*/
41 /* #define SCIP_MORE_DEBUG *//* displays complete solution for each relaxation */
42 /* #define SCIP_EVEN_MORE_DEBUG *//* shows number of deleted empty cols/rows for every relaxation and variable status &
43  * bounds as well as all constraints in the beginning */
44 
45 #include "relax_sdp.h"
46 
47 #include "assert.h" /*lint !e451*/
48 #include "string.h" /* for strcmp */
49 
50 #include "SdpVarmapper.h"
51 #include "sdpi/sdpi.h"
52 #include "scipsdp/cons_sdp.h"
53 
54 
55 #define RELAX_NAME "SDP"
56 #define RELAX_DESC "SDP relaxator"
57 #define RELAX_PRIORITY 1
58 #define RELAX_FREQ 1
59 
60 #define DEFAULT_SDPSOLVEREPSILON 1e-5
61 #define DEFAULT_SDPSOLVERFEASTOL 1e-4
62 #if 0
63 #define DEFAULT_THREADS 1
64 #endif
65 #define DEFAULT_OBJLIMIT FALSE
67 /*
68  * Data structures
69  */
70 
72 struct SCIP_RelaxData
73 {
74  SCIP_SDPI* sdpi;
75  SdpVarmapper* varmapper;
76  SCIP_Real objval;
77  SCIP_Bool origsolved;
78  SCIP_Real sdpsolverepsilon;
79  SCIP_Real sdpsolverfeastol;
80  int sdpiterations;
81 #if 0
82  int threads;
83 #endif
84  SCIP_Bool slatercheck;
85  SCIP_Bool sdpinfo;
86  SCIP_Bool objlimit;
87  int sdpcalls;
88  long int lastsdpnode;
89 };
90 
92 static
93 SCIP_RETCODE putSdpDataInInterface(
94  SCIP* scip,
95  SCIP_SDPI* sdpi,
96  SdpVarmapper* varmapper
97  )
98 {
99  int i;
100  int j;
101  int nvars;
102  SCIP_VAR ** vars;
103  SCIP_VAR ** blockvars;
104  SCIP_CONS** conss;
105  int nconss;
106  int ind;
107  SCIP_Real* obj;
108  SCIP_Real* lb;
109  SCIP_Real* ub;
110  int nsdpblocks;
111  int* sdpblocksizes;
112  int sdpconstnnonz;
113  int** constrow;
114  int** constcol;
115  SCIP_Real** constval;
116  int sdpnnonz;
117  int constnnonzcounter;
118  int*** row;
119  int*** col;
120  SCIP_Real*** val;
121  SCIP_CONSHDLR* conshdlr;
122  int blocknnonz;
123  int* nblockvars;
124  int** nblockvarnonz;
125  int* nconstblocknonz;
126  int constlength;
127  int** sdpvar;
128  const char* hdlrName;
129 
130  SCIP_Real param;
131  SCIP_CALL( SCIPgetRealParam(scip, "relaxing/SDP/sdpsolverepsilon", &param) );
132 
133  SCIPdebugMessage("Putting SDP Data in general interface! \n");
134 
135  assert( scip != NULL );
136  assert( sdpi != NULL );
137 
138  vars = SCIPgetVars(scip);
139  nvars = SCIPgetNVars(scip);
140 
141  /* prepare arrays of objective values and bounds */
142  SCIP_CALL( SCIPallocBufferArray(scip, &obj, nvars) );
143  SCIP_CALL( SCIPallocBufferArray(scip, &lb, nvars) );
144  SCIP_CALL( SCIPallocBufferArray(scip, &ub, nvars) );
145 
146  for (i = 0; i < nvars; i++)
147  {
148  obj[i] = SCIPvarGetObj(vars[i]);
149  lb[i] = SCIPvarGetLbLocal(vars[i]);
150  ub[i] = SCIPvarGetUbLocal(vars[i]);
151  }
152 
153  nconss = SCIPgetNConss(scip);
154  conss = SCIPgetConss(scip);
155 
156  /* count the number of sdpblocks and compute the number of nonzeros */
157  nsdpblocks = 0;
158  sdpnnonz = 0;
159  sdpconstnnonz = 0;
160 
161  for (i = 0; i < nconss; i++)
162  {
163  conshdlr = SCIPconsGetHdlr(conss[i]);
164  assert( conshdlr != NULL );
165 
166  hdlrName = SCIPconshdlrGetName(conshdlr);
167 
168 #ifdef SCIP_EVEN_MORE_DEBUG
169  SCIP_CALL( SCIPprintCons(scip, conss[i], NULL) );
170  SCIPinfoMessage(scip, NULL, "\n");
171 #endif
172 
173  if ( strcmp(hdlrName, "SDP") == 0 )
174  {
175  nsdpblocks++;
176 
177  SCIP_CALL( SCIPconsSdpGetNNonz(scip, conss[i], &blocknnonz, &constnnonzcounter) );
178  sdpnnonz += blocknnonz;
179  sdpconstnnonz += constnnonzcounter;
180  }
181  }
182 
183  /* create the sdp- and sdpconst-arrays */
184  SCIP_CALL( SCIPallocBufferArray(scip, &sdpblocksizes, nsdpblocks) );
185  SCIP_CALL( SCIPallocBufferArray(scip, &nblockvarnonz, nsdpblocks) );
186  SCIP_CALL( SCIPallocBufferArray(scip, &nconstblocknonz, nsdpblocks) );
187  SCIP_CALL( SCIPallocBufferArray(scip, &col, nsdpblocks) );
188  SCIP_CALL( SCIPallocBufferArray(scip, &row, nsdpblocks) );
189  SCIP_CALL( SCIPallocBufferArray(scip, &val, nsdpblocks) );
190  SCIP_CALL( SCIPallocBufferArray(scip, &constcol, nsdpblocks) );
191  SCIP_CALL( SCIPallocBufferArray(scip, &constrow, nsdpblocks) );
192  SCIP_CALL( SCIPallocBufferArray(scip, &constval, nsdpblocks) );
193  SCIP_CALL( SCIPallocBufferArray(scip, &nblockvars, nsdpblocks) );
194  SCIP_CALL( SCIPallocBufferArray(scip, &sdpvar, nsdpblocks) );
195 
196  for (i = 0; i < nsdpblocks; i++)
197  {
198  SCIP_CALL( SCIPallocBufferArray(scip, &(nblockvarnonz[i]), nvars) );
199  SCIP_CALL( SCIPallocBufferArray(scip, &col[i], nvars) );
200  SCIP_CALL( SCIPallocBufferArray(scip, &row[i], nvars) );
201  SCIP_CALL( SCIPallocBufferArray(scip, &val[i], nvars) );
202  }
203 
204  /* get the SDP-data */
205  ind = 0; /* index of the current sdp block in the complete sdp */
206  SCIP_CALL( SCIPallocBufferArray(scip, &blockvars, nvars) );
207 
208  for (i = 0; i < nconss; i++)
209  {
210  conshdlr = SCIPconsGetHdlr(conss[i]);
211  assert( conshdlr != NULL );
212 
213  hdlrName = SCIPconshdlrGetName(conshdlr);
214 
215  if ( strcmp(hdlrName, "SDP") == 0 )
216  {
217  assert( ind < nsdpblocks );
218 
219  /* allocate memory for the constant nonzeros */
220  SCIP_CALL( SCIPconsSdpGetNNonz(scip, conss[i], NULL, &constlength) );
221  nconstblocknonz[ind] = constlength;
222  SCIP_CALL( SCIPallocBufferArray(scip, &(constcol[ind]), constlength) );
223  SCIP_CALL( SCIPallocBufferArray(scip, &(constrow[ind]), constlength) );
224  SCIP_CALL( SCIPallocBufferArray(scip, &(constval[ind]), constlength) );
225 
226  /* get the data */
227  SCIP_CALL( SCIPconsSdpGetData(scip, conss[i], &nblockvars[ind], &blocknnonz, &sdpblocksizes[ind], &nvars, nblockvarnonz[ind], col[ind],
228  row[ind], val[ind], blockvars, &nconstblocknonz[ind], constcol[ind], constrow[ind], constval[ind]) );
229 
230  /* nvars and nconstblocknonz[ind] would have been overwritten if the space in the given arrays hadn't been sufficient */
231  assert( nvars == SCIPgetNVars(scip) );
232  assert( nconstblocknonz[ind] <= constlength );
233 
234  SCIP_CALL( SCIPallocBufferArray(scip, &(sdpvar[ind]), nblockvars[ind]) );
235 
236  /* get global variable indices */
237  for (j = 0; j < nblockvars[ind]; j++)
238  sdpvar[ind][j] = SCIPsdpVarmapperGetSdpIndex(varmapper, blockvars[j]);
239 
240  ind++;
241  }
242  }
243 
244  /* free the memory that is no longer needed */
245  SCIPfreeBufferArray(scip, &blockvars);
246 
247  SCIP_CALL(SCIPsdpiLoadSDP(sdpi, nvars, obj, lb, ub, nsdpblocks,
248  sdpblocksizes, nblockvars, sdpconstnnonz, nconstblocknonz, constrow,
249  constcol, constval, sdpnnonz, nblockvarnonz, sdpvar,
250  row, col, val, 0,
251  NULL, NULL, 0, NULL, NULL, NULL)); /* insert the SDP part, add an empty LP part */
252 
253  /* free the remaining memory */
254  for (i = 0; i < nsdpblocks; i++)
255  {
256  SCIPfreeBufferArrayNull(scip, &(sdpvar[i]));
257  SCIPfreeBufferArrayNull(scip, &val[i]);
258  SCIPfreeBufferArrayNull(scip, &row[i]);
259  SCIPfreeBufferArrayNull(scip, &col[i]);
260  SCIPfreeBufferArrayNull(scip, &(nblockvarnonz[i]));
261  SCIPfreeBufferArrayNull(scip, &(constval[i]));
262  SCIPfreeBufferArrayNull(scip, &(constrow[i]));
263  SCIPfreeBufferArrayNull(scip, &(constcol[i]));
264  }
265 
266  SCIPfreeBufferArrayNull(scip, &sdpvar);
267  SCIPfreeBufferArrayNull(scip, &nblockvars);
268  SCIPfreeBufferArrayNull(scip, &constval);
269  SCIPfreeBufferArrayNull(scip, &constrow);
270  SCIPfreeBufferArrayNull(scip, &constcol);
271  SCIPfreeBufferArrayNull(scip, &val);
272  SCIPfreeBufferArrayNull(scip, &row);
273  SCIPfreeBufferArrayNull(scip, &col);
274  SCIPfreeBufferArrayNull(scip, &nconstblocknonz);
275  SCIPfreeBufferArrayNull(scip, &nblockvarnonz);
276  SCIPfreeBufferArrayNull(scip, &sdpblocksizes);
277  SCIPfreeBufferArray(scip, &ub);
278  SCIPfreeBufferArray(scip, &lb);
279  SCIPfreeBufferArray(scip, &obj);
280 
281  return SCIP_OKAY;
282 }
283 
285 static
286 SCIP_RETCODE putLpDataInInterface(
287  SCIP* scip,
288  SCIP_SDPI* sdpi,
289  SdpVarmapper* varmapper
290  )
291 {
292  int i;
293  int j;
294  int nvars;
295  int nconss;
296  int scipnnonz;
297  SCIP_Real* lhs;
298  SCIP_Real* rhs;
299  int nnonz;
300  int* rowind;
301  int* colind;
302  SCIP_Real* val;
303  SCIP_ROW** rows;
304  int nrows;
305  int rownnonz;
306  SCIP_Real* rowvals;
307  SCIP_COL** rowcols;
308  SCIP_Real sciplhs;
309  SCIP_Real sciprhs;
310  int nrowssdpi;
311  SCIP_VAR** vars;
312  SCIP_Real* lb;
313  SCIP_Real* ub;
314  int* inds;
315 
316  assert( scip != NULL );
317  assert( sdpi != NULL );
318  assert( varmapper != NULL );
319 
320  nvars = SCIPgetNVars(scip);
321  assert( nvars > 0 );
322 
323  SCIP_CALL( SCIPgetLPRowsData(scip, &rows, &nrows) );
324 
325  SCIPdebugMessage("inserting %d LPRows into the interface \n", nrows);
326 
327  /* compute the total number of LP nonzeroes in SCIP */
328  scipnnonz = 0;
329  for (i = 0; i < nrows; i++)
330  {
331  assert( rows[i] != NULL );
332  scipnnonz += SCIProwGetNNonz(rows[i]);
333  }
334 
335  /* allocate memory */
336  SCIP_CALL( SCIPallocBufferArray(scip, &lhs, nrows) );
337  SCIP_CALL( SCIPallocBufferArray(scip, &rhs, nrows) );
338  SCIP_CALL( SCIPallocBufferArray(scip, &rowind, scipnnonz) );
339  SCIP_CALL( SCIPallocBufferArray(scip, &colind, scipnnonz) );
340  SCIP_CALL( SCIPallocBufferArray(scip, &val, scipnnonz) );
341 
342  /* insert the nonzeroes */
343  nnonz = 0; /* this is recomputed for the sdpi, because of the possible duplication of non-zeroes for lhs and rhs */
344  nconss = 0; /* this will be increased for each finite lhs and rhs */
345 
346  for (i = 0; i < nrows; i++)
347  {
348  SCIP_ROW* row;
349 
350  row = rows[i];
351  assert( row != 0 );
352  rownnonz = SCIProwGetNNonz(row);
353 
354  rowvals = SCIProwGetVals(row);
355  rowcols = SCIProwGetCols(row);
356  sciplhs = SCIProwGetLhs(row) - SCIProwGetConstant(row);
357  sciprhs = SCIProwGetRhs(row) - SCIProwGetConstant(row);
358 
359  for (j = 0; j < rownnonz; j++)
360  {
361  assert( SCIPcolGetVar(rowcols[j]) != 0 );
362  colind[nnonz] = SCIPsdpVarmapperGetSdpIndex(varmapper, SCIPcolGetVar(rowcols[j]));
363  rowind[nnonz] = nconss;
364  val[nnonz] = rowvals[j];
365  nnonz++;
366  }
367  lhs[nconss] = sciplhs;
368  rhs[nconss] = sciprhs;
369  nconss++;
370  }
371 
372  /* delete the old LP-block from the sdpi */
373  SCIP_CALL( SCIPsdpiGetNLPRows(sdpi, &nrowssdpi) );
374  if ( nrowssdpi > 0 )
375  {
376  SCIP_CALL( SCIPsdpiDelLPRows(sdpi, 0, nrowssdpi - 1) );
377  }
378 
379  /* add the LP-block to the sdpi */
380  SCIP_CALL( SCIPsdpiAddLPRows(sdpi, nconss, lhs, rhs, nnonz, (const int*)rowind, (const int*)colind, val) );
381 
382  /* free the remaining arrays */
383  SCIPfreeBufferArray(scip, &val);
384  SCIPfreeBufferArray(scip, &colind);
385  SCIPfreeBufferArray(scip, &rowind);
386  SCIPfreeBufferArray(scip, &rhs);
387  SCIPfreeBufferArray(scip, &lhs);
388 
389  /* update the bounds */
390 
391  /* get the variables */
392  vars = SCIPgetVars(scip);
393  assert( vars != NULL );
394 
395  /* prepare arrays of bounds */
396  SCIP_CALL( SCIPallocBufferArray(scip, &lb, nvars) );
397  SCIP_CALL( SCIPallocBufferArray(scip, &ub, nvars) );
398  SCIP_CALL( SCIPallocBufferArray(scip, &inds, nvars) );
399 
400  /* get new bounds */
401  for (i = 0; i < nvars; i++)
402  {
403  assert( vars[i] != NULL );
404  lb[i] = SCIPvarGetLbLocal(vars[i]);
405  ub[i] = SCIPvarGetUbLocal(vars[i]);
406  inds[i] = i; /* we want to change all bounds, so all indices are included in inds */
407  }
408 
409  /* inform interface */
410  SCIP_CALL( SCIPsdpiChgBounds(sdpi, nvars, inds, lb, ub) );
411 
412  /* free the bounds-arrays */
413  SCIPfreeBufferArray(scip, &inds);
414  SCIPfreeBufferArray(scip, &ub);
415  SCIPfreeBufferArray(scip, &lb);
416 
417  return SCIP_OKAY;
418 }
419 
422 static
423 SCIP_RETCODE calc_relax(
424  SCIP* scip,
425  SCIP_RELAXDATA* relaxdata,
426  SCIP_RESULT* result,
427  SCIP_Real* lowerbound
428  )
429 {
430  SCIP_VAR** vars;
431  int nvars;
432  int i;
433  int v;
434  SCIP_SDPI* sdpi;
435  SdpVarmapper* varmapper;
436  SCIP_Bool rootnode;
437 #ifdef SCIP_MORE_DEBUG
438  SCIP_Real objforscip;
439  SCIP_Real* solforscip;
440  SCIP_Bool allint;
441  int sollength;
442 #endif
443 
444  SCIPdebugMessage("calc_relax called\n");
445 
446  assert( scip != NULL );
447  assert( result != NULL );
448  assert( lowerbound != NULL );
449 
450  nvars = SCIPgetNVars(scip);
451  assert( nvars > 0 );
452  vars = SCIPgetVars (scip);
453 
454  sdpi = relaxdata->sdpi;
455  assert( sdpi != NULL );
456  varmapper = relaxdata->varmapper;
457  assert( varmapper != NULL );
458 
459  if ( relaxdata->objlimit )
460  {
461  /* set the objective limit */
462  assert( SCIPgetUpperbound(scip) > -SCIPsdpiInfinity(sdpi) );
463  SCIP_CALL( SCIPsdpiSetRealpar(sdpi, SCIP_SDPPAR_OBJLIMIT, SCIPgetUpperbound(scip)) );
464  }
465 
466  /* if this is the root node and we cannot solve the problem, we want to check for the Slater condition independent of the SCIP parameter */
467  rootnode = (SCIPnodeGetNumber(SCIPgetCurrentNode(scip)) == 1);
468 
469  /* solve the problem */
470  SCIP_CALL( SCIPsdpiSolve(sdpi, NULL, &(relaxdata->sdpiterations), rootnode) );
471  relaxdata->lastsdpnode = SCIPnodeGetNumber(SCIPgetCurrentNode(scip));
472 
473  if ( SCIPsdpiWasSolved(sdpi) && SCIPsdpiSolvedOrig(sdpi) )
474  relaxdata->origsolved = TRUE;
475  else if ( ! SCIPsdpiWasSolved(sdpi) )
476  {
477  /* We couldn't solve the problem, not even with a penalty formulation, so we reuse the relaxation result of the parent node (if one exists) */
478  SCIP_NODE* node = SCIPnodeGetParent(SCIPgetCurrentNode(scip));
479 
480  relaxdata->origsolved = FALSE;
481 
482  if ( node == 0 )
483  {
484  /* TODO: if we could generate a lower bound via penalty-with-objective, we could use it here */
485  *result = SCIP_SUSPENDED;
486  SCIPerrorMessage("The relaxation of the root node could not be solved, so there is no hope to solve this instance. \n");
487  return SCIP_ERROR;
488  }
489 
490  *lowerbound = SCIPnodeGetLowerbound(node);
491  *result = SCIP_SUCCESS;
492  SCIP_CALL( SCIPupdateLocalLowerbound(scip, *lowerbound) );
493  SCIPdebugMessage("The relaxation couldn't be solved, so the relaxation result from the parent node was copied. \n");
494  return SCIP_OKAY;
495  }
496 
497 #ifdef SCIP_MORE_DEBUG /* print the optimal solution */
498 
499  SCIP_CALL( SCIPallocBufferArray(scip, &solforscip, nvars) );
500  sollength = nvars;
501  SCIP_CALL( SCIPsdpiGetSol(sdpi, &objforscip, solforscip, &sollength) ); /* get both the objective and the solution from the SDP solver */
502 
503  assert( sollength == nvars ); /* if this isn't true any longer, the getSol-Call was unsuccessfull, because the given array wasn't long enough,
504  * but this can't happen, because the array has enough space for all sdp variables */
505 
506  SCIPdebugMessage("optimal solution: objective = %f, ", objforscip);
507  if ( SCIPsdpiFeasibilityKnown(sdpi) )
508  {
509  SCIPdebugMessage("dual feasible: %d, ", SCIPsdpiIsDualFeasible(sdpi));
510  SCIPdebugMessage("primal feasible: %d, ", SCIPsdpiIsPrimalFeasible(sdpi));
511  }
512  else
513  {
514  SCIPdebugMessage("The solver could not determine feasibility ! ");
515  }
516  for (i = 0; i < nvars; ++i)
517  {
518  printf("%s = %f, ", SCIPvarGetName(vars[i]), solforscip[i]);
519  }
520  SCIPdebugMessage("\n");
521 
522  SCIPfreeBufferArray(scip, &solforscip);
523 #endif
524 
525  if ( SCIPsdpiIsAcceptable(sdpi) )
526  {
527  if ( SCIPsdpiIsDualInfeasible(sdpi) )
528  {
529  SCIPdebugMessage("Node cut off due to infeasibility.\n");
530  *result = SCIP_CUTOFF;
531  return SCIP_OKAY;
532  }
533  else if ( SCIPsdpiIsObjlimExc(sdpi) )
534  {
535  SCIPdebugMessage("Node cut off due to objective limit.\n");
536  *result = SCIP_CUTOFF;
537  return SCIP_OKAY;
538  }
539  else if ( SCIPsdpiIsDualUnbounded(sdpi) )
540  {
541  SCIPdebugMessage("Node unbounded.");
542  *result = SCIP_SUCCESS;
543  *lowerbound = -SCIPinfinity(scip);
544  return SCIP_OKAY;
545  }
546  else if ( SCIPsdpiIsPrimalFeasible(sdpi) && SCIPsdpiIsDualFeasible(sdpi) )
547  {
548 #ifndef SCIP_MORE_DEBUG /* with MORE_DEBUG these were created when accessing solution information to print it to the console */
549  SCIP_Real objforscip;
550  SCIP_Real* solforscip;
551  SCIP_Bool allint;
552 #endif
553  SCIP_SOL* scipsol;
554  SCIP_COL** cols;
555  int ncols;
556  int slength;
557  SCIP_Bool stored;
558  SCIP_Bool allfeas;
559 
560  /* get solution w.r.t. SCIP variables */
561  SCIP_CALL( SCIPallocBufferArray(scip, &solforscip, nvars) );
562  slength = nvars;
563  SCIP_CALL( SCIPsdpiGetSol(sdpi, &objforscip, solforscip, &slength) ); /* get both the objective and the solution from the SDP solver */
564 
565  assert( slength == nvars ); /* if this isn't true any longer, the getSol-Call was unsuccessfull, because the given array wasn't long enough,
566  * but this can't happen, because the array has enough space for all sdp variables */
567 
568  /* check if the solution is integral */
569  allint = TRUE;
570  for (v = 0; v < nvars; v++)
571  {
572  if ( SCIPvarIsIntegral(SCIPsdpVarmapperGetSCIPvar(varmapper, v)) && ! (SCIPisFeasIntegral(scip, solforscip[v])) )
573  {
574  allint = FALSE;
575  break;
576  }
577  }
578 
579  /* create SCIP solution */
580  SCIP_CALL( SCIPcreateSol(scip, &scipsol, NULL) );
581  SCIP_CALL( SCIPsetSolVals(scip, scipsol, nvars, vars, solforscip) );
582 
583  *lowerbound = objforscip;
584  relaxdata->objval = objforscip;
585 
586  if ( allint ) /* if the solution is integer, we might have found a new best solution for the MISDP */
587  {
588  SCIP_CALL( SCIPcheckSol(scip, scipsol, TRUE, FALSE, FALSE, FALSE, &allfeas) ); /* is this really needed ? */
589  if ( allfeas )
590  {
591  SCIP_CALL( SCIPtrySol(scip, scipsol, TRUE, FALSE, FALSE, FALSE, &stored) );
592  if (stored)
593  SCIPdebugMessage("feasible solution for MISDP found, cut node off, solution is stored \n");
594  else
595  SCIPdebugMessage("feasible solution for MISDP found, cut node off, solution is worse than earlier one \n");
596 
597  SCIPfreeBufferArray(scip, &solforscip);
598  SCIP_CALL( SCIPfreeSol(scip, &scipsol) );
599 
600  *result = SCIP_CUTOFF;
601  return SCIP_OKAY;
602  }
603  SCIPdebugMessage("WARNING!!! Found a solution that is feasible for the SDP-solver and integrality, but infeasible for "
604  "SCIP, this will probably not properly get enforced ! \n");
605  }
606 
607  /* copy solution */
608  SCIP_CALL( SCIPgetLPColsData(scip, &cols, &ncols) );
609  for (i = 0; i < ncols; i++)
610  SCIP_CALL( SCIPsetRelaxSolVal(scip, SCIPcolGetVar(cols[i]), SCIPgetSolVal(scip, scipsol, SCIPcolGetVar(cols[i]))) );
611 
612  SCIP_CALL( SCIPmarkRelaxSolValid(scip) );
613  *result = SCIP_SUCCESS;
614 
615  /* if all int and binary vars are integral, nothing else needs to be done */
616  if ( ! allint )
617  {
618  int oldncuts = SCIPgetNCuts(scip);
619 
620  if ( SCIPgetNCuts(scip) > oldncuts )
621  *result = SCIP_SEPARATED;
622 
623  for (i = 0; i < nvars; ++i)
624  {
625  SCIP_VAR* var = vars[i];
626  if ( SCIPvarIsIntegral(var) && ! SCIPisFeasIntegral(scip, solforscip[i]) && ! SCIPisEQ(scip, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)) )
627  {
628  /* we don't set a true score, we will just let the branching rule decide */
629  SCIP_CALL( SCIPaddExternBranchCand(scip, var, 10000.0, solforscip[i]) );
630  }
631  }
632  }
633  SCIPfreeBufferArray(scip, &solforscip);
634  SCIP_CALL( SCIPfreeSol(scip, &scipsol) );
635  }
636 
637  return SCIP_OKAY;
638  }
639 
640 
641 
642  return SCIP_OKAY;
643 }
644 
646 static
647 SCIP_Bool allVarsFixed(
648  SCIP* scip
649  )
650 {
651  int i;
652  SCIP_VAR** vars;
653 
654  assert( scip != NULL );
655 
656  vars = SCIPgetVars(scip);
657 
658  /* try to find a variable that is not fixed */
659  for (i = 0; i < SCIPgetNVars(scip); i++)
660  {
661  if ( SCIPisLT(scip, SCIPvarGetLbLocal(vars[i]), SCIPvarGetUbLocal(vars[i])) )
662  return FALSE;
663  }
664 
665  /* if no variable with lower bound strictly lower than upper bound has been found, all variables are fixed */
666  return TRUE;
667 }
668 
670 static
671 SCIP_DECL_RELAXEXEC(relaxExecSdp)
672 {
673  SCIP_RELAXDATA* relaxdata;
674  int nconss;
675  int i;
676  int nvars;
677  SCIP_VAR** vars;
678  SCIP_Real* ubs;
679  SCIP_Bool cutoff;
680  SCIP_SOL* scipsol;
681  SCIP_Bool stored;
682 #ifdef SCIP_EVEN_MORE_DEBUG
683  SCIP_VAR** varsfordebug = SCIPgetVars(scip);
684  const int nvarsfordebug = SCIPgetNVars(scip);
685 #endif
686 
687  /* construct the lp and make sure, that everything is where it should be */
688  SCIP_CALL( SCIPconstructLP(scip, &cutoff) );
689 
690  if ( cutoff )
691  {
692  *result = SCIP_CUTOFF;
693  return SCIP_OKAY;
694  }
695 
696  /* very important to call flushLP */
697  SCIP_CALL( SCIPflushLP(scip) );
698 
699  /* get varmapper */
700  nconss = SCIPgetNConss(scip);
701 
702 #ifdef SCIP_EVEN_MORE_DEBUG
703  for (i = 0; i < nvarsfordebug; i++)
704  {
705  SCIPdebugMessage("variable %s: status = %u, integral = %u, bounds = [%f, %f] \n", SCIPvarGetName(varsfordebug[i]), SCIPvarGetStatus(varsfordebug[i]),
706  SCIPvarIsIntegral(varsfordebug[i]), SCIPvarGetLbLocal(varsfordebug[i]), SCIPvarGetUbLocal(varsfordebug[i]));
707  }
708 #endif
709 
710  if ( nconss == 0 )
711  {
712  /* if there are no constraints, there is nothing to do */
713  *result = SCIP_DIDNOTRUN;
714  return SCIP_OKAY;
715  }
716 
717  if ( allVarsFixed(scip) )
718  {
719  SCIP_Bool feasible;
720 
721  /* if all variables, really all, are fixed, we give this fixed solution to SCIP */
722 
723  vars = SCIPgetVars(scip);
724  nvars = SCIPgetNVars(scip);
725 
726  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &ubs, nvars) );
727 
728  *lowerbound = 0.0;
729  for (i = 0; i < nvars; i++)
730  {
731  ubs[i] = SCIPvarGetUbLocal(vars[i]);
732  *lowerbound += SCIPvarGetObj(vars[i]) * ubs[i];
733  assert( SCIPisEQ(scip, SCIPvarGetUbLocal(vars[i]), SCIPvarGetLbLocal(vars[i])));
734  }
735  if ( SCIPgetObjsense(scip) == -1 ) /*lint !e641*/
736  *lowerbound *= -1;
737 
738  SCIPdebugMessage("EVERYTHING IS FIXED, objective value = %f\n", *lowerbound);
739 
740  SCIP_CALL( SCIPcreateSol(scip, &scipsol, NULL) );
741  SCIP_CALL( SCIPsetSolVals(scip, scipsol, nvars, vars, ubs) );
742 
743  /* check if the solution really is feasible */
744  SCIP_CALL( SCIPcheckSol(scip, scipsol, FALSE, TRUE, TRUE, TRUE, &feasible) );
745 
746  stored = FALSE;
747  if ( feasible )
748  {
749  SCIP_CALL( SCIPtrySolFree(scip, &scipsol, FALSE, FALSE, FALSE, FALSE, &stored) );
750  }
751  else
752  {
753  SCIP_CALL( SCIPfreeSol(scip, &scipsol) );
754  }
755 
756  if (feasible && stored == 1)
757  {
758  *result = SCIP_CUTOFF;
759  SCIPdebugMessage("New solution was stored, node is cut off !\n");
760  }
761  else
762  {
763  *result = SCIP_CUTOFF;
764  SCIPdebugMessage("Fixed solution either infeasible or not good enough for storage, node cut off !\n");
765  }
766 
767  SCIPfreeBlockMemoryArray(scip, &ubs, nvars);
768 
769  return SCIP_OKAY;
770  }
771 
772  relaxdata = SCIPrelaxGetData(relax);
773 
774  /* update LP Data in Interface */
775  SCIP_CALL( putLpDataInInterface(scip, relaxdata->sdpi, relaxdata->varmapper) );
776 
777  SCIP_CALL( calc_relax(scip, relaxdata, result, lowerbound));
778  relaxdata->sdpcalls++;
779 
780  return SCIP_OKAY;
781 }
782 
783 
784 /*
785  * relaxator specific interface methods
786  */
787 
790 static
791 SCIP_DECL_RELAXINIT(relaxInitSolSdp)
792 {
793  SCIP_RELAXDATA* relaxdata;
794  SCIP_RETCODE retcode;
795  int nvars;
796  SCIP_VAR** vars;
797  SCIP_Real epsilon;
798  SCIP_Real feastol;
799 #if 0
800  int threads;
801 #endif
802  SCIP_Bool sdpinfo;
803  SCIP_Bool slatercheck;
804 
805  assert( relax != NULL );
806 
807  relaxdata = SCIPrelaxGetData(relax);
808 
809  assert( relaxdata != NULL );
810 
811  relaxdata->objval = 0.0;
812  relaxdata->origsolved = FALSE;
813  relaxdata->sdpcalls = 0;
814  relaxdata->sdpiterations = 0;
815 
816  nvars = SCIPgetNVars(scip);
817  vars = SCIPgetVars(scip);
818 
819  /* all SCIPvars will be added to this list, and 3/4 seems like a good load factor (java uses this factor) */
820  SCIP_CALL( SCIPsdpVarmapperCreate(scip, &(relaxdata->varmapper), (int) ceil(1.33 * nvars)) );
821  SCIP_CALL( SCIPsdpVarmapperAddVars(scip, relaxdata->varmapper, nvars, vars) );
822 
823  if ( SCIPgetNVars(scip) > 0 )
824  {
825  SCIP_CALL( putSdpDataInInterface(scip, relaxdata->sdpi, relaxdata->varmapper) );
826  }
827 
828  /* set the parameters of the SDP-Solver */
829  SCIP_CALL( SCIPgetRealParam(scip, "relaxing/SDP/sdpsolverepsilon", &epsilon) );
830  retcode = SCIPsdpiSetRealpar(relaxdata->sdpi, SCIP_SDPPAR_EPSILON, epsilon);
831  if ( retcode == SCIP_PARAMETERUNKNOWN )
832  {
833  SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL,
834  "SDP Solver <%s>: epsilon setting not available -- SCIP parameter has no effect\n",
836  }
837  else
838  {
839  SCIP_CALL( retcode );
840  }
841 
842  SCIP_CALL( SCIPgetRealParam(scip, "relaxing/SDP/sdpsolverfeastol", &feastol) );
843  retcode = SCIPsdpiSetRealpar(relaxdata->sdpi, SCIP_SDPPAR_FEASTOL, feastol);
844  if ( retcode == SCIP_PARAMETERUNKNOWN )
845  {
846  SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL,
847  "SDP Solver <%s>: feastol setting not available -- SCIP parameter has no effect\n",
849  }
850  else
851  {
852  SCIP_CALL( retcode );
853  }
854 
855 #if 0
856  SCIP_CALL( SCIPgetIntParam(scip, "relaxing/SDP/threads", &threads) );
857  retcode = SCIPsdpiSetIntpar(relaxdata->sdpi, SCIP_SDPPAR_THREADS, threads);
858  if ( retcode == SCIP_PARAMETERUNKNOWN )
859  {
860  SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL,
861  "SDP Solver <%s>: threads setting not available -- SCIP parameter has no effect\n",
863  }
864  else
865  {
866  SCIP_CALL( retcode );
867  }
868 #endif
869 
870  SCIP_CALL( SCIPgetBoolParam(scip, "relaxing/SDP/sdpinfo", &sdpinfo) );
871  retcode = SCIPsdpiSetIntpar(relaxdata->sdpi, SCIP_SDPPAR_SDPINFO, (int) sdpinfo);
872  if ( retcode == SCIP_PARAMETERUNKNOWN )
873  {
874  SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL,
875  "SDP Solver <%s>: sdpinfo setting not available -- SCIP parameter has no effect\n",
877  }
878  else
879  {
880  SCIP_CALL( retcode );
881  }
882 
883  SCIP_CALL( SCIPgetBoolParam(scip, "relaxing/SDP/slatercheck", &slatercheck) );
884  retcode = SCIPsdpiSetIntpar(relaxdata->sdpi, SCIP_SDPPAR_SLATERCHECK, (int) slatercheck);
885  if ( retcode == SCIP_PARAMETERUNKNOWN )
886  {
887  SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL,
888  "SDP Solver <%s>: slatercheck setting not available -- SCIP parameter has no effect\n",
890  }
891  else
892  {
893  SCIP_CALL( retcode );
894  }
895 
896  return SCIP_OKAY;
897 }
898 
900 static
901 SCIP_DECL_RELAXCOPY(relaxCopySdp)
902 {
903  assert( scip != NULL );
904  assert( relax != NULL );
905  assert(strcmp(SCIPrelaxGetName(relax), RELAX_NAME) == 0);
906 
907  SCIP_CALL( SCIPincludeRelaxSdp(scip) );
908 
909  return SCIP_OKAY;
910 }
911 
913 static
914 SCIP_DECL_RELAXEXIT(relaxExitSdp)
915 {
916  SCIP_RELAXDATA* relaxdata;
917 
918  assert( scip != NULL );
919  assert( relax != NULL );
920 
921  SCIPdebugMessage("Exiting Relaxation Handler \n");
922 
923  relaxdata = SCIPrelaxGetData(relax);
924  assert( relaxdata != NULL );
925 
926  if ( relaxdata->varmapper != NULL )
927  {
928  SCIP_CALL( SCIPsdpVarmapperFree(scip, &(relaxdata->varmapper)) );
929  }
930 
931  relaxdata->objval = 0.0;
932  relaxdata->origsolved = FALSE;
933  relaxdata->sdpiterations = 0;
934  relaxdata->sdpcalls = 0;
935  relaxdata->lastsdpnode = 0;
936  SCIP_CALL( SCIPsdpiClear(relaxdata->sdpi) );
937 
938  return SCIP_OKAY;
939 }
940 
942 static
943 SCIP_DECL_RELAXFREE(relaxFreeSdp)
944 {/*lint --e{715}*/
945  SCIP_RELAXDATA* relaxdata;
946 
947  relaxdata = SCIPrelaxGetData(relax);
948  assert(relaxdata != NULL);
949 
950  if ( relaxdata->sdpi != NULL )
951  {
952  SCIP_CALL( SCIPsdpiFree(&(relaxdata->sdpi)) );
953  }
954 
955  SCIPfreeMemory(scip, &relaxdata);
956 
957  SCIPrelaxSetData(relax, NULL);
958 
959  return SCIP_OKAY;
960 }
961 
962 
964 SCIP_RETCODE SCIPincludeRelaxSdp(
965  SCIP* scip
966  )
967 {
968  SCIP_RELAXDATA* relaxdata = NULL;
969  SCIP_RELAX* relax;
970  SCIP_SDPI* sdpi;
971 
972  assert( scip != NULL );
973 
974  /* create SDP relaxator data */
975  SCIP_CALL( SCIPallocMemory(scip, &relaxdata) );
976  SCIP_CALL( SCIPsdpiCreate(&sdpi, NULL, SCIPblkmem(scip)) );
977 
978  relaxdata->sdpi = sdpi;
979  relaxdata->lastsdpnode = -1;
980 
981  /* include relaxator */
982  SCIP_CALL( SCIPincludeRelaxBasic(scip, &relax, RELAX_NAME, RELAX_DESC, RELAX_PRIORITY, RELAX_FREQ,
983  relaxExecSdp, relaxdata) );
984  assert( relax != NULL );
985 
986  /* include additional callbacks */
987  SCIP_CALL( SCIPsetRelaxInitsol(scip, relax, relaxInitSolSdp) );
988  SCIP_CALL( SCIPsetRelaxExit(scip, relax, relaxExitSdp) );
989  SCIP_CALL( SCIPsetRelaxFree(scip, relax, relaxFreeSdp) );
990  SCIP_CALL( SCIPsetRelaxCopy(scip, relax, relaxCopySdp) );
991 
992  /* add parameters for SDP-solver */
993  SCIP_CALL( SCIPaddRealParam(scip, "relaxing/SDP/sdpsolverepsilon", "the stopping criterion for the duality gap the sdpsolver should use",
994  &(relaxdata->sdpsolverepsilon), TRUE, DEFAULT_SDPSOLVEREPSILON, 1e-20, 0.001, NULL, NULL) );
995  SCIP_CALL( SCIPaddRealParam(scip, "relaxing/SDP/sdpsolverfeastol", "the feasibility tolerance the SDP solver should use for the SDP constraints",
996  &(relaxdata->sdpsolverfeastol), TRUE, DEFAULT_SDPSOLVERFEASTOL, 1e-17, 0.001, NULL, NULL) );
997 #if 0
998  SCIP_CALL( SCIPaddIntParam(scip, "relaxing/SDP/threads", "number of threads used for SDP solving",
999  &(relaxdata->threads), TRUE, DEFAULT_THREADS, 1, INT_MAX, NULL, NULL) );
1000 #endif
1001  SCIP_CALL( SCIPaddBoolParam(scip, "relaxing/SDP/slatercheck", "should the Slater condition for the dual problem be check ahead of solving each SDP?",
1002  &(relaxdata->slatercheck), TRUE, FALSE, NULL, NULL) );
1003  SCIP_CALL( SCIPaddBoolParam(scip, "relaxing/SDP/sdpinfo", "should the SDP solver output information to the screen?",
1004  &(relaxdata->sdpinfo), TRUE, FALSE, NULL, NULL) );
1005  SCIP_CALL( SCIPaddBoolParam(scip, "relaxing/SDP/objlimit", "should an objective limit be given to the SDP-Solver?",
1006  &(relaxdata->objlimit), TRUE, DEFAULT_OBJLIMIT, NULL, NULL) );
1007 
1008  /* add description of SDP-solver */
1009  SCIP_CALL( SCIPincludeExternalCodeInformation(scip, SCIPsdpiGetSolverName(), SCIPsdpiGetSolverDesc()) );
1010 
1011  return SCIP_OKAY;
1012 }
1013 
1014 
1015 /* external functions */
1016 
1026  SCIP_RELAX* relax,
1027  SCIP_Real* lbvars,
1028  SCIP_Real* ubvars,
1029  int* arraylength
1031  )
1032 {
1033  SCIP_RELAXDATA* relaxdata;
1034 
1035  assert( relax != NULL );
1036  assert( lbvars != NULL );
1037  assert( ubvars != NULL );
1038  assert( arraylength != NULL );
1039  assert( *arraylength >= 0 );
1040 
1041  relaxdata = SCIPrelaxGetData(relax);
1042  assert( relaxdata != NULL );
1043 
1044  SCIP_CALL( SCIPsdpiGetPrimalBoundVars(relaxdata->sdpi, lbvars, ubvars, arraylength) );
1045 
1046  return SCIP_OKAY;
1047 }
1048 
1051  SCIP_RELAX* relax,
1052  SCIP_Bool* success,
1053  SCIP_Real* objval
1054  )
1055 {
1056  SCIP_RELAXDATA* relaxdata;
1057 
1058  assert( relax != NULL );
1059  assert( success != NULL );
1060  assert( objval != NULL );
1061 
1062  relaxdata = SCIPrelaxGetData(relax);
1063  assert( relaxdata != NULL );
1064 
1065  *success = relaxdata->origsolved;
1066  *objval = relaxdata->objval;
1067 
1068  return SCIP_OKAY;
1069 }
1070 
1073  SCIP* scip,
1074  SCIP_RELAX* relax,
1075  SCIP_Bool* success,
1076  SCIP_Real* solarray,
1077  int* sollength
1078  )
1079 {
1080  SCIP_RELAXDATA* relaxdata;
1081 
1082  assert( relax != NULL );
1083  assert( success != NULL );
1084  assert( solarray != NULL );
1085 
1086  relaxdata = SCIPrelaxGetData(relax);
1087  assert( relaxdata != NULL );
1088 
1089  *success = relaxdata->origsolved;
1090 
1091  if ( *sollength >= SCIPgetNVars(scip) )
1092  SCIP_CALL( SCIPsdpiGetSol(relaxdata->sdpi, NULL, solarray, sollength) );
1093  else
1094  {
1095  SCIPdebugMessage("Called SCIPrelaxSdpGetRelaxSol with an array that wasn't big enough, needed length %d, given %d!\n", SCIPgetNVars(scip), *sollength);
1096  *sollength = SCIPgetNVars(scip);
1097  }
1098 
1099  return SCIP_OKAY;
1100 }
1101 
1104  SCIP_RELAX* relax
1105  )
1106 {
1107  assert( relax != NULL );
1108  assert( SCIPrelaxGetData(relax) != NULL );
1109 
1110  return SCIPrelaxGetData(relax)->lastsdpnode;
1111 }
1112 
1115  SCIP_RELAX* relax
1116  )
1117 {
1118  SCIP_RELAXDATA* relaxdata;
1119 
1120  assert( relax != NULL );
1121 
1122  relaxdata = SCIPrelaxGetData(relax);
1123 
1124  assert( relaxdata != NULL );
1125  assert( relaxdata->sdpi != NULL );
1126 
1127  return SCIPsdpiSolvedOrig(relaxdata->sdpi);
1128 }
1129 
1132  SCIP_RELAX* relax
1133  )
1134 {
1135  assert( relax != NULL );
1136  assert( SCIPrelaxGetData(relax) != NULL );
1137 
1138  return SCIPrelaxGetData(relax)->sdpiterations;
1139 }
1140 
1143  SCIP_RELAX* relax
1144  )
1145 {
1146  assert( relax != NULL );
1147  assert( SCIPrelaxGetData(relax) != NULL );
1148 
1149  return ( SCIPrelaxGetData(relax)->sdpcalls );
1150 }
#define RELAX_DESC
Definition: relax_sdp.c:56
SCIP_RETCODE SCIPsdpiFree(SCIP_SDPI **sdpi)
Definition: sdpi.c:908
SCIP_Bool SCIPsdpiIsDualUnbounded(SCIP_SDPI *sdpi)
Definition: sdpi.c:2175
SCIP_RETCODE SCIPsdpiDelLPRows(SCIP_SDPI *sdpi, int firstrow, int lastrow)
Definition: sdpi.c:1369
static SCIP_DECL_RELAXCOPY(relaxCopySdp)
Definition: relax_sdp.c:901
SCIP_RETCODE SCIPsdpVarmapperAddVars(SCIP *scip, SdpVarmapper *varmapper, int nvars, SCIP_VAR **vars)
Definition: SdpVarmapper.c:106
static SCIP_Bool allVarsFixed(SCIP *scip)
Definition: relax_sdp.c:647
static SCIP_DECL_RELAXEXIT(relaxExitSdp)
Definition: relax_sdp.c:914
#define DEFAULT_SDPSOLVERFEASTOL
Definition: relax_sdp.c:61
const char * SCIPsdpiGetSolverName(void)
Definition: sdpi.c:813
SCIP_RETCODE SCIPsdpiGetSol(SCIP_SDPI *sdpi, SCIP_Real *objval, SCIP_Real *dualsol, int *dualsollength)
Definition: sdpi.c:2383
SDP relaxator.
#define RELAX_PRIORITY
Definition: relax_sdp.c:57
SCIP_Bool SCIPsdpiFeasibilityKnown(SCIP_SDPI *sdpi)
Definition: sdpi.c:2084
SCIP_RETCODE SCIPsdpiLoadSDP(SCIP_SDPI *sdpi, int nvars, SCIP_Real *obj, SCIP_Real *lb, SCIP_Real *ub, int nsdpblocks, int *sdpblocksizes, int *sdpnblockvars, int sdpconstnnonz, int *sdpconstnblocknonz, int **sdpconstrow, int **sdpconstcol, SCIP_Real **sdpconstval, int sdpnnonz, int **sdpnblockvarnonz, int **sdpvar, int ***sdprow, int ***sdpcol, SCIP_Real ***sdpval, int nlpcons, SCIP_Real *lplhs, SCIP_Real *lprhs, int lpnnonz, int *lprow, int *lpcol, SCIP_Real *lpval)
Definition: sdpi.c:1089
static SCIP_DECL_RELAXEXEC(relaxExecSdp)
Definition: relax_sdp.c:671
SCIP_VAR * SCIPsdpVarmapperGetSCIPvar(SdpVarmapper *varmapper, int ind)
Definition: SdpVarmapper.c:234
SCIP_Bool SCIPsdpiIsAcceptable(SCIP_SDPI *sdpi)
Definition: sdpi.c:2344
SCIP_RETCODE SCIPsdpVarmapperCreate(SCIP *scip, SdpVarmapper **varmapper, int size)
Definition: SdpVarmapper.c:55
SCIP_RETCODE SCIPrelaxSdpRelaxVal(SCIP_RELAX *relax, SCIP_Bool *success, SCIP_Real *objval)
Definition: relax_sdp.c:1050
SCIP_Bool SCIPsdpiIsDualInfeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:2193
General interface methods for SDP-preprocessing (mainly fixing variables and removing empty rows/cols...
static SCIP_DECL_RELAXFREE(relaxFreeSdp)
Definition: relax_sdp.c:943
struct Sdpvarmapper SdpVarmapper
Definition: SdpVarmapper.h:48
int SCIPsdpVarmapperGetSdpIndex(SdpVarmapper *varmapper, SCIP_VAR *var)
Definition: SdpVarmapper.c:222
static SCIP_RETCODE putLpDataInInterface(SCIP *scip, SCIP_SDPI *sdpi, SdpVarmapper *varmapper)
Definition: relax_sdp.c:286
SCIP_RETCODE SCIPsdpiChgBounds(SCIP_SDPI *sdpi, int nvars, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: sdpi.c:1528
int SCIPrelaxSdpGetNSdpCalls(SCIP_RELAX *relax)
Definition: relax_sdp.c:1142
Constraint handler for SDP-constraints.
SCIP_Bool SCIPsdpiIsObjlimExc(SCIP_SDPI *sdpi)
Definition: sdpi.c:2245
class that maps SCIP variables to SDP indices (the SCIP variables are given SDP indices in the order ...
SCIP_RETCODE SCIPsdpiCreate(SCIP_SDPI **sdpi, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem)
Definition: sdpi.c:852
SCIP_RETCODE SCIPconsSdpGetData(SCIP *scip, SCIP_CONS *cons, int *nvars, int *nnonz, int *blocksize, int *arraylength, int *nvarnonz, int **col, int **row, SCIP_Real **val, SCIP_VAR **vars, int *constnnonz, int *constcol, int *constrow, SCIP_Real *constval)
Definition: cons_sdp.c:2055
SCIP_RETCODE SCIPsdpiAddLPRows(SCIP_SDPI *sdpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, int nnonz, const int *row, const int *col, const SCIP_Real *val)
Definition: sdpi.c:1306
#define DEFAULT_OBJLIMIT
Definition: relax_sdp.c:65
const char * SCIPsdpiGetSolverDesc(void)
Definition: sdpi.c:821
SCIP_RETCODE SCIPsdpiSetIntpar(SCIP_SDPI *sdpi, SCIP_SDPPARAM type, int ival)
Definition: sdpi.c:2629
SCIP_Real SCIPsdpiInfinity(SCIP_SDPI *sdpi)
Definition: sdpi.c:2470
#define RELAX_FREQ
Definition: relax_sdp.c:58
long int SCIPrelaxSdpGetSdpNode(SCIP_RELAX *relax)
Definition: relax_sdp.c:1103
SCIP_Bool SCIPrelaxSdpSolvedOrig(SCIP_RELAX *relax)
Definition: relax_sdp.c:1114
SCIP_RETCODE SCIPsdpiSolve(SCIP_SDPI *sdpi, SCIP_Real *start, int *totalsdpiterations, SCIP_Bool enforceslatercheck)
Definition: sdpi.c:1780
static SCIP_RETCODE calc_relax(SCIP *scip, SCIP_RELAXDATA *relaxdata, SCIP_RESULT *result, SCIP_Real *lowerbound)
Definition: relax_sdp.c:423
static SCIP_RETCODE putSdpDataInInterface(SCIP *scip, SCIP_SDPI *sdpi, SdpVarmapper *varmapper)
Definition: relax_sdp.c:93
SCIP_Bool SCIPsdpiWasSolved(SCIP_SDPI *sdpi)
Definition: sdpi.c:2062
int SCIPrelaxSdpGetNIterations(SCIP_RELAX *relax)
Definition: relax_sdp.c:1131
SCIP_RETCODE SCIPsdpiClear(SCIP_SDPI *sdpi)
Definition: sdpi.c:1512
SCIP_RETCODE SCIPrelaxSdpGetRelaxSol(SCIP *scip, SCIP_RELAX *relax, SCIP_Bool *success, SCIP_Real *solarray, int *sollength)
Definition: relax_sdp.c:1072
SCIP_RETCODE SCIPsdpVarmapperFree(SCIP *scip, SdpVarmapper **varmapper)
Definition: SdpVarmapper.c:80
SCIP_RETCODE SCIPrelaxSdpGetPrimalBoundVars(SCIP_RELAX *relax, SCIP_Real *lbvars, SCIP_Real *ubvars, int *arraylength)
Definition: relax_sdp.c:1025
SCIP_Bool SCIPsdpiIsDualFeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:2211
struct SCIP_SDPi SCIP_SDPI
Definition: type_sdpi.h:65
SCIP_Bool SCIPsdpiIsPrimalFeasible(SCIP_SDPI *sdpi)
Definition: sdpi.c:2157
SCIP_RETCODE SCIPsdpiSetRealpar(SCIP_SDPI *sdpi, SCIP_SDPPARAM type, SCIP_Real dval)
Definition: sdpi.c:2549
#define RELAX_NAME
Definition: relax_sdp.c:55
SCIP_RETCODE SCIPconsSdpGetNNonz(SCIP *scip, SCIP_CONS *cons, int *nnonz, int *constnnonz)
Definition: cons_sdp.c:2151
static SCIP_DECL_RELAXINIT(relaxInitSolSdp)
Definition: relax_sdp.c:791
SCIP_RETCODE SCIPsdpiGetNLPRows(SCIP_SDPI *sdpi, int *nlprows)
Definition: sdpi.c:1598
SCIP_RETCODE SCIPsdpiGetPrimalBoundVars(SCIP_SDPI *sdpi, SCIP_Real *lbvars, SCIP_Real *ubvars, int *arraylength)
Definition: sdpi.c:2410
SCIP_Bool SCIPsdpiSolvedOrig(SCIP_SDPI *sdpi)
Definition: sdpi.c:2072
#define DEFAULT_SDPSOLVEREPSILON
Definition: relax_sdp.c:60
SCIP_RETCODE SCIPincludeRelaxSdp(SCIP *scip)
Definition: relax_sdp.c:964