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