Scippy

GCG

Branch-and-Price & Column Generation for Everyone

misc.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 misc.c
29  * @brief miscellaneous methods
30  * @author Gerald Gamrath
31  * @author Martin Bergner
32  */
33 
34 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35 
36 #include "gcg.h"
37 #include "relax_gcg.h"
38 #include "pricer_gcg.h"
39 #include "benders_gcg.h"
40 #include "pub_gcgvar.h"
41 #include "cons_decomp.h"
42 #include "gcgsort.h"
43 #include "stat.h"
44 #include <string.h>
45 #include <unistd.h>
46 
47 /** computes the generator of mastervar for the entry in origvar
48  * @return entry of the generator corresponding to origvar */
49 static
51  SCIP_VAR* mastervar, /**< current mastervariable */
52  SCIP_VAR* origvar /**< corresponding origvar */
53  )
54 {
55  SCIP_HASHMAP* varmap;
56  SCIP_Real origval;
57 
58  assert(mastervar != NULL);
59  assert(origvar != NULL);
60 
61  varmap = GCGmasterVarGetOrigvalmap(mastervar);
62  origval = SCIPhashmapGetImageReal(varmap, origvar);
63 
64  return origval == SCIP_INVALID ? 0.0 : origval;
65 }
66 
67 /** comparefunction for lexicographical sort */
68 static
69 GCG_DECL_SORTPTRCOMP(mastervarcomp)
70 {
71  SCIP* origprob = (SCIP *) userdata; /* TODO: continue here */
72  SCIP_VAR* mastervar1;
73  SCIP_VAR* mastervar2;
74  SCIP_VAR** origvars;
75  int norigvars;
76  int i;
77 
78  mastervar1 = (SCIP_VAR*) elem1;
79  mastervar2 = (SCIP_VAR*) elem2;
80 
81  assert(mastervar1 != NULL);
82  assert(mastervar2 != NULL);
83 
84  if( GCGvarGetBlock(mastervar1) < 0 )
85  {
86  SCIPdebugMessage("linkingvar or directy transferred var\n");
87  }
88  if( GCGvarGetBlock(mastervar2) < 0 )
89  {
90  SCIPdebugMessage("linkingvar or directy transferred var\n");
91  }
92 
93  /* TODO: get all original variables (need scip...maybe from pricer via function and scip_ */
94  origvars = SCIPgetVars(origprob);
95  norigvars = SCIPgetNVars(origprob);
96 
97  for( i = 0; i < norigvars; ++i )
98  {
99  SCIP_Real entry1;
100  SCIP_Real entry2;
101  if( SCIPvarGetType(origvars[i]) > SCIP_VARTYPE_INTEGER )
102  continue;
103 
104  entry1 = getGeneratorEntry(mastervar1, origvars[i]);
105  entry2 = getGeneratorEntry(mastervar2, origvars[i]);
106 
107  if( SCIPisFeasGT(origprob, entry1, entry2) )
108  return -1;
109  if( SCIPisFeasLT(origprob, entry1, entry2) )
110  return 1;
111  }
112 
113  return 0;
114 }
115 
116 /* transforms given solution of the master problem into solution of the original problem
117  * @todo think about types of epsilons used in this method
118  * @returns SCIP return code
119  */
121  SCIP* scip, /* SCIP data structure */
122  SCIP_SOL* mastersol, /* solution of the master problem, or NULL for current LP solution */
123  SCIP_SOL** origsol /* pointer to store the new created original problem's solution */
124  )
125 {
126  SCIP* masterprob;
127  int npricingprobs;
128  int* blocknrs;
129  SCIP_Real* blockvalue;
130  SCIP_Real increaseval;
131  SCIP_VAR** mastervars;
132  SCIP_VAR** mastervarsall;
133  SCIP_Real* mastervals;
134  int nmastervarsall;
135  int nmastervars;
136  SCIP_VAR** vars;
137  int nvars;
138  SCIP_Real feastol;
139  SCIP_Bool discretization;
140  int i;
141  int j;
142 
143  assert(scip != NULL);
144  assert(origsol != NULL);
145 
146  masterprob = GCGgetMasterprob(scip);
147  npricingprobs = GCGgetNPricingprobs(scip);
148 
149  assert( !SCIPisInfinity(scip, SCIPgetSolOrigObj(masterprob, mastersol)) );
150 
152  {
153  SCIP_SOL* relaxsol;
154 
155  relaxsol = GCGgetBendersRelaxationSol(scip);
156 
157  SCIP_CALL( SCIPcreateSolCopy(scip, origsol, relaxsol) );
158  SCIP_CALL( SCIPunlinkSol(scip, *origsol) );
159 
160  return SCIP_OKAY;
161  }
162 
163  SCIP_CALL( SCIPcreateSol(scip, origsol, GCGrelaxGetProbingheur(scip)) );
164 
165  if( GCGgetDecompositionMode(scip) != DEC_DECMODE_ORIGINAL && !GCGmasterIsSolValid(masterprob, mastersol) )
166  return SCIP_OKAY;
167 
168  SCIP_CALL( SCIPallocBufferArray(scip, &blockvalue, npricingprobs) );
169  SCIP_CALL( SCIPallocBufferArray(scip, &blocknrs, npricingprobs) );
170 
171  SCIP_CALL( SCIPgetBoolParam(scip, "relaxing/gcg/discretization", &discretization) );
172 
173  if( discretization && (SCIPgetNContVars(scip) > 0) )
174  {
175  SCIP_VAR** fixedvars;
176  SCIP_Real* fixedvals;
177  int nfixedvars;
178 
179  /* get variables of the master problem and their solution values */
180  SCIP_CALL( SCIPgetVarsData(masterprob, &mastervarsall, &nmastervarsall, NULL, NULL, NULL, NULL) );
181 
182  /* getting the fixed variables */
183  fixedvars = SCIPgetFixedVars(masterprob);
184  nfixedvars = SCIPgetNFixedVars(masterprob);
185 
186  assert(mastervarsall != NULL);
187  assert(nmastervarsall >= 0);
188 
189  SCIP_CALL( SCIPallocBufferArray(scip, &mastervars, nmastervarsall + nfixedvars) );
190 
191  SCIP_CALL( SCIPallocBufferArray(scip, &mastervals, nmastervarsall + nfixedvars) );
192  SCIP_CALL( SCIPallocBufferArray(scip, &fixedvals, nfixedvars) );
193 
194  SCIP_CALL( SCIPgetSolVals(masterprob, mastersol, nmastervarsall, mastervarsall, mastervals) );
195  SCIP_CALL( SCIPgetSolVals(masterprob, mastersol, nfixedvars, fixedvars, fixedvals) );
196 
197  nmastervars = 0;
198 
199  for( i = 0; i < nmastervarsall; ++i )
200  {
201  SCIP_Real solval;
202 
203  assert( i >= nmastervars );
204  solval = mastervals[i];
205 
206  if( !SCIPisZero(scip, solval) )
207  {
208  mastervars[nmastervars] = mastervarsall[i];
209  mastervals[nmastervars] = solval;
210 
211  ++nmastervars;
212  }
213  }
214 
215  /* adding the fixed variables to the mastervars array */
216  for( i = 0; i < nfixedvars; i++ )
217  {
218  SCIP_Real solval;
219 
220  solval = fixedvals[i];
221 
222  if( !SCIPisZero(scip, solval) )
223  {
224  mastervars[nmastervars] = fixedvars[i];
225  mastervals[nmastervars] = solval;
226 
227  ++nmastervars;
228  }
229  }
230 
231  SCIPfreeBufferArray(scip, &fixedvals);
232 
233  /* sort mastervariables lexicographically */
234  GCGsortPtrPtr((void**)mastervars, (void**) mastervals, mastervarcomp, scip, nmastervars );
235  }
236  else
237  {
238  SCIP_VAR** fixedvars;
239  SCIP_Real* fixedvals;
240  int nfixedvars;
241 
242  /* get variables of the master problem and their solution values */
243  SCIP_CALL( SCIPgetVarsData(masterprob, &mastervarsall, &nmastervarsall, NULL, NULL, NULL, NULL) );
244 
245  /* getting the fixed variables */
246  fixedvars = SCIPgetFixedVars(masterprob);
247  nfixedvars = SCIPgetNFixedVars(masterprob);
248 
249  assert(mastervarsall != NULL);
250  assert(nmastervarsall >= 0);
251 
252  SCIP_CALL( SCIPallocBufferArray(scip, &mastervars, nmastervarsall + nfixedvars) );
253  SCIP_CALL( SCIPallocBufferArray(scip, &mastervals, nmastervarsall + nfixedvars) );
254  SCIP_CALL( SCIPallocBufferArray(scip, &fixedvals, nfixedvars) );
255 
256  SCIP_CALL( SCIPgetSolVals(masterprob, mastersol, nmastervarsall, mastervarsall, mastervals) );
257  SCIP_CALL( SCIPgetSolVals(masterprob, mastersol, nfixedvars, fixedvars, fixedvals) );
258 
259  nmastervars = 0;
260 
261  for( i = 0; i < nmastervarsall; ++i )
262  {
263  SCIP_Real solval;
264 
265  assert( i >= nmastervars );
266  solval = mastervals[i];
267 
268  if( !SCIPisZero(scip, solval) )
269  {
270  mastervars[nmastervars] = mastervarsall[i];
271  mastervals[nmastervars] = solval;
272 
273  ++nmastervars;
274  }
275  }
276 
277  /* adding the fixed variables to the mastervars array */
278  for( i = 0; i < nfixedvars; i++ )
279  {
280  SCIP_Real solval;
281 
282  solval = fixedvals[i];
283 
284  if( !SCIPisZero(scip, solval) )
285  {
286  mastervars[nmastervars] = fixedvars[i];
287  mastervals[nmastervars] = solval;
288 
289  ++nmastervars;
290  }
291  }
292 
293  SCIPfreeBufferArray(scip, &fixedvals);
294  }
295 
296  /* initialize the block values for the pricing problems */
297  for( i = 0; i < npricingprobs; i++ )
298  {
299  blockvalue[i] = 0.0;
300  blocknrs[i] = 0;
301  }
302 
303  /* loop over all given master variables */
304  for( i = 0; i < nmastervars; i++ )
305  {
306  SCIP_VAR** origvars;
307  int norigvars;
308  SCIP_Real* origvals;
309  SCIP_Bool isray;
310  int blocknr;
311 
312  if( SCIPisZero(masterprob, mastervals[i]) )
313  continue;
314 
315  origvars = GCGmasterVarGetOrigvars(mastervars[i]);
316  norigvars = GCGmasterVarGetNOrigvars(mastervars[i]);
317  origvals = GCGmasterVarGetOrigvals(mastervars[i]);
318  blocknr = GCGvarGetBlock(mastervars[i]);
319  isray = GCGmasterVarIsRay(mastervars[i]);
320 
321  assert(GCGvarIsMaster(mastervars[i]));
322 
323  /** @todo handle infinite master solution values */
324  assert(!SCIPisInfinity(scip, mastervals[i]));
325 
326  /* first of all, handle variables representing rays */
327  if( isray )
328  {
329  assert(blocknr >= 0);
330  /* we also want to take into account variables representing rays, that have a small value (between normal and feas eps),
331  * so we do no feas comparison here */
332  if( SCIPisPositive(masterprob, mastervals[i]) )
333  {
334  /* loop over all original variables contained in the current master variable */
335  for( j = 0; j < norigvars; j++ )
336  {
337  if( SCIPisZero(scip, origvals[j]) )
338  continue;
339 
340  assert(!SCIPisZero(scip, origvals[j]));
341 
342  /* the original variable is a linking variable: just transfer the solution value of the direct copy (this is done later) */
343  if( GCGoriginalVarIsLinking(origvars[j]) )
344  continue;
345 
346  SCIPdebugMessage("Increasing value of %s by %f because of %s\n", SCIPvarGetName(origvars[j]), origvals[j] * mastervals[i], SCIPvarGetName(mastervars[i]));
347  /* increase the corresponding value */
348  SCIP_CALL( SCIPincSolVal(scip, *origsol, origvars[j], origvals[j] * mastervals[i]) );
349  }
350  }
351  mastervals[i] = 0.0;
352  continue;
353  }
354 
355  /* variable was directly transferred to the master problem (only in linking conss or linking variable) */
356  /** @todo this may be the wrong place for this case, handle it before the while loop
357  * and remove the similar case in the next while loop */
358  if( blocknr == -1 )
359  {
360  assert(norigvars == 1);
361  assert(origvals[0] == 1.0);
362 
363  /* increase the corresponding value */
364  SCIPdebugMessage("Increasing value of %s by %f because of %s\n", SCIPvarGetName(origvars[0]), origvals[0] * mastervals[i], SCIPvarGetName(mastervars[i]));
365  SCIP_CALL( SCIPincSolVal(scip, *origsol, origvars[0], origvals[0] * mastervals[i]) );
366  mastervals[i] = 0.0;
367  continue;
368  }
369  if( blocknr == -2 )
370  {
371  assert(norigvars == 0);
372 
373  mastervals[i] = 0.0;
374  continue;
375  }
376 
377  /* handle the variables with value >= 1 to get integral values in original solution */
378  while( SCIPisFeasGE(masterprob, mastervals[i], 1.0) )
379  {
380  assert(blocknr >= 0);
381  /* loop over all original variables contained in the current master variable */
382  for( j = 0; j < norigvars; j++ )
383  {
384  SCIP_VAR* pricingvar;
385  int norigpricingvars;
386  SCIP_VAR** origpricingvars;
387  if( SCIPisZero(scip, origvals[j]) )
388  continue;
389  assert(!SCIPisZero(scip, origvals[j]));
390 
391  /* the original variable is a linking variable: just transfer the solution value of the direct copy (this is done above) */
392  if( GCGoriginalVarIsLinking(origvars[j]) )
393  continue;
394 
395  pricingvar = GCGoriginalVarGetPricingVar(origvars[j]);
396  assert(GCGvarIsPricing(pricingvar));
397 
398  norigpricingvars = GCGpricingVarGetNOrigvars(pricingvar);
399  origpricingvars = GCGpricingVarGetOrigvars(pricingvar);
400 
401  /* just in case a variable has a value higher than the number of blocks, it represents */
402  if( norigpricingvars <= blocknrs[blocknr] )
403  {
404  SCIPdebugMessage("Increasing value of %s by %f because of %s\n", SCIPvarGetName(origpricingvars[norigpricingvars-1]), mastervals[i] * origvals[j], SCIPvarGetName(mastervars[i]));
405  /* increase the corresponding value */
406  SCIP_CALL( SCIPincSolVal(scip, *origsol, origpricingvars[norigpricingvars-1], mastervals[i] * origvals[j]) );
407  mastervals[i] = 1.0;
408  }
409  /* this should be default */
410  else
411  {
412  SCIPdebugMessage("Increasing value of %s by %f because of %s\n", SCIPvarGetName(origpricingvars[blocknrs[blocknr]]), origvals[j], SCIPvarGetName(mastervars[i]) );
413  /* increase the corresponding value */
414  SCIP_CALL( SCIPincSolVal(scip, *origsol, origpricingvars[blocknrs[blocknr]], origvals[j]) );
415  }
416  }
417  mastervals[i] = mastervals[i] - 1.0;
418  blocknrs[blocknr]++;
419  }
420  assert(!SCIPisFeasNegative(masterprob, mastervals[i]));
421  }
422 
423  /* TODO: Change order of mastervars */
424 
425  /* loop over all given master variables */
426  for( i = 0; i < nmastervars; i++ )
427  {
428  SCIP_VAR** origvars;
429  int norigvars;
430  SCIP_Real* origvals;
431  int blocknr;
432 
433  origvars = GCGmasterVarGetOrigvars(mastervars[i]);
434  norigvars = GCGmasterVarGetNOrigvars(mastervars[i]);
435  origvals = GCGmasterVarGetOrigvals(mastervars[i]);
436  blocknr = GCGvarGetBlock(mastervars[i]);
437 
438  if( SCIPisFeasZero(masterprob, mastervals[i]) )
439  {
440  continue;
441  }
442  assert(SCIPisFeasGE(masterprob, mastervals[i], 0.0) && SCIPisFeasLT(masterprob, mastervals[i], 1.0));
443 
444  while( SCIPisFeasPositive(masterprob, mastervals[i]) )
445  {
446  assert(blocknr >= 0);
447  assert(GCGvarIsMaster(mastervars[i]));
448  assert(!GCGmasterVarIsRay(mastervars[i]));
449 
450  increaseval = MIN(mastervals[i], 1.0 - blockvalue[blocknr]);
451  /* loop over all original variables contained in the current master variable */
452  for( j = 0; j < norigvars; j++ )
453  {
454  SCIP_VAR* pricingvar;
455  int norigpricingvars;
456  SCIP_VAR** origpricingvars;
457 
458  if( SCIPisZero(scip, origvals[j]) )
459  continue;
460 
461  /* the original variable is a linking variable: just transfer the solution value of the direct copy (this is done above) */
462  if( GCGoriginalVarIsLinking(origvars[j]) )
463  continue;
464 
465  pricingvar = GCGoriginalVarGetPricingVar(origvars[j]);
466  assert(GCGvarIsPricing(pricingvar));
467 
468  norigpricingvars = GCGpricingVarGetNOrigvars(pricingvar);
469  origpricingvars = GCGpricingVarGetOrigvars(pricingvar);
470 
471  if( norigpricingvars <= blocknrs[blocknr] )
472  {
473  increaseval = mastervals[i];
474 
475  SCIPdebugMessage("Increasing value of %s by %f because of %s\n", SCIPvarGetName(origpricingvars[norigpricingvars-1]), origvals[j] * increaseval, SCIPvarGetName(mastervars[i]) );
476  /* increase the corresponding value */
477  SCIP_CALL( SCIPincSolVal(scip, *origsol, origpricingvars[norigpricingvars-1], origvals[j] * increaseval) );
478  }
479  else
480  {
481  /* increase the corresponding value */
482  SCIPdebugMessage("Increasing value of %s by %f because of %s\n", SCIPvarGetName(origpricingvars[blocknrs[blocknr]]), origvals[j] * increaseval, SCIPvarGetName(mastervars[i]) );
483  SCIP_CALL( SCIPincSolVal(scip, *origsol, origpricingvars[blocknrs[blocknr]], origvals[j] * increaseval) );
484  }
485  }
486 
487  mastervals[i] = mastervals[i] - increaseval;
488  if( SCIPisFeasZero(masterprob, mastervals[i]) )
489  {
490  mastervals[i] = 0.0;
491  }
492  blockvalue[blocknr] += increaseval;
493 
494  /* if the value assigned to the block is equal to 1, this block is full and we take the next block */
495  if( SCIPisFeasGE(masterprob, blockvalue[blocknr], 1.0) )
496  {
497  blockvalue[blocknr] = 0.0;
498  blocknrs[blocknr]++;
499  }
500  }
501  }
502 
503  SCIPfreeBufferArray(scip, &mastervals);
504  SCIPfreeBufferArray(scip, &mastervars);
505 
506  SCIPfreeBufferArray(scip, &blocknrs);
507  SCIPfreeBufferArray(scip, &blockvalue);
508 
509  /* if the solution violates one of its bounds by more than feastol
510  * and less than 10*feastol, round it and print a warning
511  */
512  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
513  SCIP_CALL( SCIPgetRealParam(scip, "numerics/feastol", &feastol) );
514 
515  for( i = 0; i < nvars; ++i )
516  {
517  SCIP_Real solval;
518  SCIP_Real lb;
519  SCIP_Real ub;
520 
521  solval = SCIPgetSolVal(scip, *origsol, vars[i]);
522  lb = SCIPvarGetLbLocal(vars[i]);
523  ub = SCIPvarGetUbLocal(vars[i]);
524 
525  if( SCIPisFeasGT(scip, solval, ub) && EPSEQ(solval, ub, 10 * feastol) )
526  {
527  SCIP_CALL( SCIPsetSolVal(scip, *origsol, vars[i], ub) );
528  SCIPwarningMessage(scip, "Variable %s rounded from %g to %g in relaxation solution\n",
529  SCIPvarGetName(vars[i]), solval, ub);
530  }
531  else if( SCIPisFeasLT(scip, solval, lb) && EPSEQ(solval, lb, 10 * feastol) )
532  {
533  SCIP_CALL( SCIPsetSolVal(scip, *origsol, vars[i], lb) );
534  SCIPwarningMessage(scip, "Variable %s rounded from %g to %g in relaxation solution\n",
535  SCIPvarGetName(vars[i]), solval, lb);
536  }
537  }
538 
539  return SCIP_OKAY;
540 }
541 
542 
543 /* transforms given values of the given original variables into values of the given master variables
544  * @returns the sum of the values of the corresponding master variables that are fixed */
546  SCIP* scip, /**< SCIP data structure */
547  SCIP_VAR** origvars, /**< array with (subset of the) original variables */
548  SCIP_Real* origvals, /**< array with values (coefs) for the given original variables */
549  int norigvars, /**< number of given original variables */
550  SCIP_VAR** mastervars, /**< array of (all present) master variables */
551  SCIP_Real* mastervals, /**< array to store the values of the master variables */
552  int nmastervars /**< number of master variables */
553  )
554 {
555  int i;
556  int j;
557  int k;
558  SCIP_Real sum;
559 
560  assert(scip != NULL);
561  assert(origvars != NULL);
562  assert(origvals != NULL);
563  assert(mastervars != NULL);
564  assert(mastervals != NULL);
565  assert(nmastervars >= 0);
566 
567  sum = 0.0;
568 
569  /* set all values to 0 initially */
570  for( i = 0; i < nmastervars; i++ )
571  mastervals[i] = 0.0;
572 
573  /* iterate over all original variables */
574  for( i = 0; i < norigvars; i++ )
575  {
576  SCIP_VAR** varmastervars;
577  SCIP_Real* varmastervals;
578  int blocknr;
579 
580  assert(GCGvarIsOriginal(origvars[i]));
581  varmastervars = GCGoriginalVarGetMastervars(origvars[i]);
582  varmastervals = GCGoriginalVarGetMastervals(origvars[i]);
583  blocknr = GCGvarGetBlock(origvars[i]);
584 
585  /* variable belongs to no block (or is a linking variable), so it was transferred directly to the master problem,
586  * hence, we transfer the value directly to the corresponding master variable
587  */
588  if( blocknr < 0 )
589  {
590  assert(blocknr == -1 || blocknr == -2);
591  assert(SCIPvarIsOriginal(varmastervars[0]));
592  assert(SCIPvarGetTransVar(varmastervars[0]) != NULL);
593 
594  for( k = 0; k < nmastervars; k++ )
595  {
596  if( mastervars[k] == SCIPvarGetTransVar(varmastervars[0]) )
597  {
598  mastervals[k] += (varmastervals[0] * origvals[i]);
599  break;
600  }
601  }
602 
603  if ( k >= nmastervars )
604  {
605  // inactive variable, check whether it is fixed
606  if ( SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(varmastervars[0]), SCIPvarGetUbGlobal(varmastervars[0])) )
607  {
608  // variable is fixed in the master problem
609  sum += (SCIPvarGetLbGlobal(varmastervars[0]) * varmastervals[0] * origvals[i]);
610  }
611  else
612  {
613 #ifdef SCIP_DEBUG
614  SCIP* masterprob = GCGgetMasterprob(scip);
615  SCIP_VAR** vars = SCIPgetVars(masterprob);
616 
617  SCIPdebugMessage("OrigVar %s [%f,%f]\n", SCIPvarGetName(origvars[i]), SCIPvarGetLbGlobal(origvars[i]),
618  SCIPvarGetUbGlobal(origvars[i]));
619  SCIPdebugMessage("MasterVar %s [%f,%f]\n", SCIPvarGetName(varmastervars[0]),
620  SCIPvarGetLbGlobal(varmastervars[0]), SCIPvarGetUbGlobal(varmastervars[0]));
621 #endif
622  assert(FALSE);
623  }
624  }
625  }
626  /* variable belongs to exactly one block, so we have to look at all master variables and increase their values
627  * if they contain the original variable
628  */
629  else
630  {
631  SCIP_VAR* pricingvar;
632  SCIP_VAR* origvar;
633  SCIP_VAR** curmastervars;
634  SCIP_Real* curmastervals;
635  int ncurmastervars;
636 
637  pricingvar = GCGoriginalVarGetPricingVar(origvars[i]);
638  assert(GCGvarIsPricing(pricingvar));
639 
640  origvar = GCGpricingVarGetOriginalVar(pricingvar);
641  assert(GCGvarIsOriginal(origvar));
642  curmastervars = GCGoriginalVarGetMastervars(origvar);
643  curmastervals = GCGoriginalVarGetMastervals(origvar);
644  ncurmastervars = GCGoriginalVarGetNMastervars(origvar);
645 
646  for( j = 0; j < ncurmastervars; j++ )
647  {
648  assert(SCIPvarIsTransformed(curmastervars[j]));
649  for( k = 0; k < nmastervars; k++ )
650  if( mastervars[k] == curmastervars[j] )
651  {
652  mastervals[k] += (curmastervals[j] * origvals[i]);
653  break;
654  }
655  assert(k < nmastervars);
656  }
657  }
658 
659  }
660  return sum;
661 }
662 
663 /* checks whether the scip is the original scip instance
664  * @returns whether the scip is the original scip instance */
665 SCIP_Bool GCGisOriginal(
666  SCIP* scip /* SCIP data structure */
667  )
668 {
669  assert(scip != NULL);
670  return SCIPfindRelax(scip, "gcg") != NULL;
671 }
672 
673 /* checks whether the scip is the master problem scip
674  * @returns whether the scip is the master problem scip */
675 SCIP_Bool GCGisMaster(
676  SCIP* scip /* SCIP data structure */
677  )
678 {
679  assert(scip != NULL);
680  return SCIPfindPricer(scip, "gcg") != NULL;
681 }
682 
683 /* print out GCG statistics
684  * @returns SCIP return code */
685 SCIP_RETCODE GCGprintStatistics(
686  SCIP* scip, /* SCIP data structure */
687  FILE* file /* output file or NULL for standard output */
688 )
689 {
690  assert(scip != NULL);
691 
692  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(GCGgetMasterprob(scip)), file, "\nMaster Program statistics:\n");
693  SCIP_CALL( SCIPprintStatistics(GCGgetMasterprob(scip), file) );
695  && SCIPgetStage(GCGgetMasterprob(scip)) > SCIP_STAGE_PRESOLVED )
696  {
698  SCIP_CALL( GCGwriteSolvingDetails(scip) );
699  }
700 
702  {
703  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "\nOriginal Program statistics:\n");
704  SCIP_CALL( SCIPprintStatistics(scip, file) );
705  }
706  else
707  {
710  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "\nOriginal Program Solution statistics:\n");
711  SCIPprintSolutionStatistics(scip, file);
712  }
713  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(GCGgetMasterprob(scip)), file, "\n");
715  && SCIPgetStage(scip) >= SCIP_STAGE_SOLVING )
716  {
717  SCIP_CALL( GCGmasterPrintSimplexIters(GCGgetMasterprob(scip), file) );
718  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(GCGgetMasterprob(scip)), file, "\n");
719  }
721  {
722  SCIP_CALL( GCGconshdlrDecompPrintDetectorStatistics(scip, file) );
723  }
724  if( SCIPgetStage(scip) >= SCIP_STAGE_PRESOLVING && GCGgetNPricingprobs(scip) > 0 )
725  {
726  DEC_DECOMP* decomp;
727  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(GCGgetMasterprob(scip)), file, "\n");
728 
729  decomp = GCGgetStructDecomp(scip);
730  if( decomp != NULL )
731  SCIP_CALL( GCGprintDecompStatistics(scip, file, decomp) );
732  }
733  return SCIP_OKAY;
734 }
735 
736 /* print name of current instance to given output
737  * @returns SCIP return code */
738 SCIP_RETCODE GCGprintInstanceName(
739  SCIP* scip, /* SCIP data structure */
740  FILE* file /* output file or NULL for standard output */
741 )
742 {
743  char problemname[SCIP_MAXSTRLEN];
744  char* outputname;
745  (void) SCIPsnprintf(problemname, SCIP_MAXSTRLEN, "%s", SCIPgetProbName(scip));
746  SCIPsplitFilename(problemname, NULL, &outputname, NULL, NULL);
747 
748  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "filename: %s \n", outputname );
749  return SCIP_OKAY;
750 }
751 
752 
753 /* print out complete detection statistics
754  * @returns SCIP return code */
756  SCIP* scip, /* SCIP data structure */
757  FILE* file /* output file or NULL for standard output */
758 )
759 {
760  assert(scip != NULL);
761 
762  if( !GCGdetectionTookPlace(scip, TRUE) && !GCGdetectionTookPlace(scip, FALSE) )
763  {
764  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "\nDetection did not take place so far\n");
765  return SCIP_OKAY;
766  }
767 
768  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "\nStart writing complete detection information:\n");
769 
770  SCIP_CALL( GCGprintInstanceName(scip, file) );
771 
773 
774  GCGprintCompleteDetectionTime(scip, file);
775 
776  GCGprintPartitionInformation(scip, file);
777 
778  GCGprintDecompInformation(scip, file);
779 
780  return SCIP_OKAY;
781 }
782 
783 
784 
785 /* Checks whether the constraint belongs to GCG or not
786  * @returns whether the constraint belongs to GCG or not */
788  SCIP_CONS* cons /* constraint to check */
789  )
790 {
791  SCIP_CONSHDLR* conshdlr;
792  assert(cons != NULL);
793  conshdlr = SCIPconsGetHdlr(cons);
794  if( strcmp("origbranch", SCIPconshdlrGetName(conshdlr)) == 0 )
795  return TRUE;
796  else if( strcmp("masterbranch", SCIPconshdlrGetName(conshdlr)) == 0 )
797  return TRUE;
798 
799  return FALSE;
800 }
@ DEC_DECMODE_BENDERS
Definition: type_decomp.h:62
int GCGmasterVarGetNOrigvars(SCIP_VAR *var)
Definition: gcgvar.c:886
GCG interface methods.
SCIP_Bool GCGvarIsMaster(SCIP_VAR *var)
Definition: gcgvar.c:150
SCIP_RETCODE GCGprintDecompInformation(SCIP *scip, FILE *file)
SCIP_RETCODE GCGprintDecompStatistics(SCIP *scip, FILE *file, DEC_DECOMP *decomp)
Definition: decomp.c:3778
SCIP_RETCODE GCGconshdlrDecompPrintDetectorStatistics(SCIP *scip, FILE *file)
display statistics about detectors
int GCGoriginalVarGetNMastervars(SCIP_VAR *var)
Definition: gcgvar.c:569
SCIP_VAR ** GCGoriginalVarGetMastervars(SCIP_VAR *var)
Definition: gcgvar.c:587
SCIP_Bool GCGmasterIsSolValid(SCIP *scip, SCIP_SOL *mastersol)
SCIP_RETCODE GCGprintPartitionInformation(SCIP *scip, FILE *file)
SCIP_Bool GCGisConsGCGCons(SCIP_CONS *cons)
Definition: misc.c:787
SCIP_HASHMAP * GCGmasterVarGetOrigvalmap(SCIP_VAR *var)
Definition: gcgvar.c:979
constraint handler for structure detection
SCIP_RETCODE GCGprintCompleteDetectionStatistics(SCIP *scip, FILE *file)
Definition: misc.c:755
SCIP_HEUR * GCGrelaxGetProbingheur(SCIP *scip)
Definition: relax_gcg.c:4309
SCIP_RETCODE GCGtransformMastersolToOrigsol(SCIP *scip, SCIP_SOL *mastersol, SCIP_SOL **origsol)
Definition: misc.c:120
SCIP_VAR ** GCGmasterVarGetOrigvars(SCIP_VAR *var)
Definition: gcgvar.c:908
SCIP_Real * GCGmasterVarGetOrigvals(SCIP_VAR *var)
Definition: gcgvar.c:932
int GCGvarGetBlock(SCIP_VAR *var)
Definition: gcgvar.c:1033
SCIP_Bool GCGvarIsPricing(SCIP_VAR *var)
Definition: gcgvar.c:134
@ DEC_DECMODE_ORIGINAL
Definition: type_decomp.h:63
SCIP_Real * GCGoriginalVarGetMastervals(SCIP_VAR *var)
Definition: gcgvar.c:605
SCIP_VAR * GCGoriginalVarGetPricingVar(SCIP_VAR *var)
Definition: gcgvar.c:216
GCG Benders' decomposition.
int GCGgetNPricingprobs(SCIP *scip)
Definition: relax_gcg.c:3979
SCIP_Bool GCGvarIsOriginal(SCIP_VAR *var)
Definition: gcgvar.c:166
GCG variable pricer.
SCIP_Bool GCGisOriginal(SCIP *scip)
Definition: misc.c:665
SCIP_Real GCGtransformOrigvalsToMastervals(SCIP *scip, SCIP_VAR **origvars, SCIP_Real *origvals, int norigvars, SCIP_VAR **mastervars, SCIP_Real *mastervals, int nmastervars)
Definition: misc.c:545
SCIP * GCGgetMasterprob(SCIP *scip)
Definition: relax_gcg.c:3920
SCIP_VAR * GCGpricingVarGetOriginalVar(SCIP_VAR *var)
Definition: gcgvar.c:511
static GCG_DECL_SORTPTRCOMP(mastervarcomp)
Definition: misc.c:69
int GCGpricingVarGetNOrigvars(SCIP_VAR *var)
Definition: gcgvar.c:997
DEC_DECMODE GCGgetDecompositionMode(SCIP *scip)
Definition: relax_gcg.c:5123
@ DEC_DECMODE_DANTZIGWOLFE
Definition: type_decomp.h:61
static SCIP_Real getGeneratorEntry(SCIP_VAR *mastervar, SCIP_VAR *origvar)
Definition: misc.c:50
void GCGpricerPrintPricingStatistics(SCIP *scip, FILE *file)
SCIP_RETCODE GCGprintStatistics(SCIP *scip, FILE *file)
Definition: misc.c:685
GCG relaxator.
Prints information about the best decomposition.
SCIP_VAR ** GCGpricingVarGetOrigvars(SCIP_VAR *var)
Definition: gcgvar.c:1015
SCIP_SOL * GCGgetBendersRelaxationSol(SCIP *scip)
Definition: relax_gcg.c:5100
SCIP_RETCODE GCGprintInstanceName(SCIP *scip, FILE *file)
Definition: misc.c:738
SCIP_RETCODE GCGprintCompleteDetectionTime(SCIP *givenscip, FILE *file)
SCIP_Bool GCGisMaster(SCIP *scip)
Definition: misc.c:675
SCIP_RETCODE GCGprintBlockcandidateInformation(SCIP *scip, FILE *file)
DEC_DECOMP * GCGgetStructDecomp(SCIP *scip)
Definition: relax_gcg.c:2397
SCIP_Bool GCGmasterVarIsRay(SCIP_VAR *var)
Definition: gcgvar.c:852
SCIP_EXPORT void GCGsortPtrPtr(void **ptrarray1, void **ptrarray2, GCG_DECL_SORTPTRCOMP((*ptrcomp)), void *userdata, int len)
SCIP_Bool GCGoriginalVarIsLinking(SCIP_VAR *var)
Definition: gcgvar.c:182
public methods for GCG variables
sorting functions, adapted from SCIP's sorttpl to include userdata
SCIP_RETCODE GCGmasterPrintSimplexIters(SCIP *scip, FILE *file)
SCIP_RETCODE GCGwriteSolvingDetails(SCIP *scip)
Definition: stat.c:106
SCIP_Bool GCGdetectionTookPlace(SCIP *scip, SCIP_Bool original)