gcgvar.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-2018 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 
36 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
37 
38 #include "gcg.h"
39 #include "pub_gcgvar.h"
40 #include "struct_vardata.h"
41 #include "relax_gcg.h"
42 #include "scip_misc.h"
43 #include "scip/cons_linear.h"
44 
45 #define STARTMAXMASTERVARS 8
46 #define STARTMAXORIGVARS 1
47 
48 /*
49  * Vardata methods
50  */
51 
53 static
54 SCIP_DECL_VARDELORIG(GCGvarDelOrig)
55 {
56  if( *vardata == NULL )
57  return SCIP_OKAY;
58 
59  /*lint -e715 */
60  if( (*vardata)->vartype == GCG_VARTYPE_ORIGINAL )
61  {
62  if( (*vardata)->blocknr == -2 )
63  {
64  int nblocks;
65 
66  nblocks = GCGgetNPricingprobs(scip);
67  assert(nblocks > 0);
68 
69  assert((*vardata)->data.origvardata.linkingvardata != NULL);
70  if( (*vardata)->data.origvardata.linkingvardata->linkconss != NULL )
71  {
72  int i;
73  assert((*vardata)->data.origvardata.linkingvardata->pricingvars != NULL);
74 
75  for( i = 0; i < nblocks; i++ )
76  {
77  assert(((*vardata)->data.origvardata.linkingvardata->linkconss[i] == NULL)
78  == ((*vardata)->data.origvardata.linkingvardata->pricingvars[i] == NULL));
79  }
80 
81  SCIPfreeBlockMemoryArray(scip, &((*vardata)->data.origvardata.linkingvardata->linkconss), nblocks);
82  SCIPfreeBlockMemoryArray(scip, &((*vardata)->data.origvardata.linkingvardata->pricingvars), nblocks);
83  }
84  else if( (*vardata)->data.origvardata.linkingvardata->pricingvars != NULL )
85  SCIPfreeBlockMemoryArray(scip, &((*vardata)->data.origvardata.linkingvardata->pricingvars), nblocks);
86 
87  SCIPfreeBlockMemory(scip, &((*vardata)->data.origvardata.linkingvardata));
88  (*vardata)->data.origvardata.linkingvardata = NULL;
89  }
90  assert((*vardata)->data.origvardata.linkingvardata == NULL);
91  assert((*vardata)->data.origvardata.mastervars != NULL);
92  assert((*vardata)->data.origvardata.mastervals != NULL);
93  SCIPfreeBlockMemoryArrayNull(scip, &((*vardata)->data.origvardata.mastervars), (*vardata)->data.origvardata.maxmastervars);
94  SCIPfreeBlockMemoryArrayNull(scip, &((*vardata)->data.origvardata.mastervals), (*vardata)->data.origvardata.maxmastervars);
95 
96  if( (*vardata)->data.origvardata.ncoefs > 0 )
97  {
98  assert((*vardata)->data.origvardata.coefs != NULL);
99  assert((*vardata)->data.origvardata.masterconss != NULL);
100  SCIPfreeBlockMemoryArrayNull(scip, &((*vardata)->data.origvardata.coefs), (*vardata)->data.origvardata.ncoefs);
101  SCIPfreeBlockMemoryArrayNull(scip, &((*vardata)->data.origvardata.masterconss), (*vardata)->data.origvardata.ncoefs);
102  }
103  }
104  if( (*vardata)->vartype == GCG_VARTYPE_PRICING )
105  {
106  assert((*vardata)->data.pricingvardata.norigvars >= 1);
107  SCIPfreeBlockMemoryArray(scip, &((*vardata)->data.pricingvardata.origvars), (*vardata)->data.pricingvardata.maxorigvars);
108  }
109  assert((*vardata)->vartype != GCG_VARTYPE_MASTER);
110  SCIPfreeBlockMemory(scip, vardata);
111 
112  return SCIP_OKAY;
113 }
114 
115 
117 static
118 SCIP_DECL_VARDELTRANS(gcgvardeltrans)
119 {
120  /*lint -e715 */
121  assert((*vardata)->vartype == GCG_VARTYPE_MASTER);
122  SCIPfreeBlockMemoryArrayNull(scip, &((*vardata)->data.mastervardata.origvals), (*vardata)->data.mastervardata.norigvars);
123  SCIPfreeBlockMemoryArrayNull(scip, &((*vardata)->data.mastervardata.origvars), (*vardata)->data.mastervardata.norigvars);
124 
125  SCIPfreeBlockMemory(scip, vardata);
126 
127  return SCIP_OKAY;
128 }
129 
130 
131 
133 SCIP_Bool GCGvarIsPricing(
134  SCIP_VAR* var
135  )
136 {
137  SCIP_VARDATA* vardata;
138  assert(var != NULL);
139 
140  vardata = SCIPvarGetData(var);
141  if( vardata == NULL )
142  return FALSE;
143 
144  return vardata->vartype == GCG_VARTYPE_PRICING;
145 }
146 
148 SCIP_Bool GCGvarIsMaster(
149  SCIP_VAR* var
150  )
151 {
152  SCIP_VARDATA* vardata;
153  assert(var != NULL);
154 
155  vardata = SCIPvarGetData(var);
156  assert(vardata != NULL);
157 
158  return vardata->vartype == GCG_VARTYPE_MASTER;
159 }
160 
163  SCIP_VAR* var
164  )
165 {
166  SCIP_VARDATA* vardata;
167  assert(var != NULL);
168 
169  vardata = SCIPvarGetData(var);
170  assert(vardata != NULL);
171 
172  return vardata->vartype == GCG_VARTYPE_ORIGINAL;
173 }
174 
177  SCIP_VAR* var
178  )
179 {
180  SCIP_VARDATA* vardata;
181  assert(var != NULL);
182  assert(GCGvarIsOriginal(var));
183 
184  vardata = SCIPvarGetData(var);
185  assert(vardata != NULL);
186 
187  return vardata->blocknr == -2;
188 }
189 
192  SCIP_VAR* var
193  )
194 {
195  SCIP_VARDATA* vardata;
196  assert(var != NULL);
197  assert(GCGvarIsOriginal(var));
198 
199  vardata = SCIPvarGetData(var);
200  assert(vardata != NULL);
201 
202  return vardata->blocknr == -1;
203 }
204 
207  SCIP_VAR* var
208  )
209 {
210  SCIP_VARDATA* vardata;
211  assert(var != NULL);
212  assert(GCGvarIsOriginal(var));
213 
214  vardata = SCIPvarGetData(var);
215  assert(vardata != NULL);
216  assert(vardata->data.origvardata.linkingvardata == NULL);
217  assert(!GCGoriginalVarIsLinking(var));
218  if( vardata->data.origvardata.pricingvar != NULL )
219  assert(GCGvarIsPricing(vardata->data.origvardata.pricingvar));
220  return vardata->data.origvardata.pricingvar;
221 }
222 
225  SCIP_VAR* var,
226  SCIP_VAR* pricingvar
227  )
228 {
229  SCIP_VARDATA* vardata;
230  assert(var != NULL);
231  assert(pricingvar != NULL);
232  assert(GCGvarIsOriginal(var));
233  assert(GCGvarIsPricing(pricingvar));
234 
235  vardata = SCIPvarGetData(var);
236  assert(vardata != NULL);
237 
238  assert(vardata->data.origvardata.linkingvardata == NULL);
239  assert(!GCGoriginalVarIsLinking(var));
240  vardata->data.origvardata.pricingvar = pricingvar;
241 }
242 
245  SCIP* scip
246  )
247 {
248  SCIP_VAR** vars;
249  int nvars;
250  int i;
251 
252  assert(scip != NULL);
253 
254  vars = SCIPgetOrigVars(scip);
255  nvars = SCIPgetNOrigVars(scip);
256 
257  /* loop over the variables in the original problem */
258  for( i = 0; i < nvars; i++ )
259  {
260  assert(vars[i] != NULL);
261  SCIP_CALL( GCGorigVarCreateData(scip, vars[i]) );
262  }
263 
264  return SCIP_OKAY;
265 }
266 
268 SCIP_RETCODE GCGfreeOrigVarsData(
269  SCIP* scip
270  )
271 {
272  SCIP_VAR** vars;
273  int nvars;
274  int i;
275 
276  assert(scip != NULL);
277 
278  vars = SCIPgetOrigVars(scip);
279  nvars = SCIPgetNOrigVars(scip);
280 
281  /* loop over the variables in the original problem */
282  for( i = 0; i < nvars; i++ )
283  {
284  SCIP_VAR* var;
285  assert(vars[i] != NULL);
286  var = vars[i];
287 
288  if( SCIPvarGetData(var) != NULL )
289  {
290  SCIP_VARDATA* oldvardata;
291  oldvardata = SCIPvarGetData(var);
292 
293  SCIP_CALL( GCGvarDelOrig(scip, var, &oldvardata) );
294  SCIPvarSetData(var, NULL);
295  }
296  }
297 
298  return SCIP_OKAY;
299 }
300 
302 SCIP_RETCODE GCGorigVarCreateData(
303  SCIP* scip,
304  SCIP_VAR* var
305  )
306 {
307  SCIP_VARDATA* vardata;
308 
309  assert(scip != NULL);
310  assert(var != NULL);
311  assert(SCIPvarIsOriginal(var) || SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
312  /* create the vardata and initialize its values */
313  SCIP_CALL( SCIPallocBlockMemory(scip, &vardata) );
314  vardata->vartype = GCG_VARTYPE_ORIGINAL;
315  vardata->blocknr = -1;
316  vardata->data.origvardata.pricingvar = NULL;
317  vardata->data.origvardata.coefs = NULL;
318  vardata->data.origvardata.masterconss = NULL;
319  vardata->data.origvardata.ncoefs = 0;
320  vardata->data.origvardata.nmastervars = 0;
321  vardata->data.origvardata.maxmastervars = STARTMAXMASTERVARS;
322  vardata->data.origvardata.linkingvardata = NULL;
323  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(vardata->data.origvardata.mastervars),
324  vardata->data.origvardata.maxmastervars) );
325  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(vardata->data.origvardata.mastervals),
326  vardata->data.origvardata.maxmastervars) );
327 
328  if( SCIPvarGetData(var) != NULL )
329  {
330  SCIP_VARDATA* oldvardata;
331  oldvardata = SCIPvarGetData(var);
332 
333  SCIP_CALL( GCGvarDelOrig(scip, var, &oldvardata) );
334  }
335  SCIPvarSetData(var, vardata);
336  if( SCIPvarIsOriginal(var) )
337  {
338  SCIPvarSetDelorigData(var, GCGvarDelOrig);
339  if( SCIPvarGetTransVar(var) != NULL )
340  {
341  SCIPvarSetData(SCIPvarGetProbvar(SCIPvarGetTransVar(var)), vardata);
342  }
343  }
344  else
345  {
346  assert(SCIPvarIsTransformedOrigvar(var));
347  SCIPvarSetDeltransData(var, GCGvarDelOrig);
348  }
349 
350  return SCIP_OKAY;
351 }
352 
357  SCIP* scip,
358  SCIP_VAR* pricingvar,
359  SCIP_VAR* mastervar
360  )
361 {
362  SCIP_VARDATA* targetvardata;
363  assert(pricingvar != NULL);
364  assert(mastervar != NULL);
365  assert(GCGvarIsPricing(pricingvar));
366  /* we can't assert that mastervar is a master variable because it may not have the appropriate vardata yet */
367 
368  assert(GCGpricingVarGetNOrigvars(pricingvar) == 1);
369 
370  /* create vardata */
371  SCIP_CALL( SCIPallocBlockMemory(scip, &targetvardata) );
372  targetvardata->vartype = GCG_VARTYPE_MASTER;
373  targetvardata->blocknr = -1;
374  targetvardata->data.mastervardata.isray = FALSE;
375  targetvardata->data.mastervardata.isartificial = FALSE;
376  targetvardata->data.mastervardata.norigvars = 1;
377 
378  /* save corresoponding origvar */
379  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(targetvardata->data.mastervardata.origvars), 1) ); /*lint !e506*/
380  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(targetvardata->data.mastervardata.origvals), 1) ); /*lint !e506*/
381  targetvardata->data.mastervardata.origvars[0] = GCGpricingVarGetOrigvars(pricingvar)[0];
382  targetvardata->data.mastervardata.origvals[0] = 1.0;
383 
384  SCIPvarSetData(mastervar, targetvardata);
385  SCIPvarSetDeltransData(mastervar, gcgvardeltrans);
386 
387  return SCIP_OKAY;
388 }
389 
392  SCIP_VAR* var
393  )
394 {
395  SCIP_VARDATA* vardata;
396  assert(var != NULL);
397  assert(GCGoriginalVarIsLinking(var));
398 
399  vardata = SCIPvarGetData(var);
400  assert(vardata != NULL);
401  assert(vardata->data.origvardata.linkingvardata != NULL);
402  assert(vardata->data.origvardata.linkingvardata->pricingvars != NULL);
403 
404  return vardata->data.origvardata.linkingvardata->pricingvars;
405 }
406 
409  SCIP_VAR* origvar,
410  int pricingprobnr,
411  SCIP_VAR* var
412  )
413 {
414  SCIP_VARDATA* vardata;
415  assert(origvar != NULL);
416  assert(var != NULL);
417  assert(pricingprobnr >= 0);
418 
419  assert(GCGoriginalVarIsLinking(origvar));
420  assert(GCGvarIsPricing(var));
421 
422  vardata = SCIPvarGetData(origvar);
423  assert(vardata != NULL);
424  assert(vardata->data.origvardata.linkingvardata != NULL);
425  assert(vardata->data.origvardata.linkingvardata->pricingvars != NULL);
426 
427  vardata->data.origvardata.linkingvardata->pricingvars[pricingprobnr] = var;
428 }
429 
432  SCIP_VAR* var,
433  int nblocks,
434  int* blocks
435  )
436 {
437  SCIP_VARDATA* vardata;
438  int i;
439  int j;
440 
441  assert(var != NULL);
442  assert(nblocks == 0 || blocks != NULL);
443 
444  assert(GCGoriginalVarIsLinking(var));
445  vardata = SCIPvarGetData(var);
446  assert(vardata != NULL);
447  assert(vardata->data.origvardata.linkingvardata != NULL);
448  assert(vardata->data.origvardata.linkingvardata->nblocks > 0);
449 
450  /* the blocks array must be large enough to hold all block numbers */
451  if( nblocks < vardata->data.origvardata.linkingvardata->nblocks )
452  {
453  SCIPerrorMessage("array too small to store all block numbers!\n");
454  return SCIP_INVALIDDATA;
455  }
456  assert(nblocks >= vardata->data.origvardata.linkingvardata->nblocks);
457 
458  /* fill the blocks array */
459  j = -1;
460  for( i = 0; i < vardata->data.origvardata.linkingvardata->nblocks; ++i )
461  {
462  /* search the next block the linking variable is contained in */
463  do
464  ++j;
465  while ( vardata->data.origvardata.linkingvardata->pricingvars[j] == NULL );
466  blocks[i] = j;
467  }
468 
469  return SCIP_OKAY;
470 }
471 
474  SCIP_VAR* var
475  )
476 {
477  SCIP_VARDATA* vardata;
478  assert(var != NULL);
479 
480  assert(GCGoriginalVarIsLinking(var));
481  vardata = SCIPvarGetData(var);
482  assert(vardata != NULL);
483  assert(vardata->data.origvardata.linkingvardata != NULL);
484  assert(vardata->data.origvardata.linkingvardata->nblocks > 0);
485  return vardata->data.origvardata.linkingvardata->nblocks;
486 }
487 
490  SCIP_VAR* var
491  )
492 {
493  SCIP_VARDATA* vardata;
494  assert(var != NULL);
495  assert(GCGvarIsPricing(var));
496 
497  vardata = SCIPvarGetData(var);
498  assert(vardata != NULL);
499  assert(vardata->data.pricingvardata.norigvars >= 0);
500  assert(vardata->data.pricingvardata.origvars != NULL);
501  assert(vardata->data.pricingvardata.origvars[0] != NULL);
502  assert(vardata->blocknr >= 0); /* variable belongs to exactly one block */
503 
504  return vardata->data.pricingvardata.origvars[0];
505 }
506 
509  SCIP* scip,
510  SCIP_VAR* pricingvar,
511  SCIP_VAR* origvar
512  )
513 {
514  SCIP_VARDATA* vardata;
515  assert(pricingvar != NULL);
516  assert(origvar != NULL);
517  assert(GCGvarIsPricing(pricingvar));
518  assert(GCGvarIsOriginal(origvar));
519 
520  vardata = SCIPvarGetData(pricingvar);
521  assert(vardata != NULL);
522  assert(vardata->data.pricingvardata.norigvars >= 0);
523  assert(vardata->data.pricingvardata.origvars != NULL);
524  assert(vardata->data.pricingvardata.origvars[0] != NULL);
525  assert(vardata->blocknr >= 0); /* variable belongs to exactly one block */
526 
527  /* realloc origvars array of the pricing variable, if needed */
528  if( vardata->data.pricingvardata.maxorigvars == vardata->data.pricingvardata.norigvars )
529  {
530  int newsize = SCIPcalcMemGrowSize(scip, vardata->data.pricingvardata.norigvars+1);
531  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &(vardata->data.pricingvardata.origvars), vardata->data.pricingvardata.maxorigvars,
532  newsize) );
533  SCIPdebugMessage("origvars array of var %s resized from %d to %d\n", SCIPvarGetName(origvar),
534  vardata->data.pricingvardata.maxorigvars, newsize);
535  vardata->data.pricingvardata.maxorigvars = newsize;
536  }
537 
538  vardata->data.pricingvardata.origvars[vardata->data.pricingvardata.norigvars] = origvar;
539  vardata->data.pricingvardata.norigvars++;
540 
541  return SCIP_OKAY;
542 }
543 
546  SCIP_VAR* var
547  )
548 {
549  SCIP_VARDATA* vardata;
550  assert(var != NULL);
551  assert(GCGvarIsOriginal(var));
552 
553  vardata = SCIPvarGetData(var);
554  assert(vardata != NULL);
555  assert(vardata->data.origvardata.nmastervars >= 0);
556 
557  return vardata->data.origvardata.nmastervars;
558 }
559 
562  SCIP_VAR* var
563  )
564 {
565  SCIP_VARDATA* vardata;
566  assert(var != NULL);
567  assert(GCGvarIsOriginal(var));
568 
569  vardata = SCIPvarGetData(var);
570  assert(vardata != NULL);
571 
572  assert(vardata->data.origvardata.mastervars != NULL);
573  return vardata->data.origvardata.mastervars;
574 }
575 
578  SCIP_VAR* var
579  )
580 {
581  SCIP_VARDATA* vardata;
582  assert(var != NULL);
583  assert(GCGvarIsOriginal(var));
584 
585  vardata = SCIPvarGetData(var);
586  assert(vardata != NULL);
587 
588  assert(vardata->data.origvardata.mastervals != NULL);
589  return vardata->data.origvardata.mastervals;
590 }
591 
594  SCIP_VAR* var
595  )
596 {
597  SCIP_VARDATA* vardata;
598  assert(var != NULL);
599  assert(GCGvarIsOriginal(var));
600 
601  vardata = SCIPvarGetData(var);
602  assert(vardata != NULL);
603 
604  assert(vardata->data.origvardata.coefs != NULL || vardata->data.origvardata.ncoefs == 0 );
605  return vardata->data.origvardata.coefs;
606 }
607 
610  SCIP_VAR* var
611  )
612 {
613  SCIP_VARDATA* vardata;
614  assert(var != NULL);
615  assert(GCGvarIsOriginal(var));
616 
617  vardata = SCIPvarGetData(var);
618  assert(vardata != NULL);
619 
620  assert(vardata->data.origvardata.coefs != NULL || vardata->data.origvardata.ncoefs == 0 );
621  return vardata->data.origvardata.ncoefs;
622 }
623 
626  SCIP_VAR* var,
627  int ncoefs
628  )
629 {
630  SCIP_VARDATA* vardata;
631  assert(var != NULL);
632  assert(ncoefs >= 0);
633  assert(GCGvarIsOriginal(var));
634 
635  vardata = SCIPvarGetData(var);
636  assert(vardata != NULL);
637 
638  assert(vardata->data.origvardata.coefs != NULL || vardata->data.origvardata.ncoefs == 0 );
639  if( ncoefs == 0 )
640  assert(vardata->data.origvardata.coefs == NULL);
641 
642  vardata->data.origvardata.ncoefs = ncoefs;
643 }
644 
647  SCIP* scip,
648  SCIP_VAR* var,
649  SCIP_Real val,
650  SCIP_CONS* cons
651  )
652 {
653  SCIP_VARDATA* vardata;
654  assert(scip != NULL);
655  assert(var != NULL);
656  assert(!SCIPisZero(scip, val));
657  assert(cons != NULL);
658  assert(GCGvarIsOriginal(var));
659  vardata = SCIPvarGetData(var);
660  assert(vardata != NULL);
661 
662  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &(vardata->data.origvardata.coefs), (size_t)vardata->data.origvardata.ncoefs, (size_t)vardata->data.origvardata.ncoefs+1) );
663  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &(vardata->data.origvardata.masterconss), (size_t)vardata->data.origvardata.ncoefs, (size_t)vardata->data.origvardata.ncoefs+1) );
664 
665  assert(vardata->data.origvardata.coefs != NULL);
666  assert(vardata->data.origvardata.masterconss != NULL);
667 
668  vardata->data.origvardata.coefs[vardata->data.origvardata.ncoefs] = val;
669  vardata->data.origvardata.masterconss[vardata->data.origvardata.ncoefs] = cons;
670  vardata->data.origvardata.ncoefs++;
671 
672  return SCIP_OKAY;
673 }
674 
675 
678  SCIP_VAR* var
679  )
680 {
681  SCIP_VARDATA* vardata;
682  assert(var != NULL);
683  assert(GCGvarIsOriginal(var));
684 
685  vardata = SCIPvarGetData(var);
686  assert(vardata != NULL);
687 
688  return vardata->data.origvardata.masterconss;
689 }
690 
693  SCIP* scip,
694  SCIP_VAR* var,
695  int newblock,
696  int nblocks,
697  DEC_DECMODE mode
698  )
699 {
700  SCIP_VARDATA* vardata;
701  int blocknr;
702  assert(scip != NULL);
703  assert(var != NULL);
704  assert(GCGvarIsOriginal(var));
705 
706  vardata = SCIPvarGetData(var);
707  assert(vardata != NULL);
708 
709  assert(nblocks >= 0);
710  assert((newblock >= 0 && newblock < nblocks)
711  || (GCGgetDecompositionMode(scip) == DEC_DECMODE_BENDERS && newblock == -2));
712  blocknr = GCGvarGetBlock(var);
713  assert(newblock >= 0 || (newblock == -2 && blocknr > -1));
714  /* the variable was only in one block so far, so set up the linking variable data */
715  if( blocknr > -1 )
716  {
717  SCIP_CALL( SCIPallocBlockMemory(scip, &vardata->data.origvardata.linkingvardata) );
718  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &vardata->data.origvardata.linkingvardata->pricingvars, nblocks) );
719  BMSclearMemoryArray(vardata->data.origvardata.linkingvardata->pricingvars, nblocks);
720 
721  if( mode != DEC_DECMODE_BENDERS )
722  {
723  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &vardata->data.origvardata.linkingvardata->linkconss, nblocks) );
724  BMSclearMemoryArray(vardata->data.origvardata.linkingvardata->linkconss, nblocks);
725  }
726  else
727  vardata->data.origvardata.linkingvardata->linkconss = NULL;
728 
729  /* store old block; store the original variable, it will be exchanged for the correct pricing variable later */
730  vardata->data.origvardata.linkingvardata->pricingvars[blocknr] = var;
731  vardata->data.origvardata.linkingvardata->nblocks = 1;
732 
733  vardata->blocknr = -2;
734  }
735  assert(GCGoriginalVarIsLinking(var));
736 
737  /* store new block. In the Benders' decomposition mode, it is possible to have linking variables that only correspond
738  * to a single block. In this case, we still want the variables in the master problem, but we need to ensure that the
739  * linking variables are added correctly
740  */
741  if( newblock >= 0 && vardata->data.origvardata.linkingvardata->pricingvars[newblock] == NULL )
742  {
743  assert(mode == DEC_DECMODE_BENDERS || vardata->data.origvardata.linkingvardata->linkconss[newblock] == NULL);
744  vardata->data.origvardata.linkingvardata->pricingvars[newblock] = var;
745  vardata->data.origvardata.linkingvardata->nblocks++;
746  }
747  assert(vardata->data.origvardata.linkingvardata->nblocks <= nblocks);
748  return SCIP_OKAY;
749 }
750 
751 
754  SCIP_VAR* var
755  )
756 {
757  SCIP_VARDATA* vardata;
758  assert(var != NULL);
759  assert(GCGvarIsOriginal(var));
760  assert(GCGoriginalVarIsLinking(var));
761 
762  vardata = SCIPvarGetData(var);
763  assert(vardata != NULL);
764 
765  assert(vardata->data.origvardata.linkingvardata != NULL);
766  //assert(vardata->data.origvardata.linkingvardata->linkconss != NULL);
767  return vardata->data.origvardata.linkingvardata->linkconss;
768 }
769 
772  SCIP_VAR* var,
773  SCIP_CONS* cons,
774  int index
775  )
776 {
777  SCIP_VARDATA* vardata;
778  assert(var != NULL);
779  assert(cons != NULL);
780  assert(index >= 0);
781  assert(GCGvarIsOriginal(var));
782  assert(GCGoriginalVarIsLinking(var));
783 
784  vardata = SCIPvarGetData(var);
785  assert(vardata != NULL);
786 
787  assert(vardata->data.origvardata.linkingvardata != NULL);
788  assert(vardata->data.origvardata.linkingvardata->linkconss != NULL);
789  vardata->data.origvardata.linkingvardata->linkconss[index] = cons;
790 }
791 
794  SCIP_VAR* var
795  )
796 {
797  assert(var != NULL);
798  assert(GCGvarIsMaster(var));
799 
800  /* the master variable is a direct copy from an original variable */
801  if( GCGvarGetBlock(var) == -1 )
802  {
803  SCIP_VAR** origvars;
804  origvars = GCGmasterVarGetOrigvars(var);
805 
806  if( GCGmasterVarIsArtificial(var) )
807  return FALSE;
808 
809  return GCGoriginalVarIsLinking(origvars[0]);
810  }
811  else
812  return FALSE;
813 }
814 
817  SCIP_VAR* var
818  )
819 {
820  SCIP_VARDATA* vardata;
821  assert(var != NULL);
822  assert(GCGvarIsMaster(var));
823 
824  vardata = SCIPvarGetData(var);
825  assert(vardata != NULL);
826 
827  return vardata->data.mastervardata.isray;
828 }
829 
832  SCIP_VAR* var
833  )
834 {
835  SCIP_VARDATA* vardata;
836  assert(var != NULL);
837  assert(GCGvarIsMaster(var));
838 
839  vardata = SCIPvarGetData(var);
840  assert(vardata != NULL);
841 
842  return vardata->data.mastervardata.isartificial;
843 }
844 
847  SCIP_VAR* var
848  )
849 {
850  SCIP_VARDATA* vardata;
851  assert(var != NULL);
852  assert(GCGvarIsMaster(var));
853 
854  vardata = SCIPvarGetData(var);
855  assert(vardata != NULL);
856 
857  assert(vardata->data.mastervardata.norigvars >= 0);
858  assert(vardata->data.mastervardata.origvars != NULL || vardata->data.mastervardata.norigvars == 0);
859  assert(vardata->data.mastervardata.origvals != NULL || vardata->data.mastervardata.norigvars == 0);
860 // assert(vardata->blocknr != -1 || vardata->data.mastervardata.norigvars == 1 );
861 
862  return vardata->data.mastervardata.norigvars;
863 }
864 
867  SCIP_VAR* var
868  )
869 {
870  SCIP_VARDATA* vardata;
871  assert(var != NULL);
872  assert(GCGvarIsMaster(var));
873 
874  vardata = SCIPvarGetData(var);
875  assert(vardata != NULL);
876 
877  assert(vardata->data.mastervardata.origvars != NULL || vardata->data.mastervardata.norigvars == 0);
878 // assert(vardata->blocknr != -1 || vardata->data.mastervardata.origvars != NULL);
879 // assert(vardata->blocknr != -1 || vardata->data.mastervardata.origvars[0] != NULL);
880 // assert(vardata->blocknr != -1 || GCGvarGetBlock(vardata->data.mastervardata.origvars[0]) == -1
881 // || GCGoriginalVarIsLinking(vardata->data.mastervardata.origvars[0]));
882 
883 
884  return vardata->data.mastervardata.origvars;
885 }
886 
889  SCIP_VAR* var
890  )
891 {
892  SCIP_VARDATA* vardata;
893  assert(var != NULL);
894  assert(GCGvarIsMaster(var));
895 
896  vardata = SCIPvarGetData(var);
897  assert(vardata != NULL);
898 
899  assert(vardata->data.mastervardata.origvals != NULL || vardata->data.mastervardata.norigvars == 0);
900  return vardata->data.mastervardata.origvals;
901 }
902 
905  SCIP_VAR* var
906  )
907 {
908  SCIP_VARDATA* vardata;
909  assert(var != NULL);
910  assert(GCGvarIsPricing(var));
911 
912  vardata = SCIPvarGetData(var);
913  assert(vardata != NULL);
914 
915  assert(vardata->data.pricingvardata.norigvars >= 0);
916  return vardata->data.pricingvardata.norigvars;
917 }
918 
921  SCIP_VAR* var
922  )
923 {
924  SCIP_VARDATA* vardata;
925  assert(var != NULL);
926  assert(GCGvarIsPricing(var));
927 
928  vardata = SCIPvarGetData(var);
929  assert(vardata != NULL);
930 
931  assert(vardata->data.pricingvardata.origvars != NULL);
932  return vardata->data.pricingvardata.origvars;
933 }
934 
937  SCIP_VAR* var
938  )
939 {
940  SCIP_VARDATA* vardata;
941  assert(var != NULL);
942  vardata = SCIPvarGetData(var);
943  assert(vardata != NULL);
944 
945  assert(vardata->blocknr >= -2);
946  return vardata->blocknr;
947 }
948 
951  SCIP_VAR* var,
952  int block
953  )
954 {
955  SCIP_VARDATA* vardata;
956  assert(var != NULL);
957  assert(block >= -1);
958 
959  vardata = SCIPvarGetData(var);
960  assert(vardata != NULL);
961  vardata->blocknr = block;
962 }
963 
966  SCIP_VAR* var,
967  int block
968  )
969 {
970  SCIP_VAR** pricingvars;
971 
972  assert(var != NULL);
973  assert(block >= 0);
974 
975  assert(GCGoriginalVarIsLinking(var));
976  assert(GCGvarIsOriginal(var));
977 
978  pricingvars = GCGlinkingVarGetPricingVars(var);
979 
980  return pricingvars[block] != NULL;
981 }
982 
985  SCIP_VAR* mastervar,
986  int block
987  )
988 {
989  int varblock;
990 
991  assert(mastervar != NULL);
992  assert(block >= 0);
993 
994  varblock = GCGvarGetBlock(mastervar);
995 
996  /* the master variable is a direct copy from an original variable */
997  if( varblock == -1 )
998  {
999  SCIP_VAR** origvars;
1000 
1001  origvars = GCGmasterVarGetOrigvars(mastervar);
1002 
1003  if( GCGmasterVarIsArtificial(mastervar) )
1004  return FALSE;
1005 
1006  /* the corresponding original variable is a linking variable */
1007  if( GCGoriginalVarIsLinking(origvars[0]) )
1008  return GCGisLinkingVarInBlock(origvars[0], block);
1009  else
1010  return FALSE;
1011  }
1012  else
1013  return varblock == block;
1014 }
1015 
1022  SCIP* scip,
1023  SCIP_VAR* origvar,
1024  SCIP_VAR* var,
1025  SCIP_Real val
1026  )
1027 {
1028  SCIP_VARDATA* vardata;
1029 
1030  assert(scip != NULL);
1031  assert(origvar != NULL);
1032  assert(var != NULL);
1033  assert(GCGisOriginal(scip));
1034  vardata = SCIPvarGetData(origvar);
1035 
1036  assert(vardata != NULL);
1037  assert(GCGvarIsOriginal(origvar));
1038  assert(vardata->data.origvardata.mastervars != NULL);
1039  assert(vardata->data.origvardata.mastervals != NULL);
1040  assert(vardata->data.origvardata.nmastervars >= 0);
1041  assert(vardata->data.origvardata.maxmastervars >= vardata->data.origvardata.nmastervars);
1042 
1043  /* realloc mastervars array of the original variable, if needed */
1044  if( vardata->data.origvardata.maxmastervars == vardata->data.origvardata.nmastervars )
1045  {
1046  int newsize = SCIPcalcMemGrowSize(scip, vardata->data.origvardata.nmastervars+1);
1047  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &(vardata->data.origvardata.mastervars), vardata->data.origvardata.maxmastervars,
1048  newsize) );
1049  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &(vardata->data.origvardata.mastervals), vardata->data.origvardata.maxmastervars,
1050  newsize) );
1051  SCIPdebugMessage("mastervars array of var %s resized from %d to %d\n", SCIPvarGetName(origvar),
1052  vardata->data.origvardata.maxmastervars, newsize);
1053  vardata->data.origvardata.maxmastervars = newsize;
1054  }
1055  /* add information to the original variable's vardata */
1056  vardata->data.origvardata.mastervars[vardata->data.origvardata.nmastervars] = var;
1057  vardata->data.origvardata.mastervals[vardata->data.origvardata.nmastervars] = val;
1058  vardata->data.origvardata.nmastervars++;
1059 
1060  return SCIP_OKAY;
1061 }
1062 
1069  SCIP* scip,
1070  SCIP_VAR* origvar,
1071  SCIP_VAR* var
1072  )
1073 {
1074  SCIP_VARDATA* vardata;
1075  int i;
1076 
1077  assert(scip != NULL);
1078  assert(origvar != NULL);
1079  assert(var != NULL);
1080 
1081  vardata = SCIPvarGetData(origvar);
1082 
1083  assert(vardata != NULL);
1084  assert(GCGvarIsOriginal(origvar));
1085  assert(vardata->data.origvardata.mastervars != NULL);
1086  assert(vardata->data.origvardata.mastervals != NULL);
1087  assert(vardata->data.origvardata.nmastervars > 0);
1088  assert(vardata->data.origvardata.maxmastervars >= vardata->data.origvardata.nmastervars);
1089 
1090  for( i = 0; i < vardata->data.origvardata.nmastervars; ++i )
1091  {
1092  if( vardata->data.origvardata.mastervars[i] == var )
1093  {
1094  vardata->data.origvardata.mastervars[i] = vardata->data.origvardata.mastervars[vardata->data.origvardata.nmastervars - 1];
1095  vardata->data.origvardata.mastervals[i] = vardata->data.origvardata.mastervals[vardata->data.origvardata.nmastervars - 1];
1096  (vardata->data.origvardata.nmastervars)--;
1097 
1098  break;
1099  }
1100  }
1101  assert(i <= vardata->data.origvardata.nmastervars);
1102 #ifndef NDEBUG
1103  for( ; i < vardata->data.origvardata.nmastervars; ++i )
1104  {
1105  assert(vardata->data.origvardata.mastervars[i] != var);
1106  }
1107 #endif
1108 
1109  return SCIP_OKAY;
1110 }
1111 
1114  SCIP* scip,
1115  SCIP_VAR* origvar,
1116  SCIP_VAR** var
1117  )
1118 {
1119  SCIP_VARDATA* vardata;
1120  char name[SCIP_MAXSTRLEN];
1121  int pricingprobnr;
1122  assert(scip != NULL);
1123  assert(origvar != NULL);
1124  assert(var != NULL);
1125  assert(GCGvarIsOriginal(origvar));
1126  assert(!GCGoriginalVarIsLinking(origvar));
1127  assert(GCGoriginalVarGetPricingVar(origvar) == NULL);
1128 
1129  /* get the number of the pricing block to which the variable belongs */
1130  pricingprobnr = GCGvarGetBlock(origvar);
1131 
1132  /* create variable data */
1133  SCIP_CALL( SCIPallocBlockMemory(scip, &vardata) );
1134  vardata->vartype = GCG_VARTYPE_PRICING;
1135  vardata->blocknr = pricingprobnr;
1136  vardata->data.pricingvardata.maxorigvars = STARTMAXORIGVARS;
1137  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(vardata->data.pricingvardata.origvars), vardata->data.pricingvardata.maxorigvars) ); /*lint !e506*/
1138  vardata->data.pricingvardata.origvars[0] = origvar;
1139  vardata->data.pricingvardata.norigvars = 1;
1140 
1141  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "pr%d_%s", pricingprobnr, SCIPvarGetName(origvar));
1142  SCIP_CALL( SCIPcreateVar(scip, var, name, SCIPvarGetLbGlobal(origvar),
1143  SCIPvarGetUbGlobal(origvar), 0.0, SCIPvarGetType(origvar),
1144  TRUE, FALSE, GCGvarDelOrig, NULL, NULL, NULL, vardata) );
1145 
1146  return SCIP_OKAY;
1147 }
1148 
1151  SCIP* pricingscip,
1152  int pricingprobnr,
1153  SCIP_VAR* origvar,
1154  SCIP_VAR** var
1155  )
1156 {
1157  SCIP_VARDATA* vardata;
1158  char name[SCIP_MAXSTRLEN];
1159 
1160  assert(pricingscip != NULL);
1161  assert(pricingprobnr >= 0);
1162  assert(origvar != NULL);
1163  assert(GCGoriginalVarIsLinking(origvar));
1164  assert(var != NULL);
1165 
1166  /* create variable data */
1167  SCIP_CALL( SCIPallocBlockMemory(pricingscip, &vardata) );
1168  vardata->vartype = GCG_VARTYPE_PRICING;
1169  vardata->blocknr = pricingprobnr;
1170  vardata->data.pricingvardata.maxorigvars = STARTMAXORIGVARS;
1171  SCIP_CALL( SCIPallocBlockMemoryArray(pricingscip, &(vardata->data.pricingvardata.origvars), vardata->data.pricingvardata.maxorigvars) ); /*lint !e506*/
1172  vardata->data.pricingvardata.origvars[0] = origvar;
1173  vardata->data.pricingvardata.norigvars = 1;
1174 
1175  /* create and add variable */
1176  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "pr%d_%s", pricingprobnr, SCIPvarGetName(origvar));
1177  SCIP_CALL( SCIPcreateVar(pricingscip, var, name, SCIPvarGetLbGlobal(origvar),
1178  SCIPvarGetUbGlobal(origvar), 0.0, SCIPvarGetType(origvar),
1179  TRUE, FALSE, GCGvarDelOrig, NULL, NULL, NULL, vardata) );
1180 
1181  return SCIP_OKAY;
1182 }
1183 
1186  SCIP* masterscip,
1187  int pricingprobnr,
1188  SCIP_VAR* origvar,
1189  SCIP_CONS** linkcons
1190  )
1191 {
1192  char name[SCIP_MAXSTRLEN];
1193 
1194  assert(masterscip != NULL);
1195  assert(pricingprobnr >= 0);
1196  assert(origvar != NULL);
1197  assert(GCGoriginalVarIsLinking(origvar));
1198  assert(linkcons != NULL);
1199 
1200  /* add corresponding linking constraint to the master problem */
1201  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "l_%s_%d", SCIPvarGetName(origvar), pricingprobnr);
1202  SCIP_CALL( SCIPcreateConsLinear(masterscip, linkcons, name, 0, NULL, NULL, 0.0, 0.0,
1203  TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE) );
1204 
1205  return SCIP_OKAY;
1206 }
1207 
1209 SCIP_RETCODE GCGcreateMasterVar(
1210  SCIP* scip,
1211  SCIP* origscip,
1212  SCIP* pricingscip,
1213  SCIP_VAR** newvar,
1214  const char* varname,
1215  SCIP_Real objcoeff,
1216  SCIP_VARTYPE vartype,
1217  SCIP_Bool solisray,
1218  int prob,
1219  int nsolvars,
1220  SCIP_Real* solvals,
1221  SCIP_VAR** solvars,
1222  SCIP_Bool auxiliaryvar
1223  )
1224 {
1225  SCIP_VARDATA* newvardata;
1226  SCIP_Real lb;
1227  int i;
1228  int j;
1229  SCIP_Bool trivialsol;
1230 
1231  assert(scip != NULL);
1232  assert(pricingscip != NULL);
1233  assert(newvar != NULL);
1234  assert(varname != NULL);
1235  assert(!SCIPisInfinity(pricingscip, ABS(objcoeff)));
1236  assert(vartype == SCIP_VARTYPE_INTEGER || vartype == SCIP_VARTYPE_CONTINUOUS);
1237  assert(prob >= 0);
1238  assert(nsolvars >= 0);
1239  assert(solvals != NULL || nsolvars == 0);
1240  assert(solvars != NULL || nsolvars == 0);
1241 
1242  trivialsol = FALSE;
1243 
1244  lb = 0.0;
1245  if( auxiliaryvar )
1246  lb = -SCIPinfinity(scip);
1247 
1248  /* create data for the new variable in the master problem */
1249  SCIP_CALL( SCIPallocBlockMemory(scip, &newvardata) );
1250  newvardata->vartype = GCG_VARTYPE_MASTER;
1251  newvardata->blocknr = prob;
1252 
1253  /* store whether the variable represents a ray */
1254  newvardata->data.mastervardata.isray = solisray;
1255  newvardata->data.mastervardata.isartificial = FALSE;
1256 
1257  /* create variable in the master problem */
1258  SCIP_CALL( SCIPcreateVar(scip, newvar, varname, lb, SCIPinfinity(scip), /* GCGrelaxGetNIdenticalBlocks(origprob, prob) */
1259  objcoeff, vartype, TRUE, TRUE, NULL, NULL, gcgvardeltrans, NULL, newvardata) );
1260 
1261  /* count number of non-zeros */
1262  newvardata->data.mastervardata.norigvars = 0;
1263 
1264  for( i = 0; i < nsolvars; i++ )
1265  {
1266  assert(solvars != NULL);
1267  assert(solvals != NULL);
1268 
1269  assert(!SCIPisInfinity(scip, solvals[i]));
1270  if( !SCIPisZero(scip, solvals[i]) )
1271  {
1272  newvardata->data.mastervardata.norigvars++;
1273  }
1274  }
1275 
1276  /*
1277  * if we have not added any original variable to the mastervariable, all coefficients were 0.
1278  * In that case, we will add all variables in the pricing problem
1279  */
1280  if( newvardata->data.mastervardata.norigvars == 0 && !auxiliaryvar )
1281  {
1282  newvardata->data.mastervardata.norigvars = SCIPgetNOrigVars(pricingscip);
1283  trivialsol = TRUE;
1284  }
1285 
1286  if( newvardata->data.mastervardata.norigvars > 0 )
1287  {
1288  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(newvardata->data.mastervardata.origvars), newvardata->data.mastervardata.norigvars) );
1289  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(newvardata->data.mastervardata.origvals), newvardata->data.mastervardata.norigvars) );
1290  }
1291  else
1292  {
1293  newvardata->data.mastervardata.origvars = NULL;
1294  newvardata->data.mastervardata.origvals = NULL;
1295  }
1296 
1297  /* number of original variables already saved in mastervardata */
1298  j = 0;
1299 
1300  /* update variable datas */
1301  for( i = 0; i < nsolvars && !trivialsol; i++ )
1302  {
1303  SCIP_Real solval;
1304 
1305  assert(solvars != NULL);
1306  assert(solvals != NULL);
1307 
1308  solval = solvals[i];
1309 
1310  if( !SCIPisZero(scip, solval) )
1311  {
1312  SCIP_VAR* origvar;
1313  assert(GCGvarIsPricing(solvars[i]));
1314 
1315  origvar = GCGpricingVarGetOrigvars(solvars[i])[0];
1316  assert(origvar != NULL);
1317 
1318  assert(newvardata->data.mastervardata.origvars != NULL);
1319  assert(newvardata->data.mastervardata.origvals != NULL);
1320  assert(GCGvarIsOriginal(origvar));
1321  assert(!solisray || vartype == SCIP_VARTYPE_CONTINUOUS || SCIPisIntegral(scip, solval) || SCIPvarGetType(solvars[i]) == SCIP_VARTYPE_CONTINUOUS);
1322 
1323  /* round solval if possible to avoid numerical troubles */
1324  if( SCIPvarIsIntegral(solvars[i]) && SCIPisIntegral(scip, solval) )
1325  solval = SCIPround(scip, solval);
1326 
1327  /* save in the master problem variable's data the quota of the corresponding original variable */
1328  newvardata->data.mastervardata.origvars[j] = origvar;
1329  newvardata->data.mastervardata.origvals[j] = solval;
1330  /* save the quota in the original variable's data */
1331  SCIP_CALL( GCGoriginalVarAddMasterVar(origscip, origvar, *newvar, solval) );
1332  j++;
1333  }
1334  }
1335  if( trivialsol )
1336  {
1337  SCIP_VAR** pricingvars;
1338  int npricingvars;
1339 
1340  pricingvars = SCIPgetOrigVars(pricingscip);
1341  npricingvars = SCIPgetNOrigVars(pricingscip);
1342  for( j = 0; j < npricingvars; ++j )
1343  {
1344  SCIP_VAR* origvar;
1345  assert(GCGvarIsPricing(pricingvars[j]));
1346 
1347  origvar = GCGpricingVarGetOrigvars(pricingvars[j])[0];
1348  assert(origvar != NULL);
1349 
1350  assert(newvardata->data.mastervardata.origvars != NULL);
1351  assert(newvardata->data.mastervardata.origvals != NULL);
1352  assert(GCGvarIsOriginal(origvar));
1353  /* save in the master problem variable's data the quota of the corresponding original variable */
1354  newvardata->data.mastervardata.origvars[j] = origvar;
1355  newvardata->data.mastervardata.origvals[j] = 0.0;
1356  /* save the quota in the original variable's data */
1357  SCIP_CALL( GCGoriginalVarAddMasterVar(origscip, origvar, *newvar, 0.0) );
1358  }
1359  }
1360  assert(j == newvardata->data.mastervardata.norigvars);
1361 return SCIP_OKAY;
1362 }
1363 
1366  SCIP* scip,
1367  SCIP_VAR* var,
1368  SCIP_VAR** newvar
1370  )
1371 {
1372  SCIP_VARDATA* newvardata;
1373  int blocknr;
1374 
1375  blocknr = GCGvarGetBlock(var);
1376  assert( blocknr == -1 || blocknr == -2
1378 
1379  if( blocknr == -1 )
1380  {
1381  SCIPdebugMessage("var %s is in no block - copy it directly to the master\n", SCIPvarGetName(var));
1382  }
1383  else
1384  {
1385  SCIPdebugMessage("var %s is a linking variable - copy it directly to the master\n", SCIPvarGetName(var));
1386  }
1387 
1388  /* create vardata */
1389  SCIP_CALL( SCIPallocBlockMemory(scip, &newvardata) );
1390  newvardata->vartype = GCG_VARTYPE_MASTER;
1391  newvardata->blocknr = -1;
1392  newvardata->data.mastervardata.isray = FALSE;
1393  newvardata->data.mastervardata.isartificial = FALSE;
1394  newvardata->data.mastervardata.norigvars = 1;
1395 
1396  /* save corresoponding origvar */
1397  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(newvardata->data.mastervardata.origvars), 1) ); /*lint !e506*/
1398  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(newvardata->data.mastervardata.origvals), 1) ); /*lint !e506*/
1399  newvardata->data.mastervardata.origvars[0] = var;
1400  newvardata->data.mastervardata.origvals[0] = 1.0;
1401 
1402  /* create variable in the master problem */
1403  SCIP_CALL( SCIPcreateVar(scip, newvar, SCIPvarGetName(var),
1404  SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var), SCIPvarGetObj(var), SCIPvarGetType(var),
1405  TRUE, TRUE, NULL, NULL, gcgvardeltrans, NULL, newvardata) );
1406 
1407  return SCIP_OKAY;
1408 }
1409 
1412  SCIP* scip,
1413  SCIP_VAR** newvar,
1414  const char* name,
1415  SCIP_Real objcoef
1416  )
1417 {
1418  SCIP_VARDATA* newvardata;
1419 
1420  /* create vardata */
1421  SCIP_CALL( SCIPallocBlockMemory(scip, &newvardata) );
1422  newvardata->vartype = GCG_VARTYPE_MASTER;
1423  newvardata->blocknr = -1;
1424  newvardata->data.mastervardata.isray = FALSE;
1425  newvardata->data.mastervardata.norigvars = 0;
1426  newvardata->data.mastervardata.isartificial = TRUE;
1427 
1428  newvardata->data.mastervardata.origvars = NULL;
1429  newvardata->data.mastervardata.origvals = NULL;
1430 
1431  /* create variable in the master problem */
1432  SCIP_CALL( SCIPcreateVar(scip, newvar, name,
1433  0.0, SCIPinfinity(scip), objcoef, SCIP_VARTYPE_IMPLINT,
1434  TRUE, TRUE, NULL, NULL, gcgvardeltrans, NULL, newvardata) );
1435 
1436  return SCIP_OKAY;
1437 }
1438 
1439 /* adds the vardata to the auxiliary variable */
1441  SCIP* scip,
1442  SCIP_VAR* auxiliaryvar,
1443  int probnumber
1444  )
1445 {
1446  SCIP_VARDATA* newvardata;
1447 
1448  assert(scip != NULL);
1449  assert(auxiliaryvar != NULL);
1450 
1451  /* create data for the new variable in the master problem */
1452  SCIP_CALL( SCIPallocBlockMemory(scip, &newvardata) );
1453  newvardata->vartype = GCG_VARTYPE_MASTER;
1454  newvardata->blocknr = probnumber;
1455 
1456  /* store whether the variable represents a ray */
1457  newvardata->data.mastervardata.isray = FALSE;
1458 
1459  /* count number of non-zeros */
1460  newvardata->data.mastervardata.norigvars = 0;
1461 
1462  newvardata->data.mastervardata.origvars = NULL;
1463  newvardata->data.mastervardata.origvals = NULL;
1464 
1465  /* setting the variable data */
1466  SCIPvarSetData(auxiliaryvar, newvardata);
1467 
1468  /* setting the deltrans callback */
1469  SCIPvarSetDeltransData(auxiliaryvar, gcgvardeltrans);
1470 
1471  return SCIP_OKAY;
1472 }
1473 
1476  SCIP* scip,
1477  SCIP_VAR* var,
1478  SCIP_Longint creationNode
1479  )
1480 {
1481  SCIP_VARDATA* vardata;
1482  assert(scip != NULL);
1483  assert(var != NULL);
1484  assert(creationNode >= 0);
1485 
1486  vardata = SCIPvarGetData(var);
1487  vardata->creationnode = creationNode;
1488 }
1489 
1491 long long int GCGgetCreationNode(
1492  SCIP* scip,
1493  SCIP_VAR* var
1494  )
1495 {
1496  SCIP_VARDATA* vardata;
1497  assert(scip != NULL);
1498  assert(var != NULL);
1499 
1500  vardata = SCIPvarGetData(var);
1501  return vardata->creationnode;
1502 }
1503 
1506  SCIP* scip,
1507  SCIP_VAR* var,
1508  SCIP_Real time
1509  )
1510 {
1511  SCIP_VARDATA* vardata;
1512  assert(scip != NULL);
1513  assert(var != NULL);
1514  assert(time >= 0.0);
1515 
1516  vardata = SCIPvarGetData(var);
1517  vardata->creationtime = time;
1518 }
1519 
1522  SCIP* scip,
1523  SCIP_VAR* var
1524  )
1525 {
1526  SCIP_VARDATA* vardata;
1527  assert(scip != NULL);
1528  assert(var != NULL);
1529 
1530  vardata = SCIPvarGetData(var);
1531  return vardata->creationtime;
1532 }
1533 
1536  SCIP* scip,
1537  SCIP_VAR* var,
1538  SCIP_Longint rootredcostcall
1539  )
1540 {
1541  SCIP_VARDATA* vardata;
1542  assert(scip != NULL);
1543  assert(var != NULL);
1544  assert(rootredcostcall >= -1);
1545 
1546  vardata = SCIPvarGetData(var);
1547  vardata->rootredcostcall = rootredcostcall;
1548 }
1549 
1552  SCIP* scip,
1553  SCIP_VAR* var
1554  )
1555 {
1556  SCIP_VARDATA* vardata;
1557  assert(scip != NULL);
1558  assert(var != NULL);
1559 
1560  vardata = SCIPvarGetData(var);
1561  return vardata->rootredcostcall;
1562 }
1563 
1566  SCIP* scip,
1567  SCIP_VAR* var,
1568  SCIP_Longint iteration
1569  )
1570 {
1571  SCIP_VARDATA* vardata;
1572  assert(scip != NULL);
1573  assert(var != NULL);
1574  assert(iteration >= 0);
1575 
1576  vardata = SCIPvarGetData(var);
1577  vardata->iteration = iteration;
1578 }
1579 
1581 SCIP_Longint GCGgetIteration(
1582  SCIP* scip,
1583  SCIP_VAR* var
1584  )
1585 {
1586  SCIP_VARDATA* vardata;
1587  assert(scip != NULL);
1588  assert(var != NULL);
1589 
1590  vardata = SCIPvarGetData(var);
1591  return vardata->iteration;
1592 }
1593 
1596  SCIP* scip,
1597  SCIP_VAR* var,
1598  SCIP_Real gap
1599  )
1600 {
1601  SCIP_VARDATA* vardata;
1602  assert(scip != NULL);
1603  assert(var != NULL);
1604  assert(gap >= 0.0);
1605 
1606  vardata = SCIPvarGetData(var);
1607  vardata->gap = gap;
1608 }
1609 
1611 SCIP_Real GCGgetGap(
1612  SCIP* scip,
1613  SCIP_VAR* var
1614  )
1615 {
1616  SCIP_VARDATA* vardata;
1617  assert(scip != NULL);
1618  assert(var != NULL);
1619 
1620  vardata = SCIPvarGetData(var);
1621  return vardata->gap;
1622 }
1623 
1626  SCIP* scip,
1627  SCIP_VAR* var,
1628  SCIP_Real redcost
1629  )
1630 {
1631  SCIP_VARDATA* vardata;
1632  assert(scip != NULL);
1633  assert(var != NULL);
1634  assert(SCIPisLE(scip, redcost, 0.0));
1635 
1636  vardata = SCIPvarGetData(var);
1637  vardata->redcost = redcost;
1638 }
1639 
1641 SCIP_Real GCGgetRedcost(
1642  SCIP* scip,
1643  SCIP_VAR* var
1644  )
1645 {
1646  SCIP_VARDATA* vardata;
1647  assert(scip != NULL);
1648  assert(var != NULL);
1649 
1650  vardata = SCIPvarGetData(var);
1651  return vardata->redcost;
1652 }
1653 
1656  SCIP* scip,
1657  SCIP* origprob,
1658  SCIP_VAR* newvar,
1659  SCIP_Real redcost
1660  )
1661 {
1662  SCIP_Longint redcostcall;
1663  assert(scip != NULL);
1664  assert(GCGisMaster(scip));
1665  assert(origprob != NULL);
1666  assert(GCGisOriginal(origprob));
1667  assert(newvar != NULL);
1668 
1669  redcostcall = -1;
1670  GCGsetCreationNode(origprob, newvar, SCIPnodeGetNumber(SCIPgetCurrentNode(origprob)));
1671  GCGsetCreationTime(origprob, newvar, SCIPgetSolvingTime(scip));
1672 
1673  GCGsetRootRedcostCall(origprob, newvar, redcostcall);
1674  GCGsetIteration(origprob, newvar, SCIPgetNLPIterations(scip));
1675  GCGsetGap(origprob, newvar, MIN(SCIPgetGap(origprob), SCIPgetGap(scip))); /*lint !e666*/
1676  GCGsetRedcost(origprob, newvar, redcost);
1677 
1678 }
1679 
1684  SCIP* scip,
1685  FILE* file,
1686  SCIP_VAR* var
1687  )
1688 {
1689  int i;
1690  int blocknr;
1691  assert(GCGvarIsOriginal(var) || GCGvarIsMaster(var) || GCGvarIsPricing(var));
1692 
1693  blocknr = GCGvarGetBlock(var);
1694 
1695  if( GCGvarIsOriginal(var) )
1696  {
1697  SCIP_VAR** mastervars;
1698  SCIP_Real* mastervals;
1699  int nmastervars;
1700 
1701  if( GCGoriginalVarIsLinking(var) )
1702  {
1703  SCIP_VAR** pricingvars;
1704  int nblocks;
1705  int j;
1706  pricingvars = GCGlinkingVarGetPricingVars(var);
1707  nblocks = GCGlinkingVarGetNBlocks(var);
1708  SCIPinfoMessage(scip, file, "Variable %s (linking): %d block%s (", SCIPvarGetName(var), nblocks, nblocks == 1 ? "":"s" );
1709  /*lint --e{440}*/
1710  for( i = 0, j = 0; j < nblocks; ++i )
1711  {
1712  if( pricingvars[i] != NULL )
1713  {
1714  SCIPinfoMessage(scip, file, "%d ", i);
1715  ++j;
1716  }
1717  }
1718  SCIPinfoMessage(scip, file, ")\n");
1719  }
1720  else
1721  {
1722  SCIPinfoMessage(scip, file, "Variable %s (original): block %d\n", SCIPvarGetName(var), blocknr);
1723  }
1724 
1725  mastervars = GCGoriginalVarGetMastervars(var);
1726  mastervals = GCGoriginalVarGetMastervals(var);
1727  nmastervars = GCGoriginalVarGetNMastervars(var);
1728  SCIPinfoMessage(scip, file, "mastervars:");
1729  for( i = 0; i < nmastervars-1; i++ )
1730  {
1731  SCIPinfoMessage(scip, file, "%s (%g), ", SCIPvarGetName(mastervars[i]), mastervals[i]);
1732  }
1733  SCIPinfoMessage(scip, file, "%s (%g)\n", SCIPvarGetName(mastervars[nmastervars-1]), mastervals[nmastervars-1]);
1734  }
1735  else if( GCGvarIsPricing(var) )
1736  {
1737  SCIP_VAR** origvars;
1738  int norigvars;
1739 
1740  origvars = GCGpricingVarGetOrigvars(var);
1741  norigvars = GCGpricingVarGetNOrigvars(var);
1742 
1743  SCIPinfoMessage(scip, file, "Variable %s (pricing): block %d\n", SCIPvarGetName(var), blocknr);
1744  SCIPinfoMessage(scip, file, "origvars:");
1745  for( i = 0; i < norigvars-1; i++ )
1746  {
1747  SCIPinfoMessage(scip, file, "%s, ", SCIPvarGetName(origvars[i]));
1748  }
1749  SCIPinfoMessage(scip, file, "%s\n", SCIPvarGetName(origvars[norigvars-1]));
1750  }
1751  else if( GCGvarIsMaster(var) )
1752  {
1753  SCIP_VAR** origvars;
1754  int norigvars;
1755  SCIP_Real* origvals;
1756 
1757  origvars = GCGmasterVarGetOrigvars(var);
1758  norigvars = GCGmasterVarGetNOrigvars(var);
1759  origvals = GCGmasterVarGetOrigvals(var);
1760  SCIPinfoMessage(scip, file, "Variable %s (master): block %d\n", SCIPvarGetName(var), blocknr);
1761  SCIPinfoMessage(scip, file, "origvars:");
1762  for( i = 0; i < norigvars-1; i++ )
1763  {
1764  SCIPinfoMessage(scip, file, "%s (%g), ", SCIPvarGetName(origvars[i]), origvals[i]);
1765  }
1766  SCIPinfoMessage(scip, file, "%s (%g)\n", SCIPvarGetName(origvars[norigvars-1]), origvals[norigvars-1]);
1767  }
1768 }
SCIP_CONS ** GCGlinkingVarGetLinkingConss(SCIP_VAR *var)
Definition: gcgvar.c:753
SCIP_RETCODE GCGlinkingVarCreateMasterCons(SCIP *masterscip, int pricingprobnr, SCIP_VAR *origvar, SCIP_CONS **linkcons)
Definition: gcgvar.c:1185
void GCGsetRedcost(SCIP *scip, SCIP_VAR *var, SCIP_Real redcost)
Definition: gcgvar.c:1625
SCIP_Bool GCGvarIsOriginal(SCIP_VAR *var)
Definition: gcgvar.c:162
#define STARTMAXORIGVARS
Definition: gcgvar.c:46
SCIP_RETCODE GCGfreeOrigVarsData(SCIP *scip)
Definition: gcgvar.c:268
GCG interface methods.
SCIP_Bool GCGmasterVarIsRay(SCIP_VAR *var)
Definition: gcgvar.c:816
SCIP_Real * GCGoriginalVarGetCoefs(SCIP_VAR *var)
Definition: gcgvar.c:593
static SCIP_DECL_VARDELTRANS(gcgvardeltrans)
Definition: gcgvar.c:118
SCIP_Real GCGgetRedcost(SCIP *scip, SCIP_VAR *var)
Definition: gcgvar.c:1641
SCIP_Bool GCGisMasterVarInBlock(SCIP_VAR *mastervar, int block)
Definition: gcgvar.c:984
DEC_DECMODE GCGgetMasterDecompMode(SCIP *masterprob)
Definition: relax_gcg.c:5096
SCIP_RETCODE GCGcreateInitialMasterVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **newvar)
Definition: gcgvar.c:1365
SCIP_RETCODE GCGcreateOrigVarsData(SCIP *scip)
Definition: gcgvar.c:244
void GCGprintVar(SCIP *scip, FILE *file, SCIP_VAR *var)
Definition: gcgvar.c:1683
SCIP_RETCODE GCGoriginalVarRemoveMasterVar(SCIP *scip, SCIP_VAR *origvar, SCIP_VAR *var)
Definition: gcgvar.c:1068
SCIP_RETCODE GCGcreateMasterVar(SCIP *scip, SCIP *origscip, SCIP *pricingscip, SCIP_VAR **newvar, const char *varname, SCIP_Real objcoeff, SCIP_VARTYPE vartype, SCIP_Bool solisray, int prob, int nsolvars, SCIP_Real *solvals, SCIP_VAR **solvars, SCIP_Bool auxiliaryvar)
Definition: gcgvar.c:1209
SCIP_RETCODE GCGoriginalVarAddBlock(SCIP *scip, SCIP_VAR *var, int newblock, int nblocks, DEC_DECMODE mode)
Definition: gcgvar.c:692
SCIP_Bool GCGvarIsMaster(SCIP_VAR *var)
Definition: gcgvar.c:148
SCIP_RETCODE GCGorigVarCreateData(SCIP *scip, SCIP_VAR *var)
Definition: gcgvar.c:302
void GCGvarSetBlock(SCIP_VAR *var, int block)
Definition: gcgvar.c:950
int GCGoriginalVarGetNCoefs(SCIP_VAR *var)
Definition: gcgvar.c:609
SCIP_Longint GCGgetIteration(SCIP *scip, SCIP_VAR *var)
Definition: gcgvar.c:1581
int GCGgetNPricingprobs(SCIP *scip)
Definition: relax_gcg.c:3897
SCIP_RETCODE GCGoriginalVarAddCoef(SCIP *scip, SCIP_VAR *var, SCIP_Real val, SCIP_CONS *cons)
Definition: gcgvar.c:646
enum Decmode DEC_DECMODE
Definition: type_decomp.h:67
SCIP_VAR ** GCGpricingVarGetOrigvars(SCIP_VAR *var)
Definition: gcgvar.c:920
static SCIP_DECL_VARDELORIG(GCGvarDelOrig)
Definition: gcgvar.c:54
SCIP_RETCODE GCGaddDataAuxiliaryVar(SCIP *scip, SCIP_VAR *auxiliaryvar, int probnumber)
Definition: gcgvar.c:1440
various SCIP helper methods
SCIP_Real GCGgetCreationTime(SCIP *scip, SCIP_VAR *var)
Definition: gcgvar.c:1521
int GCGlinkingVarGetNBlocks(SCIP_VAR *var)
Definition: gcgvar.c:473
SCIP_Bool GCGmasterVarIsArtificial(SCIP_VAR *var)
Definition: gcgvar.c:831
SCIP_Bool GCGisLinkingVarInBlock(SCIP_VAR *var, int block)
Definition: gcgvar.c:965
SCIP_RETCODE GCGcopyPricingvarDataToMastervar(SCIP *scip, SCIP_VAR *pricingvar, SCIP_VAR *mastervar)
Definition: gcgvar.c:356
GCG relaxator.
SCIP_VAR ** GCGlinkingVarGetPricingVars(SCIP_VAR *var)
Definition: gcgvar.c:391
void GCGoriginalVarSetNCoefs(SCIP_VAR *var, int ncoefs)
Definition: gcgvar.c:625
SCIP_Bool GCGoriginalVarIsLinking(SCIP_VAR *var)
Definition: gcgvar.c:176
void GCGsetRootRedcostCall(SCIP *scip, SCIP_VAR *var, SCIP_Longint rootredcostcall)
Definition: gcgvar.c:1535
SCIP_Real * GCGmasterVarGetOrigvals(SCIP_VAR *var)
Definition: gcgvar.c:888
int GCGvarGetBlock(SCIP_VAR *var)
Definition: gcgvar.c:936
void GCGupdateVarStatistics(SCIP *scip, SCIP *origprob, SCIP_VAR *newvar, SCIP_Real redcost)
Definition: gcgvar.c:1655
void GCGsetCreationNode(SCIP *scip, SCIP_VAR *var, SCIP_Longint creationNode)
Definition: gcgvar.c:1475
void GCGlinkingVarSetPricingVar(SCIP_VAR *origvar, int pricingprobnr, SCIP_VAR *var)
Definition: gcgvar.c:408
SCIP_VAR * GCGpricingVarGetOriginalVar(SCIP_VAR *var)
Definition: gcgvar.c:489
#define STARTMAXMASTERVARS
Definition: gcgvar.c:45
SCIP_RETCODE GCGcreateArtificialVar(SCIP *scip, SCIP_VAR **newvar, const char *name, SCIP_Real objcoef)
Definition: gcgvar.c:1411
SCIP_Bool GCGvarIsPricing(SCIP_VAR *var)
Definition: gcgvar.c:133
SCIP_Longint GCGgetRootRedcostCall(SCIP *scip, SCIP_VAR *var)
Definition: gcgvar.c:1551
SCIP_Bool GCGoriginalVarIsTransVar(SCIP_VAR *var)
Definition: gcgvar.c:191
public methods for GCG variables
SCIP_RETCODE GCGlinkingVarGetBlocks(SCIP_VAR *var, int nblocks, int *blocks)
Definition: gcgvar.c:431
SCIP_Bool GCGisMaster(SCIP *scip)
Definition: misc.c:650
void GCGoriginalVarSetPricingVar(SCIP_VAR *var, SCIP_VAR *pricingvar)
Definition: gcgvar.c:224
int GCGpricingVarGetNOrigvars(SCIP_VAR *var)
Definition: gcgvar.c:904
SCIP_Bool GCGisOriginal(SCIP *scip)
Definition: misc.c:641
DEC_DECMODE GCGgetDecompositionMode(SCIP *scip)
Definition: relax_gcg.c:5075
SCIP_Real GCGgetGap(SCIP *scip, SCIP_VAR *var)
Definition: gcgvar.c:1611
void GCGsetCreationTime(SCIP *scip, SCIP_VAR *var, SCIP_Real time)
Definition: gcgvar.c:1505
int GCGmasterVarGetNOrigvars(SCIP_VAR *var)
Definition: gcgvar.c:846
SCIP_RETCODE GCGoriginalVarCreatePricingVar(SCIP *scip, SCIP_VAR *origvar, SCIP_VAR **var)
Definition: gcgvar.c:1113
void GCGlinkingVarSetLinkingCons(SCIP_VAR *var, SCIP_CONS *cons, int index)
Definition: gcgvar.c:771
long long int GCGgetCreationNode(SCIP *scip, SCIP_VAR *var)
Definition: gcgvar.c:1491
SCIP_RETCODE GCGoriginalVarAddMasterVar(SCIP *scip, SCIP_VAR *origvar, SCIP_VAR *var, SCIP_Real val)
Definition: gcgvar.c:1021
int GCGoriginalVarGetNMastervars(SCIP_VAR *var)
Definition: gcgvar.c:545
SCIP_RETCODE GCGlinkingVarCreatePricingVar(SCIP *pricingscip, int pricingprobnr, SCIP_VAR *origvar, SCIP_VAR **var)
Definition: gcgvar.c:1150
SCIP_VAR ** GCGmasterVarGetOrigvars(SCIP_VAR *var)
Definition: gcgvar.c:866
SCIP_VAR ** GCGoriginalVarGetMastervars(SCIP_VAR *var)
Definition: gcgvar.c:561
SCIP_CONS ** GCGoriginalVarGetMasterconss(SCIP_VAR *var)
Definition: gcgvar.c:677
SCIP_Bool GCGmasterVarIsLinking(SCIP_VAR *var)
Definition: gcgvar.c:793
SCIP_Real * GCGoriginalVarGetMastervals(SCIP_VAR *var)
Definition: gcgvar.c:577
SCIP_VAR * GCGoriginalVarGetPricingVar(SCIP_VAR *var)
Definition: gcgvar.c:206
void GCGsetGap(SCIP *scip, SCIP_VAR *var, SCIP_Real gap)
Definition: gcgvar.c:1595
void GCGsetIteration(SCIP *scip, SCIP_VAR *var, SCIP_Longint iteration)
Definition: gcgvar.c:1565
SCIP_RETCODE GCGpricingVarAddOrigVar(SCIP *scip, SCIP_VAR *pricingvar, SCIP_VAR *origvar)
Definition: gcgvar.c:508