Scippy

GCG

Branch-and-Price & Column Generation for Everyone

pricestore_gcg.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program */
4 /* GCG --- Generic Column Generation */
5 /* a Dantzig-Wolfe decomposition based extension */
6 /* of the branch-cut-and-price framework */
7 /* SCIP --- Solving Constraint Integer Programs */
8 /* */
9 /* Copyright (C) 2010-2021 Operations Research, RWTH Aachen University */
10 /* Zuse Institute Berlin (ZIB) */
11 /* */
12 /* This program is free software; you can redistribute it and/or */
13 /* modify it under the terms of the GNU Lesser General Public License */
14 /* as published by the Free Software Foundation; either version 3 */
15 /* of the License, or (at your option) any later version. */
16 /* */
17 /* This program is distributed in the hope that it will be useful, */
18 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
19 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
20 /* GNU Lesser General Public License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with this program; if not, write to the Free Software */
24 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.*/
25 /* */
26 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
27 
28 /**@file pricestore_gcg.c
29  * @brief methods for storing priced cols (based on SCIP's separation storage)
30  * @author Jonas Witt
31  * @author Christian Puchert
32  */
33 
34 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35 #include <assert.h>
36 
37 #include "scip/def.h"
38 #include "scip/set.h"
39 #include "scip/stat.h"
40 #include "scip/clock.h"
41 #include "scip/lp.h"
42 #include "scip/var.h"
43 #include "scip/tree.h"
44 #include "scip/reopt.h"
45 #include "scip/event.h"
46 #include "scip/cons.h"
47 #include "scip/debug.h"
48 
49 #include "gcg.h"
50 #include "pricestore_gcg.h"
51 #include "struct_pricestore_gcg.h"
52 #include "pricer_gcg.h"
53 
54 /*
55  * dynamic memory arrays
56  */
57 
58 /** resizes cols and score arrays to be able to store at least num entries */
59 static
61  GCG_PRICESTORE* pricestore, /**< price storage */
62  int num /**< minimal number of slots in array */
63  )
64 {
65  assert(pricestore != NULL);
66  assert(pricestore->scip != NULL);
67 
68  if( num > pricestore->colssize )
69  {
70  int newsize;
71 
72  newsize = SCIPcalcMemGrowSize(pricestore->scip, num);
73  SCIP_CALL( SCIPreallocBlockMemoryArray(pricestore->scip, &pricestore->cols, pricestore->colssize, newsize) );
74  SCIP_CALL( SCIPreallocBlockMemoryArray(pricestore->scip, &pricestore->objparallelisms, pricestore->colssize, newsize) );
75  SCIP_CALL( SCIPreallocBlockMemoryArray(pricestore->scip, &pricestore->orthogonalities, pricestore->colssize, newsize) );
76  SCIP_CALL( SCIPreallocBlockMemoryArray(pricestore->scip, &pricestore->scores, pricestore->colssize, newsize) );
77  pricestore->colssize = newsize;
78  }
79  assert(num <= pricestore->colssize);
80 
81  return SCIP_OKAY;
82 }
83 
84 /** creates price storage */
85 SCIP_RETCODE GCGpricestoreCreate(
86  SCIP* scip, /**< SCIP data structure */
87  GCG_PRICESTORE** pricestore, /**< pointer to store price storage */
88  SCIP_Real efficiacyfac, /**< factor of -redcost/norm in score function */
89  SCIP_Real objparalfac, /**< factor of objective parallelism in score function */
90  SCIP_Real orthofac, /**< factor of orthogonalities in score function */
91  SCIP_Real mincolorth, /**< minimal orthogonality of columns to add
92  (with respect to columns added in the current round) */
93  GCG_EFFICIACYCHOICE efficiacychoice /**< choice to base efficiacy on */
94  )
95 {
96  assert(pricestore != NULL);
97 
98  SCIP_CALL( SCIPallocBlockMemory(scip, pricestore) );
99 
100  SCIP_CALL( SCIPcreateClock(scip, &(*pricestore)->priceclock) );
101 
102  (*pricestore)->scip = scip;
103  (*pricestore)->cols = NULL;
104  (*pricestore)->objparallelisms = NULL;
105  (*pricestore)->orthogonalities = NULL;
106  (*pricestore)->scores = NULL;
107  (*pricestore)->colssize = 0;
108  (*pricestore)->ncols = 0;
109  (*pricestore)->nforcedcols = 0;
110  (*pricestore)->nefficaciouscols = 0;
111  (*pricestore)->ncolsfound = 0;
112  (*pricestore)->ncolsfoundround = 0;
113  (*pricestore)->ncolsapplied = 0;
114  (*pricestore)->infarkas = FALSE;
115  (*pricestore)->forcecols = FALSE;
116  (*pricestore)->efficiacyfac = efficiacyfac; /* factor of efficiacies in score function */
117  (*pricestore)->objparalfac = objparalfac; /* factor of objective parallelism in score function */
118  (*pricestore)->orthofac = orthofac; /* factor of orthogonalities in score function */
119  (*pricestore)->mincolorth = mincolorth; /* minimal orthogonality of columns to add
120  (with respect to columns added in the current round) */
121  (*pricestore)->efficiacychoice = efficiacychoice;
122 
123  return SCIP_OKAY;
124 }
125 
126 /** frees price storage */
127 SCIP_RETCODE GCGpricestoreFree(
128  SCIP* scip, /**< SCIP data structure */
129  GCG_PRICESTORE** pricestore /**< pointer to store price storage */
130  )
131 {
132  assert(scip == (*pricestore)->scip);
133  assert(pricestore != NULL);
134  assert(*pricestore != NULL);
135  assert((*pricestore)->ncols == 0);
136 
137  SCIPdebugMessage("Pricing time in pricestore = %f sec\n", GCGpricestoreGetTime(*pricestore));
138 
139  /* free clock */
140  SCIP_CALL( SCIPfreeClock(scip, &(*pricestore)->priceclock) );
141 
142  SCIPfreeBlockMemoryArrayNull(scip, &(*pricestore)->cols, (*pricestore)->colssize);
143  SCIPfreeBlockMemoryArrayNull(scip, &(*pricestore)->objparallelisms, (*pricestore)->colssize);
144  SCIPfreeBlockMemoryArrayNull(scip, &(*pricestore)->orthogonalities, (*pricestore)->colssize);
145  SCIPfreeBlockMemoryArrayNull(scip, &(*pricestore)->scores, (*pricestore)->colssize);
146  SCIPfreeBlockMemory(scip, pricestore);
147 
148  return SCIP_OKAY;
149 }
150 
151 /** informs price storage, that Farkas pricing starts now */
153  GCG_PRICESTORE* pricestore /**< price storage */
154  )
155 {
156  assert(pricestore != NULL);
157  assert(pricestore->ncols == 0);
158 
159  pricestore->infarkas = TRUE;
160 }
161 
162 /** informs price storage, that Farkas pricing is now finished */
164  GCG_PRICESTORE* pricestore /**< price storage */
165  )
166 {
167  assert(pricestore != NULL);
168  assert(pricestore->ncols == 0);
169 
170  pricestore->infarkas = FALSE;
171 }
172 
173 /** informs price storage, that the following cols should be used in any case */
175  GCG_PRICESTORE* pricestore /**< price storage */
176  )
177 {
178  assert(pricestore != NULL);
179  assert(!pricestore->forcecols);
180 
181  pricestore->forcecols = TRUE;
182 }
183 
184 /** informs price storage, that the following cols should no longer be used in any case */
186  GCG_PRICESTORE* pricestore /**< price storage */
187  )
188 {
189  assert(pricestore != NULL);
190  assert(pricestore->forcecols);
191 
192  pricestore->forcecols = FALSE;
193 }
194 
195 /** removes a non-forced col from the price storage */
196 static
198  GCG_PRICESTORE* pricestore, /**< price storage */
199  int pos, /**< position of col to delete */
200  SCIP_Bool freecol /**< should col be freed */
201  )
202 {
203  assert(pricestore != NULL);
204  assert(pricestore->cols != NULL);
205  assert(pricestore->nforcedcols <= pos && pos < pricestore->ncols);
206 
207  if( SCIPisDualfeasNegative(pricestore->scip, GCGcolGetRedcost(pricestore->cols[pos])) )
208  pricestore->nefficaciouscols--;
209 
210  /* free the column */
211  if( freecol )
212  GCGfreeGcgCol(&(pricestore->cols[pos]));
213 
214  /* move last col to the empty position */
215  pricestore->cols[pos] = pricestore->cols[pricestore->ncols-1];
216  pricestore->objparallelisms[pos] = pricestore->objparallelisms[pricestore->ncols-1];
217  pricestore->orthogonalities[pos] = pricestore->orthogonalities[pricestore->ncols-1];
218  pricestore->scores[pos] = pricestore->scores[pricestore->ncols-1];
219  pricestore->ncols--;
220 }
221 
222 /** for a given column, check if an identical column already exists in the price storage;
223  * if one exists, return its position, otherwise, return -1
224  */
225 static
227  GCG_PRICESTORE* pricestore, /**< price storage */
228  GCG_COL* col /**< column to be checked */
229  )
230 {
231  int c;
232 
233  for( c = 0; c < pricestore->ncols; ++c )
234  if( GCGcolIsEq(col, pricestore->cols[c]) )
235  return c;
236 
237  return -1;
238 }
239 
240 /** adds col to price storage;
241  * if the col should be forced to enter the LP, an infinite score will be used
242  */
243 SCIP_RETCODE GCGpricestoreAddCol(
244  SCIP* scip, /**< SCIP data structure */
245  GCG_PRICESTORE* pricestore, /**< price storage */
246  GCG_COL* col, /**< priced col */
247  SCIP_Bool forcecol /**< should the col be forced to enter the LP? */
248  )
249 {
250  SCIP_Real colobjparallelism;
251  SCIP_Real colscore;
252 
253  int oldpos;
254  int pos;
255 
256  assert(pricestore != NULL);
257  assert(pricestore->nforcedcols <= pricestore->ncols);
258  assert(col != NULL);
259 
260  /* start timing */
261  SCIP_CALL( SCIPstartClock(pricestore->scip, pricestore->priceclock) );
262 
263  /* a col is forced to enter the LP if
264  * - we construct the initial LP, or
265  * - it has infinite score factor, or
266  * if it is a non-forced col and no cols should be added, abort
267  */
268  forcecol = forcecol || pricestore->forcecols;
269 
270  GCGcolComputeNorm(scip, col);
271 
272  if( forcecol )
273  {
274  colscore = SCIPinfinity(scip);
275  colobjparallelism = 1.0;
276  }
277  else
278  {
279  /* initialize values to invalid (will be initialized during col filtering) */
280  colscore = SCIP_INVALID;
281 
282  if( SCIPisPositive(scip, pricestore->objparalfac) )
283  colobjparallelism = GCGcolComputeDualObjPara(scip, col);
284  else
285  colobjparallelism = 0.0; /* no need to calculate it */
286  }
287 
288  oldpos = pricestoreFindEqualCol(pricestore, col);
289 
290  pos = -1;
291 
292  /* If the column is no duplicate of an existing one, add it */
293  if( oldpos == -1 )
294  {
295  /* get enough memory to store the col */
296  SCIP_CALL( pricestoreEnsureColsMem(pricestore, pricestore->ncols+1) );
297  assert(pricestore->ncols < pricestore->colssize);
298 
299  if( forcecol )
300  {
301  /* make room at the beginning of the array for forced col */
302  pos = pricestore->nforcedcols;
303  pricestore->cols[pricestore->ncols] = pricestore->cols[pos];
304  pricestore->objparallelisms[pricestore->ncols] = pricestore->objparallelisms[pos];
305  pricestore->orthogonalities[pricestore->ncols] = pricestore->orthogonalities[pos];
306  pricestore->scores[pricestore->ncols] = pricestore->scores[pos];
307  pricestore->nforcedcols++;
308  }
309  else
310  pos = pricestore->ncols;
311 
312  pricestore->ncols++;
313  if( SCIPisDualfeasNegative(scip, GCGcolGetRedcost(col)) )
314  pricestore->nefficaciouscols++;
315 
316  /* update statistics of total number of found cols */
317  pricestore->ncolsfound++;
318  pricestore->ncolsfoundround++;
319  }
320  /* Otherwise, if the new column is forced and the duplicate one is not,
321  * remove the duplicate and replace it by the new column
322  */
323  else if( forcecol && oldpos >= pricestore->nforcedcols )
324  {
325  GCGfreeGcgCol(&pricestore->cols[oldpos]);
326  pricestore->cols[oldpos] = pricestore->cols[pricestore->nforcedcols];
327  pricestore->objparallelisms[oldpos] = pricestore->objparallelisms[pricestore->nforcedcols];
328  pricestore->orthogonalities[oldpos] = pricestore->orthogonalities[pricestore->nforcedcols];
329  pricestore->scores[oldpos] = pricestore->scores[pricestore->nforcedcols];
330 
331  pos = pricestore->nforcedcols;
332  pricestore->nforcedcols++;
333  }
334  /* The column already exists and is not forced, free it */
335  else
336  {
337  /* @todo: This is a little dangerous */
338  GCGfreeGcgCol(&col);
339  }
340 
341  if( pos > -1 )
342  {
343  SCIPdebugMessage("adding col %p to price storage of size %d (forcecol=%u)\n",
344  (void*)col, pricestore->ncols, forcecol);
345 
346  /* add col to arrays */
347  pricestore->cols[pos] = col;
348  pricestore->objparallelisms[pos] = colobjparallelism;
349  pricestore->orthogonalities[pos] = 1.0;
350  pricestore->scores[pos] = colscore;
351  }
352 
353  /* stop timing */
354  SCIP_CALL( SCIPstopClock(pricestore->scip, pricestore->priceclock) );
355 
356  return SCIP_OKAY;
357 }
358 
359 /** updates the orthogonalities and scores of the non-forced cols after the given col was added to the LP */
360 static
362  GCG_PRICESTORE* pricestore, /**< price storage */
363  GCG_COL* col, /**< col that was applied */
364  SCIP_Real mincolorthogonality /**< minimal orthogonality of cols to apply to LP */
365  )
366 {
367  int pos;
368 
369  assert(pricestore != NULL);
370 
371  pos = pricestore->nforcedcols;
372  while( pos < pricestore->ncols )
373  {
374  SCIP_Real thisortho;
375 
376  /* update orthogonality */
377  thisortho = GCGcolComputeOrth(pricestore->scip, col, pricestore->cols[pos]);
378 
379  if( thisortho < pricestore->orthogonalities[pos] )
380  {
381  if( thisortho < mincolorthogonality )
382  {
383  /* col is too parallel: delete the col */
384  SCIPdebugMessage(" -> deleting parallel col %p after adding %p (pos=%d, orthogonality=%g, score=%g)\n",
385  (void*) pricestore->cols[pos], (void*) col, pos, thisortho, pricestore->scores[pos]);
386  pricestoreDelCol(pricestore, pos, TRUE);
387  continue;
388  }
389  else
390  {
391  SCIP_Real colefficiacy;
392 
393  /* calculate col's efficacy */
394  switch ( pricestore->efficiacychoice )
395  {
397  colefficiacy = -1.0 * GCGcolGetRedcost(pricestore->cols[pos]);
398  break;
400  colefficiacy = -1.0 * GCGcolGetRedcost(pricestore->cols[pos])/ GCGcolGetNorm(col);
401  break;
403  SCIPerrorMessage("Lambda pricing not yet implemented.\n");
404  return SCIP_INVALIDCALL;
405  default:
406  SCIPerrorMessage("Invalid efficiacy choice.\n");
407  return SCIP_INVALIDCALL;
408  }
409 
410  /* recalculate score */
411  pricestore->orthogonalities[pos] = thisortho;
412  assert( pricestore->objparallelisms[pos] != SCIP_INVALID ); /*lint !e777*/
413  assert( pricestore->scores[pos] != SCIP_INVALID ); /*lint !e777*/
414 
415 
416  pricestore->scores[pos] = pricestore->efficiacyfac * colefficiacy
417  + pricestore->objparalfac * pricestore->objparallelisms[pos]
418  + pricestore->orthofac * thisortho;
419  }
420  }
421  pos++;
422  }
423  return SCIP_OKAY;
424 }
425 
426 /** adds the given col to priced vars and updates the orthogonalities and scores of remaining cols */
427 static
428 SCIP_RETCODE pricestoreApplyCol(
429  GCG_PRICESTORE* pricestore, /**< price storage */
430  GCG_COL* col, /**< col to apply to the LP */
431  SCIP_Bool force, /**< force column */
432  SCIP_Real mincolorthogonality,/**< minimal orthogonality of cols to apply to LP */
433  SCIP_Real score, /**< score of column (or -1.0 if not specified) */
434  SCIP_Bool* added /**< pointer to store whether the column was added */
435  )
436 {
437  assert(pricestore != NULL);
438  assert(added != NULL);
439 
440  SCIP_CALL( GCGcreateNewMasterVarFromGcgCol(pricestore->scip, pricestore->infarkas, col, force, added, NULL, score) );
441  assert(*added);
442 
443  /* update the orthogonalities if needed */
444  if( SCIPisGT(pricestore->scip, mincolorthogonality, SCIPepsilon(pricestore->scip)) || SCIPisPositive(pricestore->scip, pricestore->orthofac))
445  SCIP_CALL( pricestoreUpdateOrthogonalities(pricestore, col, mincolorthogonality) );
446 
447  return SCIP_OKAY;
448 }
449 
450 /** returns the position of the best non-forced col in the cols array */
451 static
453  GCG_PRICESTORE* pricestore /**< price storage */
454  )
455 {
456  SCIP_Real bestscore;
457  int bestpos;
458  int pos;
459 
460  assert(pricestore != NULL);
461 
462  bestscore = SCIP_REAL_MIN;
463  bestpos = -1;
464  for( pos = pricestore->nforcedcols; pos < pricestore->ncols; pos++ )
465  {
466  /* check if col is current best col */
467  assert( pricestore->scores[pos] != SCIP_INVALID ); /*lint !e777*/
468  if( pricestore->scores[pos] > bestscore )
469  {
470  bestscore = pricestore->scores[pos];
471  bestpos = pos;
472  }
473  }
474 
475  return bestpos;
476 }
477 
478 /** computes score for dual solution and initialized orthogonalities */
479 static
480 SCIP_RETCODE computeScore(
481  GCG_PRICESTORE* pricestore, /**< price storage */
482  int pos /**< position of col to handle */
483  )
484 {
485  GCG_COL* col;
486  SCIP_Real colefficiacy;
487  SCIP_Real colscore;
488 
489  col = pricestore->cols[pos];
490 
491  /* calculate cut's efficacy */
492  switch ( pricestore->efficiacychoice )
493  {
495  colefficiacy = -1.0 * GCGcolGetRedcost(pricestore->cols[pos]);
496  break;
498  colefficiacy = -1.0 * GCGcolGetRedcost(pricestore->cols[pos])/ GCGcolGetNorm(col);
499  break;
501  SCIPerrorMessage("Lambda pricing not yet implemented.\n");
502  return SCIP_INVALIDCALL;
503  default:
504  SCIPerrorMessage("Invalid efficiacy choice.\n");
505  return SCIP_INVALIDCALL;
506  }
507 
508  assert( pricestore->objparallelisms[pos] != SCIP_INVALID ); /*lint !e777*/
509  colscore = pricestore->efficiacyfac * colefficiacy
510  + pricestore->objparalfac * pricestore->objparallelisms[pos]
511  + pricestore->orthofac * 1.0;;
512  assert( !SCIPisInfinity(pricestore->scip, colscore) );
513 
514  pricestore->scores[pos] = colscore;
515 
516  /* make sure that the orthogonalities are initialized to 1.0 */
517  pricestore->orthogonalities[pos] = 1.0;
518 
519  return SCIP_OKAY;
520 }
521 
522 /** adds cols to priced vars and clears price storage */
524  GCG_PRICESTORE* pricestore, /**< price storage */
525  GCG_COLPOOL* colpool, /**< GCG column pool */
526  SCIP_Bool usecolpool, /**< use column pool? */
527  int* nfoundvars /**< pointer to store number of variables that were added to the problem */
528  )
529 {
530  SCIP* scip;
531  SCIP_Bool added;
532  int* ncolsappliedprob;
533  SCIP_Real mincolorthogonality;
534  int maxpricecols;
535  int maxpricecolsprob;
536  int ncolsapplied;
537  int pos;
538 
539  assert(pricestore != NULL);
540 
541  scip = pricestore->scip;
542 
543  SCIPdebugMessage("applying %d cols\n", pricestore->ncols);
544 
545  /* start timing */
546  SCIP_CALL( SCIPstartClock(scip, pricestore->priceclock) );
547 
548  /* get maximal number of cols to add to the LP */
549  maxpricecols = GCGpricerGetMaxColsRound(scip);
550  maxpricecolsprob = GCGpricerGetMaxColsProb(scip);
551 
552  ncolsapplied = 0;
553  SCIP_CALL( SCIPallocClearBufferArray(scip, &ncolsappliedprob, GCGgetNPricingprobs(GCGmasterGetOrigprob(scip))) );
554 
555  /* set minimal col orthogonality */
556  mincolorthogonality = pricestore->mincolorth;
557  mincolorthogonality = MAX(mincolorthogonality, SCIPepsilon(scip)); /*lint !e666 */
558 
559  /* Compute scores for all non-forced cols and initialize orthogonalities - make sure all cols are initialized again for the current dual solution */
560  for( pos = pricestore->nforcedcols; pos < pricestore->ncols; pos++ )
561  {
562  SCIP_CALL( computeScore(pricestore, pos) );
563  }
564 
565  /* apply all forced cols */
566  for( pos = 0; pos < pricestore->nforcedcols; pos++ )
567  {
568  GCG_COL* col;
569  int probnr;
570 
571  col = pricestore->cols[pos];
572  assert(SCIPisInfinity(scip, pricestore->scores[pos]));
573 
574  probnr = GCGcolGetProbNr(col);
575 
576  /* add col to the priced vars and update orthogonalities */
577  SCIPdebugMessage(" -> applying forced col %p (probnr = %d)\n", (void*) col, probnr);
578 
579  SCIP_CALL( pricestoreApplyCol(pricestore, col, TRUE, mincolorthogonality, pricestore->scores[pos], &added) );
580 
581  if( added )
582  {
583  ++ncolsapplied;
584  ++ncolsappliedprob[probnr];
585  }
586  }
587 
588  /* apply non-forced cols */
589  while( pricestore->ncols > pricestore->nforcedcols )
590  {
591  GCG_COL* col;
592  int bestpos;
593  SCIP_Real score;
594  SCIP_Bool keep = FALSE;
595  int probnr;
596 
597  /* get best non-forced col */
598  bestpos = pricestoreGetBestCol(pricestore);
599  assert(pricestore->nforcedcols <= bestpos && bestpos < pricestore->ncols);
600  assert(pricestore->scores[bestpos] != SCIP_INVALID ); /*lint !e777*/
601  col = pricestore->cols[bestpos];
602  score = pricestore->scores[bestpos];
603  assert(!SCIPisInfinity(scip, pricestore->scores[bestpos]));
604  probnr = GCGcolGetProbNr(col);
605 
606  /* Do not add (non-forced) non-violated cols.
607  * Note: do not take SCIPsetIsEfficacious(), because constraint handlers often add cols w.r.t. SCIPsetIsFeasPositive().
608  * Note2: if pricerating/feastolfac != -1, constraint handlers may even add cols w.r.t. SCIPsetIsPositive(); those are currently rejected here
609  */
610  if( SCIPisDualfeasNegative(scip, GCGcolGetRedcost(col)) && ncolsapplied < maxpricecols && ncolsappliedprob[probnr] < maxpricecolsprob )
611  {
612  /* add col to the LP and update orthogonalities */
613  SCIP_CALL( pricestoreApplyCol(pricestore, col, FALSE, mincolorthogonality, score, &added) );
614  keep = FALSE;
615  if( added )
616  {
617  SCIPdebugMessage(" -> applying col %p (pos=%d/%d, probnr=%d, efficacy=%g, objparallelism=%g, orthogonality=%g, score=%g)\n",
618  (void*) col, bestpos+1, pricestore->ncols, probnr, GCGcolGetRedcost(pricestore->cols[bestpos]), pricestore->objparallelisms[bestpos],
619  pricestore->orthogonalities[bestpos], pricestore->scores[bestpos]);
620 
621  ++ncolsapplied;
622  ++ncolsappliedprob[probnr];
623  }
624  }
625  else if( usecolpool )
626  {
627  SCIP_CALL( GCGcolpoolAddCol(colpool, col, &keep) );
628  }
629 
630  /* delete column from the pricestore */
631  pricestoreDelCol(pricestore, bestpos, !keep);
632  }
633 
634  *nfoundvars = ncolsapplied;
635 
636  /* clear the price storage and reset statistics for price round */
637  GCGpricestoreClearCols(pricestore);
638 
639  SCIPfreeBufferArray(scip, &ncolsappliedprob);
640 
641  /* stop timing */
642  SCIP_CALL( SCIPstopClock(pricestore->scip, pricestore->priceclock) );
643 
644  return SCIP_OKAY;
645 }
646 
647 /** clears the price storage without adding the cols to the LP */
649  GCG_PRICESTORE* pricestore /**< price storage */
650  )
651 {
652  int c;
653 
654  assert(pricestore != NULL);
655 
656  SCIPdebugMessage("clearing %d cols\n", pricestore->ncols);
657 
658  /* release cols */
659  for( c = 0; c < pricestore->ncols; ++c )
660  {
661  GCGfreeGcgCol(&(pricestore->cols[c]));
662  }
663 
664  /* reset counters */
665  pricestore->ncols = 0;
666  pricestore->nefficaciouscols = 0;
667  pricestore->nforcedcols = 0;
668  pricestore->ncolsfoundround = 0;
669 
670  /* if we have just finished the initial LP construction, free the (potentially large) cols array */
671  if( pricestore->infarkas )
672  {
673  SCIPfreeBlockMemoryArrayNull(pricestore->scip, &pricestore->cols, pricestore->colssize);
674  SCIPfreeBlockMemoryArrayNull(pricestore->scip, &pricestore->objparallelisms, pricestore->colssize);
675  SCIPfreeBlockMemoryArrayNull(pricestore->scip, &pricestore->orthogonalities, pricestore->colssize);
676  SCIPfreeBlockMemoryArrayNull(pricestore->scip, &pricestore->scores, pricestore->colssize);
677 
678  pricestore->colssize = 0;
679  }
680 }
681 
682 /** removes cols that are inefficacious w.r.t. the current dual solution from price storage without adding the cols to the LP */
684  GCG_PRICESTORE* pricestore /**< price storage */
685  )
686 {
687  int cnt;
688  int c;
689 
690  assert( pricestore != NULL );
691 
692  /* check non-forced cols only */
693  cnt = 0;
694  c = pricestore->nforcedcols;
695  while( c < pricestore->ncols )
696  {
697  if( !SCIPisDualfeasNegative(pricestore->scip, GCGcolGetRedcost(pricestore->cols[c])) )
698  {
699  pricestoreDelCol(pricestore, c, TRUE);
700  ++cnt;
701  }
702  else
703  ++c;
704  }
705  SCIPdebugMessage("removed %d non-efficacious cols\n", cnt);
706 }
707 
708 /** get cols in the price storage */
710  GCG_PRICESTORE* pricestore /**< price storage */
711  )
712 {
713  assert(pricestore != NULL);
714 
715  return pricestore->cols;
716 }
717 
718 /** get number of cols in the price storage */
720  GCG_PRICESTORE* pricestore /**< price storage */
721  )
722 {
723  assert(pricestore != NULL);
724 
725  return pricestore->ncols;
726 }
727 
728 /** get number of efficacious cols in the price storage */
730  GCG_PRICESTORE* pricestore /**< price storage */
731  )
732 {
733  assert(pricestore != NULL);
734 
735  return pricestore->nefficaciouscols;
736 }
737 
738 /** get total number of cols found so far */
740  GCG_PRICESTORE* pricestore /**< price storage */
741  )
742 {
743  assert(pricestore != NULL);
744 
745  return pricestore->ncolsfound;
746 }
747 
748 /** get number of cols found so far in current price round */
750  GCG_PRICESTORE* pricestore /**< price storage */
751  )
752 {
753  assert(pricestore != NULL);
754 
755  return pricestore->ncolsfoundround;
756 }
757 
758 /** get total number of cols applied to the LPs */
760  GCG_PRICESTORE* pricestore /**< price storage */
761  )
762 {
763  assert(pricestore != NULL);
764 
765  return pricestore->ncolsapplied;
766 }
767 
768 /** gets time in seconds used for pricing cols from the pricestore */
770  GCG_PRICESTORE* pricestore /**< price storage */
771  )
772 {
773  assert(pricestore != NULL);
774 
775  return SCIPgetClockTime(pricestore->scip, pricestore->priceclock);
776 }
enum GCG_Efficiacychoice GCG_EFFICIACYCHOICE
static void pricestoreDelCol(GCG_PRICESTORE *pricestore, int pos, SCIP_Bool freecol)
SCIP_Real GCGpricestoreGetTime(GCG_PRICESTORE *pricestore)
GCG interface methods.
void GCGpricestoreStartFarkas(GCG_PRICESTORE *pricestore)
void GCGcolComputeNorm(SCIP *scip, GCG_COL *gcgcol)
Definition: gcgcol.c:446
int GCGpricerGetMaxColsProb(SCIP *scip)
int GCGpricestoreGetNCols(GCG_PRICESTORE *pricestore)
static SCIP_RETCODE pricestoreUpdateOrthogonalities(GCG_PRICESTORE *pricestore, GCG_COL *col, SCIP_Real mincolorthogonality)
@ GCG_EFFICIACYCHOICE_STEEPESTEDGE
SCIP_Real GCGcolGetRedcost(GCG_COL *gcgcol)
Definition: gcgcol.c:359
GCG_EFFICIACYCHOICE efficiacychoice
void GCGpricestoreRemoveInefficaciousCols(GCG_PRICESTORE *pricestore)
SCIP_Bool GCGcolIsEq(GCG_COL *gcgcol1, GCG_COL *gcgcol2)
Definition: gcgcol.c:246
datastructures for storing priced cols
static int pricestoreFindEqualCol(GCG_PRICESTORE *pricestore, GCG_COL *col)
SCIP_RETCODE GCGpricestoreFree(SCIP *scip, GCG_PRICESTORE **pricestore)
int GCGgetNPricingprobs(SCIP *scip)
Definition: relax_gcg.c:3979
GCG variable pricer.
SCIP_RETCODE GCGpricestoreApplyCols(GCG_PRICESTORE *pricestore, GCG_COLPOOL *colpool, SCIP_Bool usecolpool, int *nfoundvars)
int GCGpricerGetMaxColsRound(SCIP *scip)
SCIP_Real GCGcolGetNorm(GCG_COL *gcgcol)
Definition: gcgcol.c:576
int GCGpricestoreGetNColsApplied(GCG_PRICESTORE *pricestore)
int GCGpricestoreGetNColsFoundRound(GCG_PRICESTORE *pricestore)
void GCGpricestoreEndForceCols(GCG_PRICESTORE *pricestore)
void GCGpricestoreStartForceCols(GCG_PRICESTORE *pricestore)
SCIP_RETCODE GCGpricestoreAddCol(SCIP *scip, GCG_PRICESTORE *pricestore, GCG_COL *col, SCIP_Bool forcecol)
SCIP * GCGmasterGetOrigprob(SCIP *scip)
void GCGfreeGcgCol(GCG_COL **gcgcol)
Definition: gcgcol.c:135
SCIP_Real * orthogonalities
SCIP_RETCODE GCGpricestoreCreate(SCIP *scip, GCG_PRICESTORE **pricestore, SCIP_Real efficiacyfac, SCIP_Real objparalfac, SCIP_Real orthofac, SCIP_Real mincolorth, GCG_EFFICIACYCHOICE efficiacychoice)
SCIP_Real * objparallelisms
GCG_COL ** GCGpricestoreGetCols(GCG_PRICESTORE *pricestore)
SCIP_RETCODE GCGcolpoolAddCol(GCG_COLPOOL *colpool, GCG_COL *col, SCIP_Bool *success)
Definition: colpool.c:281
static SCIP_RETCODE computeScore(GCG_PRICESTORE *pricestore, int pos)
int GCGcolGetProbNr(GCG_COL *gcgcol)
Definition: gcgcol.c:311
void GCGpricestoreEndFarkas(GCG_PRICESTORE *pricestore)
SCIP_RETCODE GCGcreateNewMasterVarFromGcgCol(SCIP *scip, SCIP_Bool infarkas, GCG_COL *gcgcol, SCIP_Bool force, SCIP_Bool *added, SCIP_VAR **addedvar, SCIP_Real score)
int GCGpricestoreGetNEfficaciousCols(GCG_PRICESTORE *pricestore)
void GCGpricestoreClearCols(GCG_PRICESTORE *pricestore)
@ GCG_EFFICIACYCHOICE_DANTZIG
SCIP_CLOCK * priceclock
methods for storing priced cols (based on SCIP's separation storage)
@ GCG_EFFICIACYCHOICE_LAMBDA
static int pricestoreGetBestCol(GCG_PRICESTORE *pricestore)
SCIP_Real GCGcolComputeDualObjPara(SCIP *scip, GCG_COL *gcgcol)
Definition: gcgcol.c:651
int GCGpricestoreGetNColsFound(GCG_PRICESTORE *pricestore)
static SCIP_RETCODE pricestoreEnsureColsMem(GCG_PRICESTORE *pricestore, int num)
static SCIP_RETCODE pricestoreApplyCol(GCG_PRICESTORE *pricestore, GCG_COL *col, SCIP_Bool force, SCIP_Real mincolorthogonality, SCIP_Real score, SCIP_Bool *added)
SCIP_Real GCGcolComputeOrth(SCIP *scip, GCG_COL *gcgcol1, GCG_COL *gcgcol2)
Definition: gcgcol.c:758