SCIP-SDP  3.1.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
cons_savesdpsol.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-2018 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-2018 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 /*#define SCIP_DEBUG*/
39 /*#define SCIP_MORE_DEBUG *//* shows all cuts added */
40 
41 #include "cons_savesdpsol.h"
42 #include "scip/def.h" /* for SCIP_Real, _Bool, ... */
43 #include <string.h>
44 #include <assert.h>
45 
46 /* constraint handler properties */
47 #define CONSHDLR_NAME "Savesdpsol"
48 #define CONSHDLR_DESC "saving the SDP solution at each node of the tree constraint handler"
49 #define CONSHDLR_SEPAPRIORITY 0
50 #define CONSHDLR_ENFOPRIORITY 0
51 #define CONSHDLR_CHECKPRIORITY 0
52 #define CONSHDLR_SEPAFREQ -1
53 #define CONSHDLR_PROPFREQ -1
54 #define CONSHDLR_EAGERFREQ 100
56 #define CONSHDLR_MAXPREROUNDS -1
57 #define CONSHDLR_DELAYSEPA FALSE
58 #define CONSHDLR_DELAYPROP FALSE
59 #define CONSHDLR_DELAYPRESOL FALSE
60 #define CONSHDLR_NEEDSCONS TRUE
62 #define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP
63 
65 struct SCIP_ConsData
66 {
67  SCIP_Longint node;
68  SCIP_SOL* sol;
69  SCIP_Real maxprimalentry;
70  int nblocks;
71  int* startXnblocknonz;
73  int** startXrow;
75  int** startXcol;
77  SCIP_Real** startXval;
79 };
80 
82 static
83 SCIP_DECL_CONSDELETE(consDeleteSavesdpsol)
84 { /*lint --e{715}*/
85  int b;
86 
87  assert( scip != NULL );
88  assert( conshdlr != NULL );
89  assert( cons != NULL );
90  assert( consdata != NULL );
91  assert( *consdata != NULL );
92 
93  SCIPdebugMessage("Deleting store node data constraint: <%s>.\n", SCIPconsGetName(cons));
94 
95  for (b = 0; b < (*consdata)->nblocks; b++)
96  {
97  SCIPfreeBlockMemoryArray(scip, &((*consdata)->startXval[b]), (*consdata)->startXnblocknonz[b]);
98  SCIPfreeBlockMemoryArray(scip, &((*consdata)->startXcol[b]), (*consdata)->startXnblocknonz[b]);
99  SCIPfreeBlockMemoryArray(scip, &((*consdata)->startXrow[b]), (*consdata)->startXnblocknonz[b]);
100  }
101  SCIPfreeBlockMemoryArray(scip, &((*consdata)->startXval), (*consdata)->nblocks);
102  SCIPfreeBlockMemoryArray(scip, &((*consdata)->startXcol), (*consdata)->nblocks);
103  SCIPfreeBlockMemoryArray(scip, &((*consdata)->startXrow), (*consdata)->nblocks);
104  SCIPfreeBlockMemoryArray(scip, &((*consdata)->startXnblocknonz), (*consdata)->nblocks);
105 
106  SCIPfreeSol(scip, &((*consdata)->sol));
107  SCIPfreeBlockMemory(scip, consdata);
108 
109  return SCIP_OKAY;
110 }
111 
112 
114 static
115 SCIP_DECL_CONSENFORELAX(consEnforelaxSavesdpsol)
116 {
117  assert( scip != NULL );
118  assert( conshdlr != NULL );
119  assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
120  assert( result != NULL );
121 
122  /* do nothing */
123  *result = SCIP_FEASIBLE;
124 
125  return SCIP_OKAY;
126 }
127 
128 
130 static
131 SCIP_DECL_CONSENFOLP(consEnfolpSavesdpsol)
132 {
133  assert( scip != NULL );
134  assert( conshdlr != NULL );
135  assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
136  assert( result != NULL );
137 
138  /* do nothing */
139  *result = SCIP_FEASIBLE;
140 
141  return SCIP_OKAY;
142 }
143 
144 
146 static
147 SCIP_DECL_CONSENFOPS(consEnfopsSavesdpsol)
148 {
149  assert( scip != NULL );
150  assert( conshdlr != NULL );
151  assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
152  assert( result != NULL );
153 
154  /* do nothing */
155  *result = SCIP_FEASIBLE;
156 
157  return SCIP_OKAY;
158 }
159 
160 
162 static
163 SCIP_DECL_CONSCHECK(consCheckSavesdpsol)
164 {
165  assert( scip != NULL );
166  assert( conshdlr != NULL );
167  assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
168  assert( result != NULL );
169 
170  /* do nothing */
171  *result = SCIP_FEASIBLE;
172 
173  return SCIP_OKAY;
174 }
175 
176 
178 static
179 SCIP_DECL_CONSLOCK(consLockSavesdpsol)
180 {
181  assert( scip != NULL );
182  assert( conshdlr != NULL );
183  assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
184 
185  /* do nothing */
186  return SCIP_OKAY;
187 }
188 
189 
191 static
192 SCIP_DECL_CONSHDLRCOPY(conshdlrCopySavesdpsol)
193 {
194  assert( scip != NULL );
195  assert( conshdlr != NULL );
196  assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
197  assert( valid != NULL );
198 
199  /* call inclusion method of constraint handler */
200  SCIP_CALL( SCIPincludeConshdlrSavesdpsol(scip) );
201 
202  *valid = TRUE;
203 
204  return SCIP_OKAY;
205 }
206 
207 
209 static
210 SCIP_DECL_CONSCOPY(consCopySavesdpsol)
211 { /*lint --e{715}*/
212 
213  /* do not do anything: no Savesdpsol constraint should be present in the copy */
214  return SCIP_OKAY;
215 }
216 
217 
219 extern
220 SCIP_RETCODE SCIPincludeConshdlrSavesdpsol(
221  SCIP* scip
222  )
223 {
224  SCIP_CONSHDLR* conshdlr;
225 
226  /* include constraint handler */
227  conshdlr = NULL;
228  SCIP_CALL( SCIPincludeConshdlrBasic(scip, &conshdlr, CONSHDLR_NAME, CONSHDLR_DESC,
230  consEnfolpSavesdpsol, consEnfopsSavesdpsol, consCheckSavesdpsol, consLockSavesdpsol,
231  NULL) );
232  assert( conshdlr != NULL );
233 
234  /* set additional callbacks */
235  SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteSavesdpsol) );
236  SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopySavesdpsol, consCopySavesdpsol) );
237  SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxSavesdpsol) );
238 
239  return SCIP_OKAY;
240 }
241 
242 
243 /*
244  * External functions
245  */
246 
248 SCIP_RETCODE createConsSavesdpsol(
249  SCIP* scip,
250  SCIP_CONS** cons,
251  const char* name,
252  SCIP_Longint node,
253  SCIP_SOL* sol,
254  SCIP_Real maxprimalentry,
255  int nblocks,
256  int* startXnblocknonz,
258  int** startXrow,
260  int** startXcol,
262  SCIP_Real** startXval
264  )
265 {
266  SCIP_CONSDATA* consdata = NULL;
267  SCIP_CONSHDLR* conshdlr;
268  int b;
269 
270  assert( scip != NULL );
271  assert( name != NULL );
272  assert( sol != NULL );
273  assert( nblocks >= 0 );
274  assert( nblocks == 0 || startXnblocknonz != NULL );
275  assert( nblocks == 0 || startXrow != NULL );
276  assert( nblocks == 0 || startXcol != NULL );
277  assert( nblocks == 0 || startXval != NULL );
278 
279  SCIPdebugMessage("Creating Savesdpsol constraint <%s>.\n", name);
280 
281  /* find the node data constraint handler */
282  conshdlr = SCIPfindConshdlr(scip, "Savesdpsol");
283  if ( conshdlr == NULL )
284  {
285  SCIPerrorMessage("Savesdpsol constraint handler not found\n");
286  return SCIP_PLUGINNOTFOUND;
287  }
288 
289  /* create constraint data */
290  SCIP_CALL( SCIPallocBlockMemory(scip, &consdata) );
291 
292  consdata->node = node;
293  SCIP_CALL( SCIPcreateSolCopy(scip, &(consdata->sol), sol) );
294  SCIP_CALL( SCIPunlinkSol(scip, consdata->sol) );
295  consdata->maxprimalentry = maxprimalentry;
296 
297  /* allocate memory for primal solution and copy startXnblocknonz*/
298  if ( startXnblocknonz != NULL )
299  {
300  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &consdata->startXnblocknonz, startXnblocknonz, nblocks) );
301  }
302  else
303  consdata->startXnblocknonz = NULL;
304 
305  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->startXrow, nblocks) );
306  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->startXcol, nblocks) );
307  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->startXval, nblocks) );
308 
309  for (b = 0; b < nblocks; b++)
310  {
311  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &consdata->startXrow[b], startXrow[b], startXnblocknonz[b]) );
312  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &consdata->startXcol[b], startXcol[b], startXnblocknonz[b]) );
313  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &consdata->startXval[b], startXval[b], startXnblocknonz[b]) );
314  }
315 
316  consdata->nblocks = nblocks;
317 
318  /* create constraint */
319  SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, FALSE, FALSE, FALSE, FALSE, FALSE,
320  TRUE, FALSE, TRUE, FALSE, TRUE));
321 
322  return SCIP_OKAY;
323 }
324 
326 SCIP_Longint SCIPconsSavesdpsolGetNodeIndex(
327  SCIP* scip,
328  SCIP_CONS* cons
329  )
330 {
331  SCIP_CONSDATA* consdata;
332 
333  assert ( scip != NULL );
334  assert ( cons != NULL );
335 
336  consdata = SCIPconsGetData(cons);
337 
338  assert ( consdata != NULL );
339 
340  return consdata->node;
341 }
342 
345  SCIP* scip,
346  SCIP_CONS* cons
347  )
348 {
349  SCIP_CONSDATA* consdata;
350 
351  assert ( scip != NULL );
352  assert ( cons != NULL );
353 
354  consdata = SCIPconsGetData(cons);
355 
356  assert ( consdata != NULL );
357 
358  return consdata->sol;
359 }
360 
363  SCIP* scip,
364  SCIP_CONS* cons
365  )
366 {
367  SCIP_CONSDATA* consdata;
368 
369  assert ( scip != NULL );
370  assert ( cons != NULL );
371 
372  consdata = SCIPconsGetData(cons);
373 
374  assert ( consdata != NULL );
375 
376  return consdata->maxprimalentry;
377 }
378 
381  SCIP* scip,
382  SCIP_CONS* cons,
383  int nblocks,
384  int* startXnblocknonz
386  )
387 {
388  SCIP_CONSDATA* consdata;
389  int b;
390 
391  assert ( scip != NULL );
392  assert ( cons != NULL );
393 
394  consdata = SCIPconsGetData(cons);
395 
396  assert ( consdata != NULL );
397 
398  if ( nblocks != consdata->nblocks )
399  {
400  SCIPerrorMessage("SCIPconsSavesdpsolGetPrimalMatrix expected nblocks = %d but got %d\n", consdata->nblocks, nblocks);
401  return SCIP_ERROR;
402  }
403 
404  for (b = 0; b < nblocks; b++)
405  startXnblocknonz[b] = consdata->startXnblocknonz[b];
406 
407  return SCIP_OKAY;
408 }
409 
412  SCIP* scip,
413  SCIP_CONS* cons,
414  int nblocks,
415  int* startXnblocknonz,
417  int** startXrow,
418  int** startXcol,
419  SCIP_Real** startXval
420  )
421 {
422  SCIP_CONSDATA* consdata;
423  int b;
424  int i;
425  SCIP_Bool msgthrown = FALSE;
426 
427  assert ( scip != NULL );
428  assert ( cons != NULL );
429 
430  consdata = SCIPconsGetData(cons);
431 
432  assert ( consdata != NULL );
433 
434  if ( nblocks != consdata->nblocks )
435  {
436  SCIPerrorMessage("SCIPconsSavesdpsolGetPrimalMatrix expected nblocks = %d but got %d\n", consdata->nblocks, nblocks);
437  return SCIP_ERROR;
438  }
439 
440  for (b = 0; b < nblocks; b++)
441  {
442  if ( startXnblocknonz[b] < consdata->startXnblocknonz[b] )
443  {
444  if ( ! msgthrown )
445  {
446  SCIPdebugMessage("Unsufficient arraylength %d for block %d in SCIPconsSavesdpsolGetPrimalMatrix, need at least %d!\n",
447  startXnblocknonz[b], b, consdata->startXnblocknonz[b]);
448  msgthrown = TRUE;
449  }
450  startXnblocknonz[b] = consdata->startXnblocknonz[b];
451  }
452  else
453  {
454  startXnblocknonz[b] = consdata->startXnblocknonz[b];
455  for (i = 0; i < consdata->startXnblocknonz[b]; i++)
456  {
457  startXrow[b][i] = consdata->startXrow[b][i];
458  startXcol[b][i] = consdata->startXcol[b][i];
459  startXval[b][i] = consdata->startXval[b][i];
460  }
461  }
462  }
463 
464  return SCIP_OKAY;
465 }
#define CONSHDLR_NEEDSCONS
static SCIP_DECL_CONSENFOLP(consEnfolpSavesdpsol)
SCIP_Real SCIPconsSavesdpsolGetMaxPrimalEntry(SCIP *scip, SCIP_CONS *cons)
static SCIP_DECL_CONSENFORELAX(consEnforelaxSavesdpsol)
SCIP_RETCODE SCIPconsSavesdpsolGetPrimalMatrixNonzeros(SCIP *scip, SCIP_CONS *cons, int nblocks, int *startXnblocknonz)
#define CONSHDLR_CHECKPRIORITY
SCIP_RETCODE createConsSavesdpsol(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_Longint node, SCIP_SOL *sol, SCIP_Real maxprimalentry, int nblocks, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval)
SCIP_SOL * SCIPconsSavesdpsolGetDualVector(SCIP *scip, SCIP_CONS *cons)
static SCIP_DECL_CONSCOPY(consCopySavesdpsol)
static SCIP_DECL_CONSLOCK(consLockSavesdpsol)
#define CONSHDLR_ENFOPRIORITY
static SCIP_DECL_CONSENFOPS(consEnfopsSavesdpsol)
static SCIP_DECL_CONSDELETE(consDeleteSavesdpsol)
#define CONSHDLR_EAGERFREQ
SCIP_RETCODE SCIPconsSavesdpsolGetPrimalMatrix(SCIP *scip, SCIP_CONS *cons, int nblocks, int *startXnblocknonz, int **startXrow, int **startXcol, SCIP_Real **startXval)
static SCIP_DECL_CONSCHECK(consCheckSavesdpsol)
SCIP_RETCODE SCIPincludeConshdlrSavesdpsol(SCIP *scip)
static SCIP_DECL_CONSHDLRCOPY(conshdlrCopySavesdpsol)
SCIP_Longint SCIPconsSavesdpsolGetNodeIndex(SCIP *scip, SCIP_CONS *cons)
#define CONSHDLR_DESC
#define CONSHDLR_NAME
char name[SCIP_MAXSTRLEN]
constraint handler for saving SDP solutions in nodes