Scippy

SCIP

Solving Constraint Integer Programs

compr_largestrepr.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2015 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file compr_largestrepr.c
17  * @brief largestrepr tree compression
18  * @author Jakob Witzig
19  */
20 
21 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
22 
23 #include <assert.h>
24 
25 #include "scip/compr_largestrepr.h"
26 #include "scip/compr.h"
27 #include "scip/pub_reopt.h"
28 
29 
30 #define COMPR_NAME "largestrepr"
31 #define COMPR_DESC "heuristic searching for large common representatives"
32 #define COMPR_PRIORITY 2000
33 #define COMPR_MINNNODES 20
34 
35 #define DEFAUL_MEM_REPR 10
36 
37 /*
38  * Data structures
39  */
40 
41 /** tree compression data */
42 struct SCIP_ComprData
43 {
44  /* representative data */
45  SCIP_REOPTNODE** representatives; /**< list of representatives */
46  int nrepresentatives; /**< number of representatives */
47  int representativessize;/**< allocated memory for representatives */
48  SCIP_Bool initialized; /**< was compressor data initialized? */
49 
50  /* statictics */
51  SCIP_Real rate; /**< rate of compression */
52  SCIP_Real loi; /**< loss of information */
53  int nnodes; /**< number of nodes after compressing */
54 
55  /* parameters */
56  int mincomvars; /**< minimal number of common variables */
57  int niters; /**< number of runs in the constrained part */
58 };
59 
60 
61 /*
62  * Local methods
63  */
64 
65 /** calculate a signature of variables fixed to 0 and 1 by using binary shift
66  * and or operations. we calculate the signature on the basis of SCIPvarGetProbindex() % 64
67  */
68 static
70  SCIP_VAR** vars, /**< variable array */
71  SCIP_Real* vals, /**< value array */
72  int nvars, /**< number of variables */
73  SCIP_Longint* signature0, /**< pointer to store the signatures of variables fixed to 0 */
74  SCIP_Longint* signature1 /**< pointer to store the signatures of variables fixed to 1 */
75  )
76 {
77  int v;
78 
79  (*signature0) = 0;
80  (*signature1) = 0;
81 
82  for( v = nvars - 1; v >= 0; --v )
83  {
84  if( vals[v] == 0 )
85  (*signature0) |= ((unsigned int)1 << ((unsigned int)SCIPvarGetProbindex(vars[v]) % 64)); /*lint !e647*/
86  else
87  (*signature1) |= ((unsigned int)1 << ((unsigned int)SCIPvarGetProbindex(vars[v]) % 64)); /*lint !e647*/
88  }
89 
90  return;
91 }
92 
93 /** try to find a representation of the current search frontier.
94  *
95  * We use the signatures of variables fixed to 0 and 1 to decide if there is
96  * definitely no intersection or if the intersection is potentially non-empty.
97  *
98  * To find a good representation we start the procedure with a node and choose the best one.
99  * the heuristic tries to find a representation of size 2 in each iteration, i.e., runs in the
100  * constrained part.
101  */
102 static
104  SCIP* scip, /**< SCIP data structure */
105  SCIP_COMPR* compr, /**< compression method */
106  SCIP_COMPRDATA* comprdata, /**< compression data */
107  SCIP_RESULT* result /**< result pointer */
108  )
109 {
110  SCIP_NODE* currentnode;
111  SCIP_VAR*** repvars;
112  SCIP_Real** repvals;
113  int* nrepvars;
114  SCIP_VAR*** vars;
115  SCIP_Real** vals;
116  SCIP_BOUNDTYPE** bounds;
117  SCIP_Bool* covered;
118  const char** varnames;
119  SCIP_Real loi;
120  int nreps;
121  SCIP_Longint* signature0;
122  SCIP_Longint* signature1;
123  int* common_vars;
124  unsigned int* leaveids;
125  int* nvars;
126  int nids;
127  int nleaveids;
128  int k;
129  int current_id;
130  int start_id;
131 
132  assert(scip != NULL);
133  assert(comprdata != NULL);
134 
135  *result = SCIP_DIDNOTRUN;
136 
137  assert(SCIPgetStage(scip) <= SCIP_STAGE_PRESOLVED);
138 
139  currentnode = NULL;
140  nleaveids = SCIPgetNReoptLeaves(scip, currentnode);
141 
142  SCIPdebugMessage(">> start <%s> (nleaves: %d)\n", COMPR_NAME, nleaveids);
143 
144  if( SCIPcomprGetMinNodes(compr) > nleaveids )
145  {
146  SCIPdebugMessage("-> skip compression (min. leaves = %d)\n", SCIPcomprGetMinNodes(compr));
147  return SCIP_OKAY;
148  }
149 
150  *result = SCIP_DIDNOTFIND;
151 
152  SCIPdebugMessage("-> try compression with %d node(s)\n", nleaveids);
153 
154  /* collect the nodes to compress */
155  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &leaveids, nleaveids) );
156 
157  SCIP_CALL( SCIPgetReoptLeaveIDs(scip, currentnode, leaveids, nleaveids, &nids) );
158  assert(nids == nleaveids);
159 
160  /* allocate memory to store the old tree */
161  SCIP_CALL( SCIPallocBufferArray(scip, &vars, nleaveids) );
162  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nleaveids) );
163  SCIP_CALL( SCIPallocBufferArray(scip, &bounds, nleaveids) );
164  SCIP_CALL( SCIPallocBufferArray(scip, &nvars, nleaveids) );
165  SCIP_CALL( SCIPallocBufferArray(scip, &varnames, SCIPgetNOrigVars(scip)) );
166 
167  /* allocate memory to store the signatures */
168  SCIP_CALL( SCIPallocBufferArray(scip, &signature0, nleaveids) );
169  SCIP_CALL( SCIPallocBufferArray(scip, &signature1, nleaveids) );
170 
171  /* get data of nodes */
172  for( k = 0; k < nleaveids; k++ )
173  {
174  SCIP_REOPTNODE* reoptnode;
175  int mem_vars;
176  int nvars2;
177  int nafterdualvars;
178 
179  mem_vars = SCIPgetNBinVars(scip);
180 
181  /* allocate memory */
182  SCIP_CALL( SCIPallocBufferArray(scip, &vars[k], mem_vars) ); /*lint !e866*/
183  SCIP_CALL( SCIPallocBufferArray(scip, &vals[k], mem_vars) ); /*lint !e866*/
184  SCIP_CALL( SCIPallocBufferArray(scip, &bounds[k], mem_vars) ); /*lint !e866*/
185 
186  /* get the branching path */
187  reoptnode = SCIPgetReoptnode(scip, leaveids[k]);
188  SCIPgetReoptnodePath(scip, reoptnode, vars[k], vals[k], bounds[k], mem_vars, &nvars2, &nafterdualvars);
189 
190  nvars[k] = nvars2 + nafterdualvars;
191 
192  /* calculate the signature*/
193  calcSignature(vars[k], vals[k], nvars[k], &signature0[k], &signature1[k]);
194  }
195 
196  for( start_id = 0; start_id < nleaveids; start_id++ )
197  {
198  nreps = -1;
199  loi = 0.0;
200 
201  /* initialize the covered-array with FALSE */
202  SCIP_CALL( SCIPallocBufferArray(scip, &covered, nleaveids) );
203 
204  for( k = 0; k < nleaveids; k++ )
205  covered[k] = FALSE;
206 
207  current_id = start_id;
208 
209  /* initialize storage for representatives */
210  SCIP_CALL( SCIPallocBufferArray(scip, &repvars, 2+comprdata->niters) );
211  SCIP_CALL( SCIPallocBufferArray(scip, &repvals, 2+comprdata->niters) );
212  SCIP_CALL( SCIPallocBufferArray(scip, &nrepvars, 2+comprdata->niters) );
213 
214  SCIPdebugMessage("+---+ start round %d +---+\n", start_id+1);
215 
216  /* try to find common representatives */
217  while( nreps-1 <= comprdata->niters
218  && (nreps == -1 || (current_id % nleaveids) != start_id) )
219  {
220  int* idx_common_vars;
221  int* idx_non_zero;
222  int* covered_ids;
223  int ncovered;
224  int ncommon_vars;
225  int nnon_zero_vars;
226  int next_id;
227  int nnemptyinters;
228  int v;
229 
230  /* find the first id which is not covered */
231  while( covered[current_id % nleaveids] && (nreps == -1 || (current_id % nleaveids) != start_id) )
232  current_id++;
233 
234  current_id %= nleaveids;
235 
236  if( nreps > 0 && current_id == start_id )
237  goto TERMINATE;
238 
239  /* if the this is the fist round with a new start_id we set the number of representatives to 0 */
240  nreps = MAX(0, nreps);
241 
242  nnemptyinters = 0;
243 
244  /* mark the node as covered */
245  covered[current_id] = TRUE;
246 
247  /* find the next not covered id */
248  next_id = (current_id+1) % nleaveids ;
249  while( covered[next_id] && next_id != current_id )
250  next_id = (next_id+1) % nleaveids;
251 
252  if( next_id == current_id )
253  goto TERMINATE;
254 
255  /* get a clear array of size SCIPgetNOrigVars */
256  SCIP_CALL( SCIPallocClearMemoryArray(scip, &common_vars, SCIPgetNOrigVars(scip)) );
257 
258  /* allocate buffer */
259  ncommon_vars = 0;
260  nnon_zero_vars = 0;
261  SCIP_CALL( SCIPallocBufferArray(scip, &idx_common_vars, nvars[current_id]) );
262  SCIP_CALL( SCIPallocBufferArray(scip, &idx_non_zero, nvars[current_id]) );
263  SCIP_CALL( SCIPallocBufferArray(scip, &covered_ids, nleaveids) );
264  ncovered = 0;
265 
266  /* initialize common vars:
267  * vars[i] = 0 -> variable with idx i is not fixed
268  * vars[i] = 1 -> variable with idx i is fixed to zero
269  * vars[i] = 2 -> variable with idx i is fixed to one */
270  for( v = 0; v < nvars[current_id]; v++ )
271  {
272  if( SCIPisFeasEQ(scip, vals[current_id][v], 0.0) )
273  common_vars[SCIPvarGetProbindex(vars[current_id][v])] = 1;
274  else
275  {
276  assert(SCIPisFeasEQ(scip, vals[current_id][v], 1.0));
277  common_vars[SCIPvarGetProbindex(vars[current_id][v])] = 2;
278  }
279 
280  varnames[SCIPvarGetProbindex(vars[current_id][v])] = SCIPvarGetName(vars[current_id][v]);
281 
282  idx_non_zero[nnon_zero_vars] = SCIPvarGetProbindex(vars[current_id][v]);
283  nnon_zero_vars++;
284  }
285 
286  SCIPdebugMessage("start with ID %u, %d non zeros\n", leaveids[current_id], nnon_zero_vars);
287 
288  covered_ids[ncovered] = current_id;
289  ncovered++;
290 
291  while( nnon_zero_vars >= comprdata->mincomvars )
292  {
293  /* find the next id which is not covered */
294  while( covered[next_id % nleaveids] && (next_id % nleaveids) != current_id )
295  {
296  /* go to the next node if the intersection is empty */
297  if( (signature0[current_id] | signature0[next_id % nleaveids]) != signature0[current_id]
298  || (signature1[current_id] | signature1[next_id % nleaveids]) != signature1[current_id])
299  {
300  next_id++;
301  }
302  else
303  break;
304  }
305 
306  if( (next_id % nleaveids) == current_id )
307  break;
308 
309  next_id %= nleaveids;
310 
311  if( covered[next_id] )
312  goto EMPTY;
313 
314  ncommon_vars = 0;
315 
316  /* @todo : ensure that the number of common variables is at least mincomvars */
317 
318  /* calculate the intersection */
319  for( v = 0; v < nvars[next_id]; v++ )
320  {
321  if( common_vars[SCIPvarGetProbindex(vars[next_id][v])] == (vals[next_id][v] == 0 ? 1 : 2) )
322  {
323  idx_common_vars[ncommon_vars] = SCIPvarGetProbindex(vars[next_id][v]);
324  ncommon_vars++;
325  }
326  }
327 
328  if( ncommon_vars < comprdata->mincomvars )
329  goto EMPTY;
330 
331  /* clear all non-zero entries which are not part of the intersection */
332  for( v = 0; v < nnon_zero_vars; )
333  {
334  int v2;
335  for( v2 = 0; v2 < ncommon_vars; v2++ )
336  {
337  if( idx_non_zero[v] == idx_common_vars[v2] )
338  break;
339  }
340 
341  /* the variable is not part of the intersection */
342  if( v2 == ncommon_vars )
343  {
344  common_vars[idx_non_zero[v]] = 0;
345 
346  /* replace the idx with the last */
347  idx_non_zero[v] = idx_non_zero[nnon_zero_vars-1];
348  nnon_zero_vars--;
349  }
350  else
351  v++;
352  }
353 
354  /* mark the node as covered */
355  if( nnon_zero_vars > 0 )
356  {
357  covered[next_id] = TRUE;
358  nnemptyinters++;
359 
360  SCIPdebugMessage("-> found intersection with ID %u, %d non zeros\n", leaveids[next_id], nnon_zero_vars);
361 
362  covered_ids[ncovered] = next_id;
363  ncovered++;
364  }
365 
366  EMPTY:
367  next_id++;
368 
369  if( next_id % nleaveids == (current_id-1) % nleaveids )
370  break;
371  }
372 
373  if( nnemptyinters > 0 )
374  {
375  /* increase the number of representatives */
376  if( nreps == 0 )
377  nreps += 2;
378  else
379  nreps++;
380 
381  SCIP_CALL( SCIPallocBufferArray(scip, &repvars[nreps-2], nnon_zero_vars) ); /*lint !e866*/
382  SCIP_CALL( SCIPallocBufferArray(scip, &repvals[nreps-2], nnon_zero_vars) ); /*lint !e866*/
383  nrepvars[nreps-2] = nnon_zero_vars;
384 
385  /* set the common variables and bounds (use non-zero idx)*/
386  for( k = 0; k < nnon_zero_vars; k++ )
387  {
388  repvars[nreps-2][k] = SCIPfindVar(scip, varnames[idx_non_zero[k]]);
389  repvals[nreps-2][k] = common_vars[idx_non_zero[k]] - 1;
390  assert(repvals[nreps-2][k] == 0 || repvals[nreps-2][k] == 1);
391  }
392  }
393  else
394  {
395  SCIPdebugMessage("-> did not found a intersection larger than %d\n", comprdata->mincomvars);
396  covered[current_id] = FALSE;
397  }
398 
399  /* calculate the loss of information */
400  for( v = 0; v < ncovered; v++ )
401  {
402  loi += nvars[covered_ids[v]] - nnon_zero_vars;
403  }
404 
405  SCIPdebugMessage("-> current representation is of size %d with loi = %.1f\n", nreps, loi);
406 
407  current_id = (current_id + 1) % nleaveids;
408 
409  /* free memory */
410  SCIPfreeMemoryArray(scip, &common_vars);
411  SCIPfreeBufferArray(scip, &idx_common_vars);
412  SCIPfreeBufferArray(scip, &idx_non_zero);
413 
414  SCIPfreeBufferArray(scip, &covered_ids);
415  }
416 
417  TERMINATE:
418 
419  /* add the number of variables of uncovered nodes to the loss of information */
420  for( k = 0; k < nleaveids; k++ )
421  {
422  if( !covered[k] )
423  loi += nvars[k];
424  }
425 
426  SCIPdebugMessage("-> final representation is of size %d with loi = %.1f\n", nreps, loi);
427 
428  /* We found a better representation, i.e., with less loss of information.
429  * 1. reset the previous represenation
430  * 2. check if we need to reallocate the memory
431  * 3. set the new representation
432  */
433  if( SCIPisFeasLT(scip, loi, comprdata->loi) )
434  {
435  /* reset the current representation */
436  SCIP_CALL( SCIPresetRepresentation(scip, comprdata->representatives, comprdata->nrepresentatives) );
437 
438  /* ensure that enough memory is allocated */
439  if( comprdata->representativessize < nreps )
440  {
441  /* free the representatoin */
442  SCIP_CALL( SCIPfreeRepresentation(scip, comprdata->representatives, comprdata->nrepresentatives) );
443 
444  /* reallocate memory */
445  SCIP_CALL( SCIPreallocMemoryArray(scip, &comprdata->representatives, nreps) );
446  comprdata->representativessize = nreps;
447 
448  /* initialize the representation */
449  SCIP_CALL( SCIPinitRepresentation(scip, comprdata->representatives, comprdata->representativessize) );
450  }
451 
452  /* set the new representation
453  *
454  * copy the new representation. we skip the last representative because it is implicitly given by the union of
455  * the logic-or constraints of all previous representatives.
456  */
457  comprdata->loi = loi;
458  comprdata->nrepresentatives = nreps;
459 
460  for( k = 0; k < nreps-1; k++ )
461  {
462  int v;
463 
464  for( v = 0; v < nrepvars[k]; v++ )
465  {
466  SCIP_CALL( SCIPaddReoptnodeBndchg(scip, comprdata->representatives[k], repvars[k][v],
467  repvals[k][v], repvals[k][v] == 0 ? SCIP_BOUNDTYPE_UPPER : SCIP_BOUNDTYPE_LOWER) );
468  }
469  }
470 
471  *result = SCIP_SUCCESS;
472  }
473 
474  /* free representatives storage */
475  for( k = 0; k <= nreps-2; k++ )
476  {
477  SCIPfreeBufferArray(scip, &repvals[k]);
478  SCIPfreeBufferArray(scip, &repvars[k]);
479  }
480 
481  SCIPfreeBufferArray(scip, &nrepvars);
482  SCIPfreeBufferArray(scip, &repvals);
483  SCIPfreeBufferArray(scip, &repvars);
484 
485  /* free covered array */
486  SCIPfreeBufferArray(scip, &covered);
487  }
488 
489  /* check if we have found a representation and construct the missing constraints */
490  if( comprdata->nrepresentatives > 0 )
491  {
492  SCIPdebugMessage("best representation found has %d leaf nodes and loi = %g\n", comprdata->nrepresentatives, comprdata->loi);
493 
494  /* iterate over all representatives */
495  for( k = 0; k < comprdata->nrepresentatives-1; k++ )
496  {
497  int r;
498 
499  /* add a constraint (corresponding to the branching path of k) to all representatives
500  * in the subtree induced by the sibling of k */
501  for( r = k+1; r < comprdata->nrepresentatives; r++ )
502  {
503  SCIP_VAR** pathvars;
504  SCIP_Real* pathvals;
505  SCIP_BOUNDTYPE* pathboundtypes;
506  int pathvarssize;
507  int npathvars;
508  int npathafterdualvars;
509 
510  pathvarssize = SCIPreoptnodeGetNVars(comprdata->representatives[k]);
511 
512  /* allocate buffer */
513  SCIP_CALL( SCIPallocBufferArray(scip, &pathvars, pathvarssize) );
514  SCIP_CALL( SCIPallocBufferArray(scip, &pathvals, pathvarssize) );
515  SCIP_CALL( SCIPallocBufferArray(scip, &pathboundtypes, pathvarssize) );
516 
517  /* get the stored path */
518  SCIPgetReoptnodePath(scip, comprdata->representatives[k], pathvars, pathvals, pathboundtypes, pathvarssize,
519  &npathvars, &npathafterdualvars);
520 
521  SCIP_CALL( SCIPaddReoptnodeCons(scip, comprdata->representatives[r], pathvars, pathvals, npathvars,
523 
524  /* free buffer */
525  SCIPfreeBufferArray(scip, &pathboundtypes);
526  SCIPfreeBufferArray(scip, &pathvals);
527  SCIPfreeBufferArray(scip, &pathvars);
528  }
529  }
530  }
531 
532  /* free memory */
533  for( k = nleaveids-1; k >= 0; k-- )
534  {
535  SCIPfreeBufferArray(scip, &bounds[k]);
536  SCIPfreeBufferArray(scip, &vals[k]);
537  SCIPfreeBufferArray(scip, &vars[k]);
538  }
539 
540  SCIPfreeBufferArray(scip, &signature1);
541  SCIPfreeBufferArray(scip, &signature0);
542 
543  SCIPfreeBufferArray(scip, &varnames);
544  SCIPfreeBufferArray(scip, &nvars);
545  SCIPfreeBufferArray(scip, &bounds);
546  SCIPfreeBufferArray(scip, &vals);
547  SCIPfreeBufferArray(scip, &vars);
548 
549  SCIPfreeBlockMemoryArray(scip, &leaveids, nleaveids);
550 
551  return SCIP_OKAY;
552 }
553 
554 /** apply the found representation to the reopttree. */
555 static
557  SCIP* scip, /**< SCIP data structure */
558  SCIP_COMPR* compr, /**< compression method */
559  SCIP_COMPRDATA* comprdata, /**< compression data */
560  SCIP_RESULT* result /**< result pointer */
561  )
562 {
563  SCIP_Bool success;
564  int r;
565 
566  assert(scip != NULL);
567  assert(compr != NULL);
568  assert(comprdata != NULL);
569 
570  *result = SCIP_DIDNOTRUN;
571 
572  if( comprdata->nrepresentatives == 0 )
573  return SCIP_OKAY;
574 
575  /* set references to the root node */
576  for(r = 0; r < comprdata->nrepresentatives; r++)
577  SCIPreoptnodeSetParentID(comprdata->representatives[r], 0);
578 
579  success = FALSE;
580  SCIP_CALL( SCIPsetReoptCompression(scip, comprdata->representatives, comprdata->nrepresentatives, &success) );
581 
582  SCIP_CALL( SCIPfreeRepresentation(scip, comprdata->representatives, comprdata->representativessize) );
583 
584  if( success )
585  *result = SCIP_SUCCESS;
586 
587  return SCIP_OKAY;
588 }
589 
590 /*
591  * Callback methods of tree compression
592  */
593 
594 /** destructor of tree compression to free user data (called when SCIP is exiting) */
595 static
596 SCIP_DECL_COMPRFREE(comprFreeLargestrepr)
597 {
598  SCIP_COMPRDATA* comprdata;
599 
600  assert(scip != NULL);
601  assert(compr != NULL);
602 
603  comprdata = SCIPcomprGetData(compr);
604  assert(comprdata != NULL);
605 
606  SCIPfreeMemory(scip, &comprdata);
607  SCIPcomprSetData(compr, NULL);
608 
609  return SCIP_OKAY;
610 }
611 
612 /** deinitialization method of tree compression (called before transformed problem is freed) */
613 static
614 SCIP_DECL_COMPREXIT(comprExitLargestrepr)
615 {
616  SCIP_COMPRDATA* comprdata;
617 
618  assert(scip != NULL);
619  assert(compr != NULL);
620 
621  comprdata = SCIPcomprGetData(compr);
622  assert(comprdata != NULL);
623 
624  if( comprdata->initialized )
625  {
626  if( comprdata->representativessize > 0 )
627  {
628  SCIPfreeMemoryArray(scip, &comprdata->representatives);
629  }
630 
631  comprdata->representatives = NULL;
632  comprdata->representativessize = 0;
633  comprdata->nrepresentatives = 0;
634  comprdata->initialized = FALSE;
635  }
636 
637  return SCIP_OKAY;
638 }
639 
640 /** execution method of tree compression */
641 static
642 SCIP_DECL_COMPREXEC(comprExecLargestrepr)
643 {
644  SCIP_COMPRDATA* comprdata;
645 
646  comprdata = SCIPcomprGetData(compr);
647  assert(comprdata != NULL);
648 
649  if( !comprdata->initialized )
650  {
651  SCIPdebugMessage(">> initializing <%s>\n", COMPR_NAME);
652 
653  comprdata->representativessize = DEFAUL_MEM_REPR;
654  comprdata->nrepresentatives = 0;
655  comprdata->rate = 0.0;
656  comprdata->loi = SCIPinfinity(scip);
657  comprdata->nnodes = 0;
658  SCIP_CALL( SCIPallocClearMemoryArray(scip, &comprdata->representatives, comprdata->representativessize) );
659 
660  /* initialize the representation */
661  SCIP_CALL( SCIPinitRepresentation(scip, comprdata->representatives, comprdata->representativessize) );
662 
663  comprdata->initialized = TRUE;
664  }
665 
666  *result = SCIP_DIDNOTRUN;
667 
668  /* try to find a representation */
669  SCIP_CALL( constructCompression(scip, compr, comprdata, result) );
670 
671  assert(*result == SCIP_DIDNOTRUN || *result == SCIP_DIDNOTFIND || *result == SCIP_SUCCESS);
672 
673  /* apply the representation, if some was found */
674  if( *result == SCIP_SUCCESS )
675  {
676  SCIP_CALL( applyCompression(scip, compr, comprdata, result) );
677  assert(*result == SCIP_DIDNOTRUN || *result == SCIP_SUCCESS);
678 
679  SCIPdebugMessage("->%s apply compression.\n", *result == SCIP_DIDNOTRUN ? " did not" : "");
680  }
681 
682  return SCIP_OKAY;
683 }
684 
685 /*
686  * tree compression specific interface methods
687  */
688 
689 /** creates the largestrepr tree compression and includes it in SCIP */
691  SCIP* scip /**< SCIP data structure */
692  )
693 {
694  SCIP_COMPRDATA* comprdata;
695  SCIP_COMPR* compr;
696 
697  /* create largestrepr tree compression data */
698  SCIP_CALL( SCIPallocMemory(scip, &comprdata) );
699  assert(comprdata != NULL);
700  comprdata->initialized = FALSE;
701 
702  /* include tree compression */
704  comprExecLargestrepr, comprdata) );
705 
706  assert(compr != NULL);
707 
708  /* set non fundamental callbacks via setter functions */
709  SCIP_CALL( SCIPsetComprExit(scip, compr, comprExitLargestrepr) );
710  SCIP_CALL( SCIPsetComprFree(scip, compr, comprFreeLargestrepr) );
711 
712  /* add largestrepr tree compression parameters */
713  SCIP_CALL( SCIPaddIntParam(scip, "compression/"COMPR_NAME"/iterations", "number of runs in the constrained part.", &comprdata->niters, FALSE, 5, 1, INT_MAX, NULL, NULL) );
714  SCIP_CALL( SCIPaddIntParam(scip, "compression/"COMPR_NAME"/mincommonvars", "minimal number of common variables.", &comprdata->mincomvars, FALSE, 3, 1, INT_MAX, NULL, NULL) );
715 
716  return SCIP_OKAY;
717 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:51
int SCIPcomprGetMinNodes(SCIP_COMPR *compr)
Definition: compr.c:453
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16341
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip.h:20402
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41528
SCIP_REOPTNODE * SCIPgetReoptnode(SCIP *scip, unsigned int id)
Definition: scip.c:15127
#define NULL
Definition: lpi_spx.cpp:130
static void calcSignature(SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Longint *signature0, SCIP_Longint *signature1)
#define DEFAUL_MEM_REPR
void SCIPgetReoptnodePath(SCIP *scip, SCIP_REOPTNODE *reoptnode, SCIP_VAR **vars, SCIP_Real *vals, SCIP_BOUNDTYPE *boundtypes, int mem, int *nvars, int *nafterdualvars)
Definition: scip.c:15228
SCIP_COMPRDATA * SCIPcomprGetData(SCIP_COMPR *compr)
Definition: compr.c:306
#define FALSE
Definition: def.h:53
int SCIPgetNBinVars(SCIP *scip)
Definition: scip.c:10780
#define TRUE
Definition: def.h:52
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
void SCIPcomprSetData(SCIP_COMPR *compr, SCIP_COMPRDATA *comprdata)
Definition: compr.c:316
SCIP_RETCODE SCIPsetReoptCompression(SCIP *scip, SCIP_REOPTNODE **representation, int nrepresentatives, SCIP_Bool *success)
Definition: scip.c:15177
#define COMPR_DESC
#define COMPR_NAME
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip.h:20385
public methods for reoptimization
#define SCIPdebugMessage
Definition: pub_message.h:77
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:20414
SCIP_RETCODE SCIPaddReoptnodeBndchg(SCIP *scip, SCIP_REOPTNODE *reoptnode, SCIP_VAR *var, SCIP_Real val, SCIP_BOUNDTYPE boundtype)
Definition: scip.c:15149
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip.c:3542
int SCIPgetNReoptLeaves(SCIP *scip, SCIP_NODE *node)
Definition: scip.c:15114
int SCIPgetNOrigVars(SCIP *scip)
Definition: scip.c:11175
SCIP_RETCODE SCIPsetComprFree(SCIP *scip, SCIP_COMPR *compr, SCIP_DECL_COMPRFREE((*comprfree)))
Definition: scip.c:7516
SCIP_RETCODE SCIPresetRepresentation(SCIP *scip, SCIP_REOPTNODE **representatives, int nrepresentatives)
Definition: scip.c:15287
#define SCIPallocMemory(scip, ptr)
Definition: scip.h:20355
static SCIP_RETCODE applyCompression(SCIP *scip, SCIP_COMPR *compr, SCIP_COMPRDATA *comprdata, SCIP_RESULT *result)
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:20426
void SCIPreoptnodeSetParentID(SCIP_REOPTNODE *reoptnode, unsigned int parentid)
Definition: reopt.c:4817
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41515
#define COMPR_MINNNODES
SCIP_Real SCIPinfinity(SCIP *scip)
Definition: scip.c:41245
#define SCIP_CALL(x)
Definition: def.h:263
SCIP_RETCODE SCIPinitRepresentation(SCIP *scip, SCIP_REOPTNODE **representatives, int nrepresentatives)
Definition: scip.c:15257
struct SCIP_ComprData SCIP_COMPRDATA
Definition: type_compr.h:40
#define COMPR_PRIORITY
int SCIPreoptnodeGetNVars(SCIP_REOPTNODE *reoptnode)
Definition: reopt.c:4683
#define SCIP_Bool
Definition: def.h:50
SCIP_RETCODE SCIPincludeComprLargestrepr(SCIP *scip)
SCIP_RETCODE SCIPsetComprExit(SCIP *scip, SCIP_COMPR *compr, SCIP_DECL_COMPREXIT((*comprexit)))
Definition: scip.c:7548
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip.c:801
#define MAX(x, y)
Definition: tclique_def.h:75
#define SCIPfreeMemoryArray(scip, ptr)
Definition: scip.h:20373
#define SCIPreallocMemoryArray(scip, ptr, newnum)
Definition: scip.h:20363
static SCIP_DECL_COMPRFREE(comprFreeLargestrepr)
#define SCIPallocClearMemoryArray(scip, ptr, num)
Definition: scip.h:20359
#define SCIPfreeMemory(scip, ptr)
Definition: scip.h:20371
SCIP_RETCODE SCIPaddReoptnodeCons(SCIP *scip, SCIP_REOPTNODE *reoptnode, SCIP_VAR **vars, SCIP_Real *vals, int nvars, REOPT_CONSTYPE constype)
Definition: scip.c:15205
internal methods for tree compressions
SCIP_RETCODE SCIPincludeComprBasic(SCIP *scip, SCIP_COMPR **compr, const char *name, const char *desc, int priority, int minnnodes, SCIP_DECL_COMPREXEC((*comprexec)), SCIP_COMPRDATA *comprdata)
Definition: scip.c:7462
static SCIP_DECL_COMPREXEC(comprExecLargestrepr)
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:16648
SCIP_RETCODE SCIPfreeRepresentation(SCIP *scip, SCIP_REOPTNODE **representatives, int nrepresentatives)
Definition: scip.c:15316
#define SCIP_Real
Definition: def.h:124
SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
Definition: scip.c:11429
largestrepr tree compression
#define SCIP_Longint
Definition: def.h:109
static SCIP_DECL_COMPREXIT(comprExitLargestrepr)
static SCIP_RETCODE constructCompression(SCIP *scip, SCIP_COMPR *compr, SCIP_COMPRDATA *comprdata, SCIP_RESULT *result)
SCIP_RETCODE SCIPgetReoptLeaveIDs(SCIP *scip, SCIP_NODE *node, unsigned int *ids, int idssize, int *nids)
Definition: scip.c:15074