Scippy

GCG

Branch-and-Price & Column Generation for Everyone

gcgcol.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 gcgcol.c
29  * @brief methods for working with gcg column structure
30  * @author Jonas Witt
31  *
32  * Various methods to work with gcg column structure
33  *
34  */
35 
36 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
37 
38 #include "pub_gcgcol.h"
39 
40 #include "gcg.h"
41 #include "scip/def.h"
42 #include "scip/scip.h"
43 #include "scip/cons_linear.h"
44 #include "scip_misc.h"
45 #include "blockmemshell/memory.h"
46 #include "pricer_gcg.h"
47 #include "sepa_master.h"
48 
49 #include <assert.h>
50 
51 /** create a gcg column */
52 SCIP_RETCODE GCGcreateGcgCol(
53  SCIP* pricingprob, /**< SCIP data structure (pricing problem) */
54  GCG_COL** gcgcol, /**< pointer to store gcg column */
55  int probnr, /**< number of corresponding pricing problem */
56  SCIP_VAR** vars, /**< (sorted) array of variables of corresponding pricing problem */
57  SCIP_Real* vals, /**< array of solution values (belonging to vars) */
58  int nvars, /**< number of variables */
59  SCIP_Bool isray, /**< is the column a ray? */
60  SCIP_Real redcost /**< last known reduced cost */
61  )
62 {
63  int i;
64  int nnonz;
65 
66  SCIP_CALL( SCIPallocBlockMemory(pricingprob, gcgcol) );
67 
68  (*gcgcol)->maxvars = SCIPcalcMemGrowSize(pricingprob, nvars);
69  SCIP_CALL( SCIPallocBlockMemoryArray(pricingprob, &((*gcgcol)->vars), (*gcgcol)->maxvars) );
70  SCIP_CALL( SCIPallocBlockMemoryArray(pricingprob, &((*gcgcol)->vals), (*gcgcol)->maxvars) );
71 
72  (*gcgcol)->pricingprob = pricingprob;
73  (*gcgcol)->probnr = probnr;
74  (*gcgcol)->isray = isray;
75  (*gcgcol)->redcost = redcost;
76  (*gcgcol)->age = 0;
77  (*gcgcol)->mastercoefs = NULL;
78  (*gcgcol)->mastercuts = NULL;
79  (*gcgcol)->linkvars = NULL;
80  (*gcgcol)->nmastercoefs = 0;
81  (*gcgcol)->nmastercuts = 0;
82  (*gcgcol)->maxmastercoefs = 0;
83  (*gcgcol)->maxmastercuts = 0;
84  (*gcgcol)->nlinkvars = 0;
85  (*gcgcol)->initcoefs = FALSE;
86 
87 
88  nnonz = 0;
89  for( i = 0; i < nvars; ++i )
90  {
91  SCIP_VAR* origvar;
92  SCIP_Real scalar;
93  SCIP_Real constant;
94  SCIP_Real origval;
95 
96  scalar = 1.0;
97  constant = 0.0;
98 
99  origvar = vars[i];
100 
101  /* todo: capture vars? */
102  SCIP_CALL( SCIPvarGetOrigvarSum(&origvar, &scalar, &constant) );
103 
104  assert( !SCIPisZero(pricingprob, scalar) );
105 
106  origval = (vals[i] - constant) / scalar;
107 
108  /* round origval if possible to avoid numerical troubles */
109  if( SCIPvarIsIntegral(origvar) && SCIPisFeasIntegral(pricingprob, origval) )
110  origval = SCIPround(pricingprob, origval);
111 
112  if( !SCIPisZero(pricingprob, origval) )
113  {
114  (*gcgcol)->vars[nnonz] = origvar;
115  (*gcgcol)->vals[nnonz] = origval;
116  ++nnonz;
117  }
118  }
119 
120  (*gcgcol)->nvars = nnonz;
121 
122  /* sort vars and vals array w.r.t. variable index */
123  SCIPsortPtrReal((void**)(*gcgcol)->vars, (double*)(*gcgcol)->vals, SCIPvarComp, nnonz);
124 
125 #ifndef NDEBUG
126  for( i = 1 ; i < (*gcgcol)->nvars; ++i )
127  {
128  assert( SCIPvarCompare((*gcgcol)->vars[i-1], (*gcgcol)->vars[i]) != 0 );
129  }
130 #endif
131  return SCIP_OKAY;
132 }
133 
134 /** free a gcg column */
136  GCG_COL** gcgcol /**< pointer to store gcg column */
137  )
138 {
139  assert(gcgcol != NULL);
140  assert(*gcgcol != NULL);
141 
142  /* todo: release vars? */
143  assert((*gcgcol)->nvars == 0 || (*gcgcol)->vars != NULL);
144  SCIPfreeBlockMemoryArrayNull((*gcgcol)->pricingprob, &(*gcgcol)->vars, (*gcgcol)->maxvars);
145  assert((*gcgcol)->nvars == 0 || (*gcgcol)->vals != NULL);
146  SCIPfreeBlockMemoryArrayNull((*gcgcol)->pricingprob, &(*gcgcol)->vals, (*gcgcol)->maxvars);
147  SCIPfreeBlockMemoryArrayNull((*gcgcol)->pricingprob, &(*gcgcol)->mastercoefs, (*gcgcol)->maxmastercoefs);
148  SCIPfreeBlockMemoryArrayNull((*gcgcol)->pricingprob, &(*gcgcol)->linkvars, (*gcgcol)->maxlinkvars);
149  SCIPfreeBlockMemoryArrayNull((*gcgcol)->pricingprob, &(*gcgcol)->mastercuts, (*gcgcol)->maxmastercuts);
150  SCIPfreeBlockMemory((*gcgcol)->pricingprob, gcgcol);
151 }
152 
153 /** create a gcg column from a solution to a pricing problem */
155  SCIP* pricingprob, /**< SCIP data structure (pricing problem) */
156  GCG_COL** gcgcol, /**< pointer to store gcg column */
157  int prob, /**< number of corresponding pricing problem */
158  SCIP_SOL* sol, /**< solution of pricing problem with index prob */
159  SCIP_Bool isray, /**< is column a ray? */
160  SCIP_Real redcost /**< last known reduced cost */
161 )
162 {
163  SCIP_VAR** solvars;
164  SCIP_VAR** colvars;
165 
166  SCIP_Real* colvals;
167 
168  int nsolvars;
169  int ncolvars;
170 
171  int i;
172 
173  solvars = SCIPgetOrigVars(pricingprob);
174  nsolvars = SCIPgetNOrigVars(pricingprob);
175 
176  SCIP_CALL( SCIPallocBufferArray(pricingprob, &colvars, nsolvars) );
177  SCIP_CALL( SCIPallocBufferArray(pricingprob, &colvals, nsolvars) );
178 
179  ncolvars = 0;
180 
181  for( i = 0; i < nsolvars; ++i )
182  {
183  SCIP_VAR* solvar;
184  SCIP_Real solval;
185 
186  solvar = solvars[i];
187  solval = SCIPgetSolVal(pricingprob, sol, solvar);
188 
189  /* round solval if possible to avoid numerical troubles */
190  if( SCIPvarIsIntegral(solvar) && SCIPisFeasIntegral(pricingprob, solval) )
191  solval = SCIPround(pricingprob, solval);
192 
193  if( SCIPisZero(pricingprob, solval) )
194  {
195  continue;
196  }
197 
198  colvars[ncolvars] = solvar;
199  colvals[ncolvars] = solval;
200  ++ncolvars;
201  }
202 
203  SCIP_CALL( GCGcreateGcgCol(pricingprob, gcgcol, prob, colvars, colvals, ncolvars, isray, redcost) );
204 
205  SCIPfreeBufferArray(pricingprob, &colvals);
206  SCIPfreeBufferArray(pricingprob, &colvars);
207 
208  return SCIP_OKAY;
209 }
210 
211 /** comparison method for sorting gcg columns by non-decreasing reduced cost */
212 SCIP_DECL_SORTPTRCOMP(GCGcolCompRedcost)
213 {
214  SCIP_Real redcost1;
215  SCIP_Real redcost2;
216 
217  redcost1 = GCGcolGetRedcost((GCG_COL*) elem1);
218  redcost2 = GCGcolGetRedcost((GCG_COL*) elem2);
219 
220  if( redcost1 < redcost2 )
221  return -1;
222  else if( redcost1 > redcost2 )
223  return +1;
224  else
225  return 0;
226 }
227 
228 /** comparison method for sorting gcg columns by non-increasing age */
229 SCIP_DECL_SORTPTRCOMP(GCGcolCompAge)
230 {
231  int age1;
232  int age2;
233 
234  age1 = GCGcolGetAge((GCG_COL*) elem1);
235  age2 = GCGcolGetAge((GCG_COL*) elem2);
236 
237  if( age1 < age2 )
238  return +1;
239  else if( age1 > age2 )
240  return -1;
241  else
242  return 0;
243 }
244 
245 /** comparison method for gcg columns. Returns TRUE iff columns are equal */
246 SCIP_Bool GCGcolIsEq(
247  GCG_COL* gcgcol1,
248  GCG_COL* gcgcol2
249 )
250 {
251  SCIP* pricingprob;
252 
253  SCIP_VAR** vars1;
254  SCIP_VAR** vars2;
255 
256  SCIP_Real* vals1;
257  SCIP_Real* vals2;
258 
259  int nvars1;
260  int nvars2;
261  int probnr1;
262  int probnr2;
263 
264  int i;
265 
266 
267  probnr1 = GCGcolGetProbNr(gcgcol1);
268  probnr2 = GCGcolGetProbNr(gcgcol2);
269 
270  if( probnr1 != probnr2 )
271  return FALSE;
272 
273  nvars1 = GCGcolGetNVars(gcgcol1);
274  nvars2 = GCGcolGetNVars(gcgcol2);
275 
276  if( nvars1 != nvars2 )
277  return FALSE;
278 
279  pricingprob = GCGcolGetPricingProb(gcgcol1);
280  vars1 = GCGcolGetVars(gcgcol1);
281  vars2 = GCGcolGetVars(gcgcol2);
282 
283  vals1 = GCGcolGetVals(gcgcol1);
284  vals2 = GCGcolGetVals(gcgcol2);
285 
286  for( i = 0; i < nvars1; ++i )
287  {
288  SCIP_VAR* var1;
289  SCIP_VAR* var2;
290 
291  SCIP_Real val1;
292  SCIP_Real val2;
293 
294  var1 = vars1[i];
295  var2 = vars2[i];
296 
297  val1 = vals1[i];
298  val2 = vals2[i];
299 
300  if( SCIPvarCompare(var1, var2) != 0 || !SCIPisEQ(pricingprob, val1, val2) )
301  {
302  return FALSE;
303  }
304  }
305 
306  return TRUE;
307 
308 }
309 
310 /** get pricing problem index of gcg column */
312  GCG_COL* gcgcol
313  )
314 {
315  return gcgcol->probnr;
316 }
317 
318 /** get pricing problem of gcg column */
320  GCG_COL* gcgcol
321  )
322 {
323  return gcgcol->pricingprob;
324 }
325 
326 /** get variables of gcg column */
327 SCIP_VAR** GCGcolGetVars(
328  GCG_COL* gcgcol
329  )
330 {
331  return gcgcol->vars;
332 }
333 
334 /** get values of gcg column */
335 SCIP_Real* GCGcolGetVals(
336  GCG_COL* gcgcol
337  )
338 {
339  return gcgcol->vals;
340 }
341 
342 /** get number of variables of gcg column */
344  GCG_COL* gcgcol
345  )
346 {
347  return gcgcol->nvars;
348 }
349 
350 /** is gcg column a ray? */
351 SCIP_Bool GCGcolIsRay(
352  GCG_COL* gcgcol
353  )
354 {
355  return gcgcol->isray;
356 }
357 
358 /** get reduced cost of gcg column */
360  GCG_COL* gcgcol
361  )
362 {
363  return gcgcol->redcost;
364 }
365 
366 /** get age of gcg column */
368  GCG_COL* gcgcol
369  )
370 {
371  return gcgcol->age;
372 }
373 
374 /** update reduced cost of variable and increase age */
376  GCG_COL* gcgcol, /**< gcg column structure */
377  SCIP_Real redcost, /**< new reduced cost */
378  SCIP_Bool growold /**< change age depending on reduced cost? */
379  )
380 {
381  gcgcol->redcost = redcost;
382 
383  if( !growold )
384  return;
385 
386  if( !SCIPisNegative(gcgcol->pricingprob, redcost) )
387  ++(gcgcol->age);
388  else
389  gcgcol->age = 0;
390 }
391 
392 /** get master coefficients of column */
394  GCG_COL* gcgcol /**< gcg column structure */
395  )
396 {
397  return gcgcol->mastercoefs;
398 }
399 
400 /** get number of master coefficients of column */
402  GCG_COL* gcgcol /**< gcg column structure */
403  )
404 {
405  return gcgcol->nmastercoefs;
406 }
407 
408 /** set master coefficients information of column */
409 SCIP_RETCODE GCGcolSetMastercoefs(
410  GCG_COL* gcgcol, /**< gcg column structure */
411  SCIP_Real* mastercoefs, /**< array of master coefficients */
412  int nmastercoefs /**< new number of master coefficients */
413  )
414 {
415  int i;
416 
417  SCIPdebugMessage("Col set master coefs\n");
418  assert(gcgcol->nmastercoefs == 0);
419  if( nmastercoefs == 0 )
420  return SCIP_OKAY;
421 
422  gcgcol->maxmastercoefs = SCIPcalcMemGrowSize(gcgcol->pricingprob, nmastercoefs);
423  SCIP_CALL( SCIPallocBlockMemoryArray(gcgcol->pricingprob, &(gcgcol->mastercoefs), gcgcol->maxmastercoefs) );
424 
425  for( i = 0; i < nmastercoefs; ++i )
426  {
427  SCIP_Real coef = mastercoefs[i];
428  gcgcol->mastercoefs[i] = coef;
429  }
430 
431  gcgcol->nmastercoefs = nmastercoefs;
432 
433  return SCIP_OKAY;
434 }
435 
436 /** set norm of column */
438  GCG_COL* gcgcol, /**< gcg column structure */
439  SCIP_Real norm /**< norm of column */
440  )
441 {
442  gcgcol->norm = norm;
443 }
444 
445 /** get norm of column */
447  SCIP* scip, /**< SCIP data structure */
448  GCG_COL* gcgcol /**< gcg column structure */
449  )
450 {
451  int i;
452  SCIP_Real norm;
453 
454  SCIP_Real* solvals;
455  SCIP_Real* mastercoefs;
456  int nmastercoefs;
457  SCIP_Real* mastercuts;
458  int nmastercuts;
459  int* linkvars;
460  int nlinkvars;
461 
462  assert(scip != NULL);
463  assert(gcgcol != NULL);
464 
465  solvals = GCGcolGetVals(gcgcol);
466  nmastercoefs = GCGcolGetNMastercoefs(gcgcol);
467  mastercoefs = GCGcolGetMastercoefs(gcgcol);
468  nmastercuts = GCGcolGetNMastercuts(gcgcol);
469  mastercuts = GCGcolGetMastercuts(gcgcol);
470  nmastercuts = GCGcolGetNMastercuts(gcgcol);
471  nlinkvars = GCGcolGetNLinkvars(gcgcol);
472  linkvars = GCGcolGetLinkvars(gcgcol);
473 
474  norm = 0.0;
475  /* compute scalar of master values of gcg columns */
476  for( i = 0; i < nmastercoefs; ++i )
477  {
478  if( !SCIPisZero(scip, mastercoefs[i]))
479  norm += SQR(mastercoefs[i]);
480  }
481 
482  for( i = 0; i < nmastercuts; ++i )
483  {
484  if( !SCIPisZero(scip, mastercuts[i]))
485  norm += SQR(mastercuts[i]);
486  }
487 
488 
489  for( i = 0; i < nlinkvars; ++i )
490  {
491  if( !SCIPisZero(scip, solvals[linkvars[i]]) )
492  norm += solvals[linkvars[i]];
493  }
494 
495  /* consider convexity constraint */
496  norm += 1.0;
497 
498  gcgcol->norm = norm;
499 }
500 
501 /** set master coefficients of column as initialized */
503  GCG_COL* gcgcol /**< gcg column structure */
504  )
505 {
506  assert(!gcgcol->initcoefs);
507  gcgcol->initcoefs = TRUE;
508  return SCIP_OKAY;
509 }
510 
511 /** return if master coefficients of column have been initialized */
513  GCG_COL* gcgcol /**< gcg column structure */
514  )
515 {
516  return gcgcol->initcoefs;
517 }
518 
519 /** get master coefficients of column */
521  GCG_COL* gcgcol /**< gcg column structure */
522  )
523 {
524  return gcgcol->linkvars;
525 }
526 
527 /** get number of master coefficients of column */
529  GCG_COL* gcgcol /**< gcg column structure */
530  )
531 {
532  return gcgcol->nlinkvars;
533 }
534 
535 /** set master coefficients information of column */
536 SCIP_RETCODE GCGcolSetLinkvars(
537  GCG_COL* gcgcol, /**< gcg column structure */
538  int* linkvars, /**< array of linking variable indices for gcgcol->var */
539  int nlinkvars /**< number of linking variables in gcgcol->var */
540  )
541 {
542  int i;
543 
544  assert(gcgcol->nlinkvars == 0);
545 
546  gcgcol->maxlinkvars = SCIPcalcMemGrowSize(gcgcol->pricingprob, nlinkvars);
547  SCIP_CALL( SCIPallocBlockMemoryArray(gcgcol->pricingprob, &(gcgcol->linkvars), gcgcol->maxlinkvars) );
548 
549  for( i = 0; i < nlinkvars; ++i )
550  {
551  gcgcol->linkvars[i] = linkvars[i];
552  }
553 
554  gcgcol->nlinkvars = nlinkvars;
555 
556  return SCIP_OKAY;
557 }
558 
559 /** get master cut coefficients of column */
561  GCG_COL* gcgcol /**< gcg column structure */
562  )
563 {
564  return gcgcol->mastercuts;
565 }
566 
567 /** get number of master cut coefficients of column */
569  GCG_COL* gcgcol /**< gcg column structure */
570  )
571 {
572  return gcgcol->nmastercuts;
573 }
574 
575 /** get norm of column */
576 SCIP_Real GCGcolGetNorm(
577  GCG_COL* gcgcol /**< gcg column structure */
578  )
579 {
580  return gcgcol->norm;
581 }
582 
583 /** update master cut coefficients information of column */
585  GCG_COL* gcgcol, /**< gcg column structure */
586  SCIP_Real* newmastercuts, /**< pointer to new array of master cut coefficients */
587  int nnewmastercuts /**< new number of master cut coefficients */
588  )
589 {
590  int i;
591  int newsize;
592 
593  i = gcgcol->nmastercuts + nnewmastercuts;
594  newsize = SCIPcalcMemGrowSize(gcgcol->pricingprob, i);
595  if( i > gcgcol->maxmastercuts )
596  {
597  SCIP_CALL( SCIPreallocBlockMemoryArray(GCGcolGetPricingProb(gcgcol), &(gcgcol->mastercuts),
598  gcgcol->maxmastercuts, newsize) );
599  }
600 
601  gcgcol->maxmastercuts = newsize;
602 
603  for( i = 0; i < nnewmastercuts; ++i )
604  {
605  gcgcol->mastercuts[gcgcol->nmastercuts] = newmastercuts[i];
606  ++(gcgcol->nmastercuts);
607  }
608 
609  return SCIP_OKAY;
610 }
611 
612 /** return solution value of variable in gcg column */
613 SCIP_Real GCGcolGetSolVal(
614  SCIP* scip, /**< SCIP data structure */
615  GCG_COL* gcgcol, /**< gcg column */
616  SCIP_VAR* var /**< variable */
617  )
618 {
619  SCIP_VAR** vars;
620  SCIP_Real* vals;
621  int nvars;
622  int pos;
623  SCIP_Bool found;
624 
625  vars = gcgcol->vars;
626  vals = gcgcol->vals;
627  nvars = gcgcol->nvars;
628 
629  found = SCIPsortedvecFindPtr((void**) vars, SCIPvarComp, (void*) var, nvars, &pos);
630 
631  if( !found )
632  {
633  return 0.0;
634  }
635 
636  return vals[pos];
637 }
638 
639 /** returns whether the col's age exceeds the age limit */
640 SCIP_Bool GCGcolIsAged(
641  GCG_COL* col, /**< col to check */
642  int agelimit /**< maximum age a col can reach before it is deleted from the pool, or -1 */
643  )
644 {
645  assert(col != NULL);
646 
647  return (agelimit >= 0 && col->age > agelimit);
648 }
649 
650 /** compute parallelism of column to dual objective */
652  SCIP* scip, /**< SCIP data structure */
653  GCG_COL* gcgcol /**< gcg column */
654 )
655 {
656  SCIP_Real para;
657 
658  int i;
659 
660  SCIP_CONS** masterconss;
661  SCIP_ROW** cuts;
662 
663  int prob;
664 
665  SCIP_Real* mastercoefs;
666  int nmastercoefs;
667  SCIP_Real* mastercuts;
668  int nmastercuts;
669 
670  SCIP_Real dualobjnorm;
671 
672 
673  assert(scip != NULL);
674  assert(gcgcol != NULL);
675 
676  prob = GCGcolGetProbNr(gcgcol);
677  nmastercoefs = GCGcolGetNMastercoefs(gcgcol);
678  mastercoefs = GCGcolGetMastercoefs(gcgcol);
679  nmastercuts = GCGcolGetNMastercuts(gcgcol);
680  mastercuts = GCGcolGetMastercuts(gcgcol);
681  masterconss = GCGgetMasterConss(GCGmasterGetOrigprob(scip));
682  cuts = GCGsepaGetMastercuts(scip);
683 
684  para = 0.0;
685 
686  dualobjnorm = 0.0;
687 
688  /* compute scalar of master values of gcg columns */
689  for( i = 0; i < nmastercoefs; ++i )
690  {
691  SCIP_Real lhs;
692  SCIP_Real rhs;
693 
694  lhs = SCIPgetLhsLinear(scip, masterconss[i]);
695  rhs = SCIPgetRhsLinear(scip, masterconss[i]);
696 
697  if( !SCIPisInfinity(scip, -lhs))
698  {
699  dualobjnorm += SQR(lhs);
700 
701  if( SCIPisPositive(scip, mastercoefs[i]) )
702  para += mastercoefs[i] * lhs;
703  }
704  else if( !SCIPisInfinity(scip, rhs) )
705  {
706  dualobjnorm += SQR(rhs);
707 
708  if(SCIPisNegative(scip, mastercoefs[i] ) )
709  para += mastercoefs[i] * rhs;
710  }
711  }
712 
713  for( i = 0; i < nmastercuts; ++i )
714  {
715  SCIP_Real lhs;
716  SCIP_Real rhs;
717 
718  if( !SCIProwIsInLP(cuts[i]) )
719  continue;
720 
721  lhs = SCIProwGetLhs(cuts[i]);
722  rhs = SCIProwGetRhs(cuts[i]);
723 
724  if( !SCIPisInfinity(scip, -lhs))
725  {
726  dualobjnorm += SQR(lhs);
727 
728  if( SCIPisPositive(scip, mastercuts[i]) )
729  para += mastercuts[i] * lhs;
730  }
731  else if( !SCIPisInfinity(scip, rhs) )
732  {
733  dualobjnorm += SQR(rhs);
734 
735  if(SCIPisNegative(scip, mastercuts[i] ) )
736  para += mastercuts[i] * rhs;
737  }
738  }
739 
740  for( i = 0; i < GCGgetNPricingprobs(GCGmasterGetOrigprob(scip)); ++i )
741  dualobjnorm += SQR(GCGgetNIdenticalBlocks(GCGmasterGetOrigprob(scip), i));
742 
743  para += SQR(GCGgetNIdenticalBlocks(GCGmasterGetOrigprob(scip), prob));
744 
745  assert(!SCIPisInfinity(scip, ABS(para)));
746 
747  dualobjnorm = SQRT(dualobjnorm);
748  assert(!SCIPisInfinity(scip, dualobjnorm));
749  assert(SCIPisPositive(scip, dualobjnorm));
750  assert(SCIPisPositive(scip, gcgcol->norm));
751 
752  para = para / (dualobjnorm * gcgcol->norm);
753 
754  return para;
755 }
756 
757 /** compute orthogonality of two gcg columns */
759  SCIP* scip, /**< SCIP data structure */
760  GCG_COL* gcgcol1, /**< first gcg column */
761  GCG_COL* gcgcol2 /**< second gcg column */
762 )
763 {
764  int i;
765  int j;
766  SCIP_Real para = 0.0;
767  SCIP_Real norm1 = 0.0;
768  SCIP_Real norm2 = 0.0;
769 
770  int prob1;
771 
772  SCIP_VAR** solvars1;
773  SCIP_Real* solvals1;
774  SCIP_Real* mastercoefs1;
775  int nmastercoefs1;
776  SCIP_Real* mastercuts1;
777  int nmastercuts1;
778  int* linkvars1;
779  int nlinkvars1;
780 
781  int prob2;
782 
783  SCIP_VAR** solvars2;
784  SCIP_Real* solvals2;
785  SCIP_Real* mastercoefs2;
786  SCIP_Real* mastercuts2;
787  int* linkvars2;
788  int nlinkvars2;
789 
790  assert(scip != NULL);
791  assert(gcgcol1 != NULL);
792  assert(gcgcol2 != NULL);
793 
794  prob1 = GCGcolGetProbNr(gcgcol1);
795  solvars1 = GCGcolGetVars(gcgcol1);
796  solvals1 = GCGcolGetVals(gcgcol1);
797  nmastercoefs1 = GCGcolGetNMastercoefs(gcgcol1);
798  mastercoefs1 = GCGcolGetMastercoefs(gcgcol1);
799  nmastercuts1 = GCGcolGetNMastercuts(gcgcol1);
800  mastercuts1 = GCGcolGetMastercuts(gcgcol1);
801  nlinkvars1 = GCGcolGetNLinkvars(gcgcol1);
802  linkvars1 = GCGcolGetLinkvars(gcgcol1);
803 
804  prob2 = GCGcolGetProbNr(gcgcol2);
805  solvars2 = GCGcolGetVars(gcgcol2);
806  solvals2 = GCGcolGetVals(gcgcol2);
807  mastercoefs2 = GCGcolGetMastercoefs(gcgcol2);
808  mastercuts2 = GCGcolGetMastercuts(gcgcol2);
809  nlinkvars2 = GCGcolGetNLinkvars(gcgcol2);
810  linkvars2 = GCGcolGetLinkvars(gcgcol2);
811 
812  /* compute scalar of master values of gcg columns */
813  for( i = 0; i < nmastercoefs1; ++i )
814  {
815  if( SCIPisPositive(scip, mastercoefs1[i] * mastercoefs2[i]) )
816  para += mastercoefs1[i] * mastercoefs2[i];
817 
818  if( SCIPisPositive(scip, mastercoefs1[i]) )
819  norm1 += SQR(mastercoefs1[i]);
820  if( SCIPisPositive(scip, mastercoefs2[i]) )
821  norm2 += SQR(mastercoefs2[i]);
822  }
823 
824  for( i = 0; i < nmastercuts1; ++i )
825  {
826  if( SCIPisPositive(scip, mastercuts1[i] * mastercuts2[i]) )
827  para += mastercuts1[i] * mastercuts2[i];
828 
829  if( SCIPisPositive(scip, mastercuts1[i]) )
830  norm1 += SQR(mastercuts1[i]);
831  if( SCIPisPositive(scip, mastercuts2[i]) )
832  norm2 += SQR(mastercuts2[i]);
833  }
834 
835  for( i = 0; i < nlinkvars1; ++i )
836  {
837  SCIP_VAR* linkvar1;
838  SCIP_Real linkval1;
839  linkvar1 = solvars1[linkvars1[i]];
840  linkval1 = solvals1[linkvars1[i]];
841 
842  norm1 += SQR(linkval1);
843 
844  for( j = 0; j < nlinkvars2; ++j )
845  {
846  SCIP_VAR* linkvar2;
847  SCIP_Real linkval2;
848  linkvar2 = solvars2[linkvars2[j]];
849  linkval2 = solvals2[linkvars2[j]];
850 
851  if( linkvar1 == linkvar2 )
852  {
853  para += linkval1 * linkval2;
854  break;
855  }
856  }
857  }
858 
859  for( i = 0; i < nlinkvars2; ++i )
860  {
861  SCIP_Real linkval2;
862 
863  linkval2 = solvals2[linkvars2[i]];
864 
865  norm2 += SQR(linkval2);
866  }
867 
868 
869  /* scalar for convexitiy constraints */
870  if( prob1 == prob2 )
871  para *= 1.0;
872 
873  norm1 *= 1.0;
874  norm2 *= 1.0;
875 
876  norm1 = SQRT(norm1);
877  norm2 = SQRT(norm2);
878 
879  assert(SCIPisPositive(scip, norm1) && SCIPisPositive(scip, norm2));
880 
881  para = para/(norm1*norm2);
882 
883  return 1.0 - para;
884 }
SCIP_RETCODE GCGcreateGcgCol(SCIP *pricingprob, GCG_COL **gcgcol, int probnr, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Bool isray, SCIP_Real redcost)
Definition: gcgcol.c:52
int * linkvars
Definition: struct_gcgcol.h:70
GCG interface methods.
void GCGcolComputeNorm(SCIP *scip, GCG_COL *gcgcol)
Definition: gcgcol.c:446
SCIP_Bool GCGcolIsRay(GCG_COL *gcgcol)
Definition: gcgcol.c:351
void GCGcolUpdateRedcost(GCG_COL *gcgcol, SCIP_Real redcost, SCIP_Bool growold)
Definition: gcgcol.c:375
int GCGcolGetNMastercuts(GCG_COL *gcgcol)
Definition: gcgcol.c:568
SCIP_Real GCGcolGetSolVal(SCIP *scip, GCG_COL *gcgcol, SCIP_VAR *var)
Definition: gcgcol.c:613
SCIP_Real GCGcolGetRedcost(GCG_COL *gcgcol)
Definition: gcgcol.c:359
int GCGcolGetNLinkvars(GCG_COL *gcgcol)
Definition: gcgcol.c:528
SCIP_Real * GCGcolGetMastercoefs(GCG_COL *gcgcol)
Definition: gcgcol.c:393
SCIP_Bool GCGcolIsAged(GCG_COL *col, int agelimit)
Definition: gcgcol.c:640
public methods for working with gcg columns
SCIP_RETCODE GCGcreateGcgColFromSol(SCIP *pricingprob, GCG_COL **gcgcol, int prob, SCIP_SOL *sol, SCIP_Bool isray, SCIP_Real redcost)
Definition: gcgcol.c:154
int probnr
Definition: struct_gcgcol.h:53
int maxlinkvars
Definition: struct_gcgcol.h:72
SCIP_Bool GCGcolIsEq(GCG_COL *gcgcol1, GCG_COL *gcgcol2)
Definition: gcgcol.c:246
SCIP_Bool GCGcolGetInitializedCoefs(GCG_COL *gcgcol)
Definition: gcgcol.c:512
int GCGgetNPricingprobs(SCIP *scip)
Definition: relax_gcg.c:3979
GCG variable pricer.
various SCIP helper methods
SCIP_Real * vals
Definition: struct_gcgcol.h:55
SCIP_Real * mastercoefs
Definition: struct_gcgcol.h:63
SCIP_Real redcost
Definition: struct_gcgcol.h:59
master separator
SCIP * pricingprob
Definition: struct_gcgcol.h:52
SCIP_Real GCGcolGetNorm(GCG_COL *gcgcol)
Definition: gcgcol.c:576
void GCGcolSetNorm(GCG_COL *gcgcol, SCIP_Real norm)
Definition: gcgcol.c:437
int GCGgetNIdenticalBlocks(SCIP *scip, int pricingprobnr)
Definition: relax_gcg.c:4053
SCIP_Real * GCGcolGetVals(GCG_COL *gcgcol)
Definition: gcgcol.c:335
SCIP_RETCODE GCGcolSetLinkvars(GCG_COL *gcgcol, int *linkvars, int nlinkvars)
Definition: gcgcol.c:536
SCIP_Bool initcoefs
Definition: struct_gcgcol.h:73
int * GCGcolGetLinkvars(GCG_COL *gcgcol)
Definition: gcgcol.c:520
SCIP * GCGmasterGetOrigprob(SCIP *scip)
SCIP_Real norm
Definition: struct_gcgcol.h:69
SCIP * GCGcolGetPricingProb(GCG_COL *gcgcol)
Definition: gcgcol.c:319
SCIP_VAR ** GCGcolGetVars(GCG_COL *gcgcol)
Definition: gcgcol.c:327
SCIP_Bool isray
Definition: struct_gcgcol.h:58
void GCGfreeGcgCol(GCG_COL **gcgcol)
Definition: gcgcol.c:135
SCIP_RETCODE GCGcolSetMastercoefs(GCG_COL *gcgcol, SCIP_Real *mastercoefs, int nmastercoefs)
Definition: gcgcol.c:409
SCIP_DECL_SORTPTRCOMP(GCGcolCompRedcost)
Definition: gcgcol.c:212
int nmastercuts
Definition: struct_gcgcol.h:67
int nmastercoefs
Definition: struct_gcgcol.h:64
int GCGcolGetNMastercoefs(GCG_COL *gcgcol)
Definition: gcgcol.c:401
SCIP_Real * mastercuts
Definition: struct_gcgcol.h:66
int GCGcolGetNVars(GCG_COL *gcgcol)
Definition: gcgcol.c:343
int GCGcolGetProbNr(GCG_COL *gcgcol)
Definition: gcgcol.c:311
int nlinkvars
Definition: struct_gcgcol.h:71
SCIP_CONS ** GCGgetMasterConss(SCIP *scip)
Definition: relax_gcg.c:4098
SCIP_ROW ** GCGsepaGetMastercuts(SCIP *scip)
Definition: sepa_master.c:438
int maxmastercoefs
Definition: struct_gcgcol.h:65
int maxmastercuts
Definition: struct_gcgcol.h:68
int GCGcolGetAge(GCG_COL *gcgcol)
Definition: gcgcol.c:367
SCIP_Real * GCGcolGetMastercuts(GCG_COL *gcgcol)
Definition: gcgcol.c:560
SCIP_RETCODE GCGcolUpdateMastercuts(GCG_COL *gcgcol, SCIP_Real *newmastercuts, int nnewmastercuts)
Definition: gcgcol.c:584
SCIP_Real GCGcolComputeDualObjPara(SCIP *scip, GCG_COL *gcgcol)
Definition: gcgcol.c:651
SCIP_RETCODE GCGcolSetInitializedCoefs(GCG_COL *gcgcol)
Definition: gcgcol.c:502
SCIP_Real GCGcolComputeOrth(SCIP *scip, GCG_COL *gcgcol1, GCG_COL *gcgcol2)
Definition: gcgcol.c:758
SCIP_VAR ** vars
Definition: struct_gcgcol.h:54