SCIP-SDP  3.2.0
SdpVarmapper.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-2020 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-2020 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 #include "scip/scip.h"
39 #include "scip/type_misc.h" /* for SCIP Hashmap */
40 #include "SdpVarmapper.h"
41 
42 /* turn off lint warnings for whole file: */
43 /*lint --e{788,818}*/
44 
45 struct Sdpvarmapper
46 {
47  SCIP_VAR** sdptoscip;
48  SCIP_HASHMAP* sciptosdp;
49  int nvars;
50 };
51 
54  SCIP* scip,
55  SdpVarmapper** varmapper,
56  int size
57  )
58 {
59  assert ( scip != NULL );
60  assert ( varmapper != NULL );
61  assert ( size >= 0 );
62 
63  SCIP_CALL( SCIPallocBlockMemory(scip, varmapper) );
64  (*varmapper)->nvars = 0;
65  (*varmapper)->sdptoscip = NULL;
66 
67  if ( size == 0 )
68  {
69  SCIPdebugMsg(scip, "SCIPsdpVarmapperCreate called for size 0!\n");
70 
71  return SCIP_OKAY;
72  }
73 
74  SCIP_CALL( SCIPhashmapCreate(&((*varmapper)->sciptosdp), SCIPblkmem(scip), size) );
75 
76  return SCIP_OKAY;
77 }
78 
80 SCIP_RETCODE SCIPsdpVarmapperFree(
81  SCIP* scip,
82  SdpVarmapper** varmapper
83  )
84 {
85  int i;
86 
87  SCIPdebugMsg(scip, "Freeing SdpVarmapper \n");
88 
89  assert ( scip != NULL );
90  assert ( varmapper != NULL );
91 
92  /* release all vars */
93  for (i = 0; i < (*varmapper)->nvars; i++)
94  {
95  SCIP_CALL( SCIPreleaseVar(scip, &((*varmapper)->sdptoscip[i])) );
96  }
97 
98  if ( (*varmapper)->nvars )
99  SCIPhashmapFree(&((*varmapper)->sciptosdp));
100 
101  SCIPfreeBlockMemoryArrayNull(scip, &(*varmapper)->sdptoscip, (*varmapper)->nvars);
102  SCIPfreeBlockMemory(scip, varmapper);
103 
104  return SCIP_OKAY;
105 }
106 
109  SCIP* scip,
110  SdpVarmapper* varmapper,
111  int nvars,
112  SCIP_VAR** vars
113  )
114 { /*lint --e{818}*/
115  int i;
116  SCIP_Bool reallocneeded; /* we allocate memory to add nvars variables, but if some of them already existed in the varmapper, we don't add them and
117  * should reallocate later */
118  int allocsize;
119 
120  if ( nvars == 0 )
121  return SCIP_OKAY;
122 
123  assert ( scip != NULL );
124  assert ( varmapper != NULL );
125  assert ( nvars >= 0 );
126  assert ( vars != NULL );
127 
128  allocsize = varmapper->nvars + nvars;
129  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &(varmapper->sdptoscip), varmapper->nvars, allocsize) );
130 
131  reallocneeded = FALSE;
132 
133  for (i = 0; i < nvars; i++)
134  {
135  if ( ! (SCIPhashmapExists(varmapper->sciptosdp, vars[i])) ) /* make sure, that there are no duplicates in the lists */
136  {
137  varmapper->sdptoscip[varmapper->nvars] = vars[i];
138 #if ( SCIP_VERSION >= 700 || (SCIP_VERSION >= 602 && SCIP_SUBVERSION > 0) )
139  SCIP_CALL( SCIPhashmapInsertInt(varmapper->sciptosdp, (void*) vars[i], varmapper->nvars) );
140 #else
141  SCIP_CALL( SCIPhashmapInsert(varmapper->sciptosdp, (void*) vars[i], (void*) (size_t) varmapper->nvars) );
142 #endif
143  varmapper->nvars++;
144  SCIP_CALL( SCIPcaptureVar(scip, vars[i]) );
145  }
146  else
147  {
148  SCIPdebugMsg(scip, "variable %s was not added to the varmapper as it was already part of it \n", SCIPvarGetName(vars[i]));
149  reallocneeded = TRUE;
150  }
151  }
152 
153  if ( reallocneeded )
154  {
155  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &(varmapper->sdptoscip), allocsize, varmapper->nvars) );
156  }
157 
158  return SCIP_OKAY;
159 }
160 
163  SCIP* scip,
164  SdpVarmapper* varmapper,
165  SCIP_VAR* var,
166  int pos
167  )
168 {
169  int i;
170 
171  assert ( scip != NULL );
172  assert ( varmapper != NULL );
173  assert ( var != NULL );
174  assert ( pos >= 0 );
175  assert ( pos <= varmapper->nvars );
176 
177  if ( ! SCIPhashmapExists(varmapper->sciptosdp, var) ) /* make sure, that there are no duplicates in the lists */
178  {
179  if ( pos == varmapper->nvars ) /* add it to the end */
180  {
181  SCIP_CALL(SCIPsdpVarmapperAddVars(scip, varmapper, 1, &var));
182  }
183  else
184  {
185  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &varmapper->sdptoscip, varmapper->nvars, varmapper->nvars + 1) );
186 
187  /* move all variables after pos one spot to the right to make room for the new one */
188  for (i = varmapper->nvars - 1; i >= pos; i--)
189  {
190  varmapper->sdptoscip[i + 1] = varmapper->sdptoscip[i]; /*lint !e679*/
191 #if ( SCIP_VERSION >= 700 || (SCIP_VERSION >= 602 && SCIP_SUBVERSION > 0) )
192  SCIP_CALL( SCIPhashmapSetImageInt(varmapper->sciptosdp, varmapper->sdptoscip[i + 1], i + 1) );
193 #else
194  SCIP_CALL( SCIPhashmapSetImage(varmapper->sciptosdp, varmapper->sdptoscip[i + 1], (void*) (size_t) (i + 1)) );
195 #endif
196  }
197 
198  varmapper->sdptoscip[pos] = var;
199 #if ( SCIP_VERSION >= 700 || (SCIP_VERSION >= 602 && SCIP_SUBVERSION > 0) )
200  SCIP_CALL( SCIPhashmapInsertInt(varmapper->sciptosdp, var, pos) );
201 #else
202  SCIP_CALL( SCIPhashmapInsert(varmapper->sciptosdp, var, (void*) (size_t) pos) );
203 #endif
204  varmapper->nvars++;
205  SCIP_CALL( SCIPcaptureVar(scip, var) );
206  }
207  }
208  else
209  SCIPdebugMsg(scip, "variable %s was not added to the varmapper as it was already part of it.\n", SCIPvarGetName(var));
210 
211  return SCIP_OKAY;
212 }
213 
216  SdpVarmapper* varmapper
217  )
218 {
219  assert ( varmapper != NULL );
220 
221  return varmapper->nvars;
222 }
223 
226  SdpVarmapper* varmapper,
227  SCIP_VAR* var
228  )
229 {
230  assert ( varmapper != NULL );
231  assert ( var != NULL );
232 
233  return SCIPhashmapExists(varmapper->sciptosdp, var);
234 }
235 
238  SdpVarmapper* varmapper,
239  SCIP_VAR* var
240  )
241 {
242  assert ( varmapper != NULL );
243  assert ( var != NULL );
244 
245 #if ( SCIP_VERSION >= 700 || (SCIP_VERSION >= 602 && SCIP_SUBVERSION > 0) )
246  return SCIPhashmapGetImageInt(varmapper->sciptosdp, (void*) var);
247 #else
248  return (int) (size_t) SCIPhashmapGetImage(varmapper->sciptosdp, (void*) var);
249 #endif
250 }
251 
254  SdpVarmapper* varmapper,
255  int ind
256  )
257 {
258  assert ( varmapper != NULL );
259  assert ( 0 <= ind && ind < varmapper->nvars );
260 
261  return varmapper->sdptoscip[ind];
262 }
263 
266  SCIP* scip,
267  SdpVarmapper* varmapper,
268  int ind
269  )
270 {
271  SCIP_VAR* var;
272  int i;
273 
274  assert ( scip != NULL );
275  assert ( varmapper != NULL );
276  assert ( 0 <= ind && ind < varmapper->nvars );
277 
278  var = varmapper->sdptoscip[ind];
279 
280  assert ( SCIPhashmapExists(varmapper->sciptosdp, var) );
281 
282  SCIP_CALL( SCIPhashmapRemove(varmapper->sciptosdp, var) );
283  SCIP_CALL( SCIPreleaseVar(scip, &(varmapper)->sdptoscip[ind]) );
284 
285  /* shift all entries of the sdptoscip-array behind ind one to the left and update their sciptosdp-entries */
286  for (i = ind + 1; i < varmapper->nvars; i++)
287  {
288  varmapper->sdptoscip[i - 1] = varmapper->sdptoscip[i];
289 #if ( SCIP_VERSION >= 700 || (SCIP_VERSION >= 602 && SCIP_SUBVERSION > 0) )
290  SCIP_CALL( SCIPhashmapSetImageInt(varmapper->sciptosdp, varmapper->sdptoscip[i - 1], i - 1) );
291 #else
292  SCIP_CALL( SCIPhashmapSetImage(varmapper->sciptosdp, varmapper->sdptoscip[i - 1], (void*) (size_t) (i - 1)) );
293 #endif
294  }
295 
296  /* reallocate memory */
297  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &varmapper->sdptoscip, varmapper->nvars, varmapper->nvars - 1) );
298 
299  varmapper->nvars--;
300 
301  return SCIP_OKAY;
302 }
303 
306  SCIP* scip,
307  SdpVarmapper* varmapper
308  )
309 {
310  SCIP_VAR* var;
311  int k;
312 
313  assert ( scip != NULL );
314  assert ( varmapper != NULL );
315 
316  for (k = 0; k < varmapper->nvars; ++k)
317  {
318  SCIP_CALL( SCIPgetTransformedVar(scip, varmapper->sdptoscip[k], &var) );
319  SCIP_CALL( SCIPcaptureVar(scip, var) );
320 
321  SCIP_CALL( SCIPhashmapRemove(varmapper->sciptosdp, varmapper->sdptoscip[k]) );
322 #if ( SCIP_VERSION >= 700 || (SCIP_VERSION >= 602 && SCIP_SUBVERSION > 0) )
323  SCIP_CALL( SCIPhashmapInsertInt(varmapper->sciptosdp, var, k) );
324 #else
325  SCIP_CALL( SCIPhashmapInsert(varmapper->sciptosdp, var, (void*) (size_t) k) );
326 #endif
327  SCIP_CALL( SCIPreleaseVar(scip, &varmapper->sdptoscip[k]) );
328 
329  varmapper->sdptoscip[k] = var;
330  }
331 
332  return SCIP_OKAY;
333 }
334 
337  SCIP* scip,
338  SdpVarmapper* oldmapper,
339  SdpVarmapper* newmapper
340  )
341 {
342  int nvars;
343  int i;
344 
345  nvars = oldmapper->nvars;
346 
347  newmapper->nvars = nvars;
348 
349  /* allocate memory */
350  SCIP_CALL( SCIPallocBlockMemory(scip, &newmapper) );
351  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &newmapper->sdptoscip, nvars) );
352 
353  /* copy entries */
354  for (i = 0; i < nvars; i++)
355  {
356  newmapper->sdptoscip[i] = oldmapper->sdptoscip[i];
357 #if ( SCIP_VERSION >= 700 || (SCIP_VERSION >= 602 && SCIP_SUBVERSION > 0) )
358  SCIP_CALL( SCIPhashmapInsertInt(newmapper->sciptosdp, oldmapper->sdptoscip[i], i) );
359 #else
360  SCIP_CALL( SCIPhashmapInsert(newmapper->sciptosdp, oldmapper->sdptoscip[i], (void*) (size_t) i) );
361 #endif
362  SCIP_CALL( SCIPcaptureVar(scip, newmapper->sdptoscip[i]) );
363  }
364 
365  return SCIP_OKAY;
366 }
SCIP_RETCODE SCIPsdpVarmapperAddVars(SCIP *scip, SdpVarmapper *varmapper, int nvars, SCIP_VAR **vars)
Definition: SdpVarmapper.c:108
SCIP_Bool SCIPsdpVarmapperExistsSCIPvar(SdpVarmapper *varmapper, SCIP_VAR *var)
Definition: SdpVarmapper.c:225
SCIP_RETCODE SCIPsdpVarmapperClone(SCIP *scip, SdpVarmapper *oldmapper, SdpVarmapper *newmapper)
Definition: SdpVarmapper.c:336
SCIP_VAR * SCIPsdpVarmapperGetSCIPvar(SdpVarmapper *varmapper, int ind)
Definition: SdpVarmapper.c:253
int SCIPsdpVarmapperGetNVars(SdpVarmapper *varmapper)
Definition: SdpVarmapper.c:215
SCIP_RETCODE SCIPsdpVarmapperCreate(SCIP *scip, SdpVarmapper **varmapper, int size)
Definition: SdpVarmapper.c:53
struct Sdpvarmapper SdpVarmapper
Definition: SdpVarmapper.h:48
int SCIPsdpVarmapperGetSdpIndex(SdpVarmapper *varmapper, SCIP_VAR *var)
Definition: SdpVarmapper.c:237
maps SCIP variables to SDP indices (the SCIP variables are given SDP indices in the order in which th...
SCIP_RETCODE SCIPsdpVarmapperTransform(SCIP *scip, SdpVarmapper *varmapper)
Definition: SdpVarmapper.c:305
SCIP_RETCODE SCIPsdpVarmapperInsertVar(SCIP *scip, SdpVarmapper *varmapper, SCIP_VAR *var, int pos)
Definition: SdpVarmapper.c:162
SCIP_RETCODE SCIPsdpVarmapperFree(SCIP *scip, SdpVarmapper **varmapper)
Definition: SdpVarmapper.c:80
SCIP_RETCODE SCIPsdpVarmapperRemoveSdpIndex(SCIP *scip, SdpVarmapper *varmapper, int ind)
Definition: SdpVarmapper.c:265