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