Scippy

GCG

Branch-and-Price & Column Generation for Everyone

pricingprob.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 pricingprob.c
29  * @brief methods for working with pricing problems
30  * @author Christian Puchert
31  *
32  * Various methods to work with pricing problems
33  *
34  */
35 
36 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
37 
38 #include "pricingprob.h"
39 #include "pub_pricingprob.h"
40 
41 #include "gcg.h"
42 #include "pricestore_gcg.h"
43 #include "pub_colpool.h"
44 #include "pub_gcgcol.h"
45 #include "pub_pricingjob.h"
46 
47 #include "scip/scip.h"
48 
49 
50 /** create a pricing problem */
51 SCIP_RETCODE GCGpricingprobCreate(
52  SCIP* scip, /**< SCIP data structure (master problem) */
53  GCG_PRICINGPROB** pricingprob, /**< pricing problem to be created */
54  SCIP* pricingscip, /**< SCIP data structure of the corresponding pricing problem */
55  int probnr, /**< index of the corresponding pricing problem */
56  int nroundscol /**< number of previous pricing rounds for which the number of improving columns should be counted */
57 )
58 {
59  SCIP_CALL( SCIPallocBlockMemory(scip, pricingprob) );
60 
61  (*pricingprob)->pricingscip = pricingscip;
62  (*pricingprob)->probnr = probnr;
63  (*pricingprob)->branchconss = NULL;
64  (*pricingprob)->branchduals = NULL;
65  (*pricingprob)->nbranchconss = 0;
66  (*pricingprob)->branchconsssize = 0;
67  (*pricingprob)->branchconsidx = 0;
68  (*pricingprob)->consisadded = TRUE;
69  (*pricingprob)->status = GCG_PRICINGSTATUS_UNKNOWN;
70  (*pricingprob)->lowerbound = -SCIPinfinity(scip);
71  (*pricingprob)->nimpcols = 0;
72  (*pricingprob)->nsolves = 0;
73  (*pricingprob)->maxcolsround = SCIPcalcMemGrowSize(scip, nroundscol);
74 
75  SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &(*pricingprob)->ncolsround, (*pricingprob)->maxcolsround) );
76 
77 
78  return SCIP_OKAY;
79 }
80 
81 /** free a pricing problem */
83  SCIP* scip, /**< SCIP data structure (master problem) */
84  GCG_PRICINGPROB** pricingprob /**< pricing problem to be freed */
85 )
86 {
87  SCIPfreeBlockMemoryArrayNull(scip, &(*pricingprob)->branchduals, (*pricingprob)->branchconsssize);
88  SCIPfreeBlockMemoryArrayNull(scip, &(*pricingprob)->branchconss, (*pricingprob)->branchconsssize);
89  SCIPfreeBlockMemoryArray(scip, &(*pricingprob)->ncolsround, (*pricingprob)->maxcolsround);
90  SCIPfreeBlockMemory(scip, pricingprob);
91  *pricingprob = NULL;
92 }
93 
94 /** initialize pricing problem at the beginning of the pricing round */
96  GCG_PRICINGPROB* pricingprob /**< pricing problem structure */
97  )
98 {
99  assert(pricingprob->nimpcols == 0);
100 
101  pricingprob->nbranchconss = 0;
102  pricingprob->branchconsidx = 0;
103  pricingprob->consisadded = TRUE;
104 }
105 
106 /** uninitialize pricing problem at the beginning of the pricing round */
108  GCG_PRICINGPROB* pricingprob, /**< pricing problem structure */
109  int nroundscol /**< number of previous pricing rounds for which the number of improving columns should be counted */
110  )
111 {
112  int i;
113 
114  for( i = nroundscol-1; i > 0; --i )
115  pricingprob->ncolsround[i] = pricingprob->ncolsround[i-1];
116  pricingprob->ncolsround[0] = pricingprob->nimpcols;
117 
118  pricingprob->nimpcols = 0;
119 }
120 
121 /** add generic branching data (constraint and dual value) to the current pricing problem */
123  SCIP* scip, /**< SCIP data structure (master problem) */
124  GCG_PRICINGPROB* pricingprob, /**< pricing problem structure */
125  SCIP_CONS* branchcons, /**< generic branching constraint */
126  SCIP_Real branchdual /**< corresponding dual solution value */
127  )
128 {
129  /* allocate memory, if necessary */
130  if( pricingprob->branchconsssize == pricingprob->nbranchconss )
131  {
132  int newsize = SCIPcalcMemGrowSize(scip, pricingprob->branchconsssize+1);
133 
134  assert((pricingprob->branchconsssize == 0) == (pricingprob->branchconss == NULL));
135  assert((pricingprob->branchconsssize == 0) == (pricingprob->branchduals == NULL));
136 
137  if( pricingprob->branchconss == NULL )
138  {
139  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &pricingprob->branchconss, newsize) );
140  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &pricingprob->branchduals, newsize) );
141  }
142  else
143  {
144  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &pricingprob->branchconss, pricingprob->branchconsssize, newsize) );
145  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &pricingprob->branchduals, pricingprob->branchconsssize, newsize) );
146  }
147  pricingprob->branchconsssize = newsize;
148  }
149 
150  /* add constraint and dual solution value */
151  pricingprob->branchconss[pricingprob->nbranchconss] = branchcons;
152  pricingprob->branchduals[pricingprob->nbranchconss] = branchdual;
153  ++pricingprob->nbranchconss;
154  ++pricingprob->branchconsidx;
155 
156  return SCIP_OKAY;
157 }
158 
159 /** reset the pricing problem statistics for the current pricing round */
161  SCIP* scip, /**< SCIP data structure (master problem) */
162  GCG_PRICINGPROB* pricingprob /**< pricing problem structure */
163  )
164 {
165  assert(pricingprob->nimpcols == 0);
166 
167  pricingprob->branchconsidx = pricingprob->nbranchconss;
168  pricingprob->status = GCG_PRICINGSTATUS_UNKNOWN;
169  pricingprob->lowerbound = -SCIPinfinity(scip);
170  pricingprob->nsolves = 0;
171 }
172 
173 /** update solution information of a pricing problem */
175  SCIP* scip, /**< SCIP data structure (master problem) */
176  GCG_PRICINGPROB* pricingprob, /**< pricing problem structure */
177  GCG_PRICINGSTATUS status, /**< status of last pricing job */
178  SCIP_Real lowerbound, /**< new lower bound */
179  int nimpcols /**< number of new improving columns */
180  )
181 {
182  /* if the solver was not applicable to the problem, there is nothing to be done */
183  if( status == GCG_PRICINGSTATUS_NOTAPPLICABLE )
184  return;
185 
186  /* update status, lower bound and number of improving columns */
187  pricingprob->status = status;
188  if( SCIPisDualfeasGT(scip, lowerbound, pricingprob->lowerbound) )
189  pricingprob->lowerbound = lowerbound;
190  pricingprob->nimpcols += nimpcols;
191 
192  ++pricingprob->nsolves;
193 }
194 
195 /** get the SCIP instance corresponding to the pricing problem */
197  GCG_PRICINGPROB* pricingprob /**< pricing problem structure */
198  )
199 {
200  return pricingprob->pricingscip;
201 }
202 
203 /** get the index of the corresponding pricing problem */
205  GCG_PRICINGPROB* pricingprob /**< pricing problem structure */
206  )
207 {
208  return pricingprob->probnr;
209 }
210 
211 /** get generic branching data corresponding to the pricing problem */
213  GCG_PRICINGPROB* pricingprob, /**< pricing problem structure */
214  SCIP_CONS*** branchconss, /**< pointer to store branching constraints array, or NULL */
215  SCIP_Real** branchduals, /**< pointer to store array of corresponding dual values, or NULL */
216  int* nbranchconss /**< pointer to store number of generic branching constraints, or NULL */
217  )
218 {
219  if( branchconss != NULL )
220  *branchconss = pricingprob->branchconss;
221  if( branchduals != NULL )
222  *branchduals = pricingprob->branchduals;
223  if( nbranchconss != NULL )
224  *nbranchconss = pricingprob->nbranchconss;
225 }
226 
227 /** get the number of generic branching constraints corresponding to the pricing problem */
229  GCG_PRICINGPROB* pricingprob /**< pricing problem structure */
230  )
231 {
232  return pricingprob->nbranchconss;
233 }
234 
235 /** get index of current generic branching constraint considered the pricing problem */
237  GCG_PRICINGPROB* pricingprob /**< pricing problem structure */
238  )
239 {
240  return pricingprob->branchconsidx;
241 }
242 
243 /** check if the current generic branching constraint has already been added */
245  GCG_PRICINGPROB* pricingprob /**< pricing problem structure */
246  )
247 {
248  return pricingprob->consisadded;
249 }
250 
251 /** mark the current generic branching constraint to be added */
253  GCG_PRICINGPROB* pricingprob /**< pricing problem structure */
254  )
255 {
256  pricingprob->consisadded = TRUE;
257 }
258 
259 /** add the information that the next branching constraint must be added */
261  GCG_PRICINGPROB* pricingprob /**< pricing problem structure */
262  )
263 {
264  assert(pricingprob->branchconsidx >= 1);
265  --pricingprob->branchconsidx;
266  pricingprob->consisadded = FALSE;
267  pricingprob->status = GCG_PRICINGSTATUS_UNKNOWN;
268 }
269 
270 /** get the status of a pricing problem */
272  GCG_PRICINGPROB* pricingprob /**< pricing problem structure */
273  )
274 {
275  return pricingprob->status;
276 }
277 
278 /** get the lower bound of a pricing problem */
280  GCG_PRICINGPROB* pricingprob /**< pricing problem structure */
281  )
282 {
283  return pricingprob->lowerbound;
284 }
285 
286 /** get the number of improving columns found for this pricing problem */
288  GCG_PRICINGPROB* pricingprob /**< pricing problem structure */
289  )
290 {
291  return pricingprob->nimpcols;
292 }
293 
294 /** get the number of times the pricing problem was solved during the loop */
296  GCG_PRICINGPROB* pricingprob /**< pricing problem structure */
297  )
298 {
299  return pricingprob->nsolves;
300 }
301 
302 /** get the total number of improving columns found in the last pricing rounds */
304  GCG_PRICINGPROB* pricingprob, /**< pricing problem structure */
305  int nroundscol /**< number of previous pricing rounds for which the number of improving columns should be counted */
306  )
307 {
308  int ncols;
309  int i;
310 
311  ncols = 0;
312  for( i = 0; i < nroundscol; ++i )
313  ncols += pricingprob->ncolsround[i];
314 
315  return ncols;
316 }
public methods for working with pricing problems
SCIP_RETCODE GCGpricingprobAddGenericBranchData(SCIP *scip, GCG_PRICINGPROB *pricingprob, SCIP_CONS *branchcons, SCIP_Real branchdual)
Definition: pricingprob.c:122
GCG interface methods.
void GCGpricingprobMarkBranchconsAdded(GCG_PRICINGPROB *pricingprob)
Definition: pricingprob.c:252
int GCGpricingprobGetBranchconsIdx(GCG_PRICINGPROB *pricingprob)
Definition: pricingprob.c:236
void GCGpricingprobUpdate(SCIP *scip, GCG_PRICINGPROB *pricingprob, GCG_PRICINGSTATUS status, SCIP_Real lowerbound, int nimpcols)
Definition: pricingprob.c:174
void GCGpricingprobInitPricing(GCG_PRICINGPROB *pricingprob)
Definition: pricingprob.c:95
SCIP_Real GCGpricingprobGetLowerbound(GCG_PRICINGPROB *pricingprob)
Definition: pricingprob.c:279
int GCGpricingprobGetNSolves(GCG_PRICINGPROB *pricingprob)
Definition: pricingprob.c:295
public methods for working with pricing jobs
void GCGpricingprobReset(SCIP *scip, GCG_PRICINGPROB *pricingprob)
Definition: pricingprob.c:160
public methods for working with gcg columns
void GCGpricingprobNextBranchcons(GCG_PRICINGPROB *pricingprob)
Definition: pricingprob.c:260
int GCGpricingprobGetNColsLastRounds(GCG_PRICINGPROB *pricingprob, int nroundscol)
Definition: pricingprob.c:303
void GCGpricingprobFree(SCIP *scip, GCG_PRICINGPROB **pricingprob)
Definition: pricingprob.c:82
enum GCG_PricingStatus GCG_PRICINGSTATUS
@ GCG_PRICINGSTATUS_NOTAPPLICABLE
public methods for storing cols in a col pool
GCG_PRICINGSTATUS status
GCG_PRICINGSTATUS GCGpricingprobGetStatus(GCG_PRICINGPROB *pricingprob)
Definition: pricingprob.c:271
SCIP * GCGpricingprobGetPricingscip(GCG_PRICINGPROB *pricingprob)
Definition: pricingprob.c:196
SCIP_CONS ** branchconss
SCIP_Real * branchduals
int GCGpricingprobGetNGenericBranchconss(GCG_PRICINGPROB *pricingprob)
Definition: pricingprob.c:228
void GCGpricingprobExitPricing(GCG_PRICINGPROB *pricingprob, int nroundscol)
Definition: pricingprob.c:107
private methods for working with pricing problems, to be used by the pricing controller only
void GCGpricingprobGetGenericBranchData(GCG_PRICINGPROB *pricingprob, SCIP_CONS ***branchconss, SCIP_Real **branchduals, int *nbranchconss)
Definition: pricingprob.c:212
@ GCG_PRICINGSTATUS_UNKNOWN
methods for storing priced cols (based on SCIP's separation storage)
int GCGpricingprobGetProbnr(GCG_PRICINGPROB *pricingprob)
Definition: pricingprob.c:204
int GCGpricingprobGetNImpCols(GCG_PRICINGPROB *pricingprob)
Definition: pricingprob.c:287
SCIP_Bool GCGpricingprobBranchconsIsAdded(GCG_PRICINGPROB *pricingprob)
Definition: pricingprob.c:244
SCIP_RETCODE GCGpricingprobCreate(SCIP *scip, GCG_PRICINGPROB **pricingprob, SCIP *pricingscip, int probnr, int nroundscol)
Definition: pricingprob.c:51