Scippy

SCIP

Solving Constraint Integer Programs

presol_dualinfer.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2016 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file presol_dualinfer.c
17  * @ingroup PRESOLVERS
18  * @brief dual inference presolver
19  * @author Dieter Weninger
20  *
21  * This presolver exploits dual informations on continuous variables for
22  * fixings of integer/continuous variables and side changes.
23  *
24  */
25 
26 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
27 
28 #include <stdio.h>
29 #include <assert.h>
30 #include <string.h>
31 
32 #include "scip/pub_matrix.h"
33 #include "scip/cons_linear.h"
34 #include "presol_dualinfer.h"
35 
36 #define PRESOL_NAME "dualinfer"
37 #define PRESOL_DESC "exploit dual informations for fixings and side changes"
38 #define PRESOL_PRIORITY -200 /**< priority of the presolver (>= 0: before, < 0: after constraint handlers) */
39 #define PRESOL_MAXROUNDS 0 /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */
40 #define PRESOL_TIMING SCIP_PRESOLTIMING_EXHAUSTIVE /* timing of the presolver (fast, medium, or exhaustive) */
41 #define MAX_LOOPS 7 /**< maximal number of dual bound strengthening loops */
42 
43 
44 /*
45  * Data structures
46  */
47 
48 
49 /** type of fixing direction */
51 {
52  FIXATLB = -1,
53  NOFIX = 0
54 };
56 
57 /** type of side change */
59 {
60  RHSTOLHS = -1,
61  NOCHANGE = 0,
63 };
64 typedef enum SideChange SIDECHANGE;
65 
66 
67 /*
68  * Local methods
69  */
70 
71 /** calculate minimal column activity from one continuous variable without one row */
72 static
74  SCIP* scip, /**< SCIP main data structure */
75  SCIP_MATRIX* matrix, /**< matrix containing the constraints */
76  int col, /**< column index */
77  int withoutrow, /**< exclude row index */
78  SCIP_Real* lbdual[2], /**< lower bounds of dual variables */
79  SCIP_Real* ubdual[2], /**< upper bounds of dual variables */
80  int part, /**< which of part of the dual variables is active */
81  SCIP_Real* lbdualbounds[2], /**< lower bounds of dual variables corresponding to primal variable bounds */
82  SCIP_Real* ubdualbounds[2] /**< upper bounds of dual variables corresponding to primal variable bounds */
83  )
84 {
85  SCIP_VAR* var;
86  SCIP_Real* valpnt;
87  int* colpnt;
88  int* colend;
89  SCIP_Real val;
90  SCIP_Real mincolactivity;
91  int row;
92  int p;
93 
94  assert(scip != NULL);
95  assert(matrix != NULL);
96  assert(lbdual[0] != NULL);
97  assert(ubdual[0] != NULL);
98  assert(lbdual[1] != NULL);
99  assert(ubdual[1] != NULL);
100  assert(lbdualbounds[0] != NULL);
101  assert(ubdualbounds[0] != NULL);
102  assert(lbdualbounds[1] != NULL);
103  assert(ubdualbounds[1] != NULL);
104 
105  var = SCIPmatrixGetVar(matrix, col);
106 
107  assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
108 
109  mincolactivity = 0;
110 
111  colpnt = SCIPmatrixGetColIdxPtr(matrix, col);
112  colend = colpnt + SCIPmatrixGetColNNonzs(matrix, col);
113  valpnt = SCIPmatrixGetColValPtr(matrix, col);
114 
115  for( ; colpnt < colend; colpnt++, valpnt++ )
116  {
117  row = *colpnt;
118  val = *valpnt;
119 
120  if( row == withoutrow )
121  {
122  if( SCIPmatrixIsRowRhsInfinity(matrix, row) )
123  continue;
124 
125  if( part == 0 )
126  {
127  /* consider second part */
128  val = -val;
129  p = 1;
130  }
131  else
132  {
133  /* consider first part */
134  p = 0;
135  }
136 
137  if( val > 0.0 )
138  {
139  assert(!SCIPisInfinity(scip, -lbdual[p][row]));
140  mincolactivity += val * lbdual[p][row];
141  }
142  else if( val < 0.0 )
143  {
144  assert(!SCIPisInfinity(scip, ubdual[p][row]));
145  mincolactivity += val * ubdual[p][row];
146  }
147  }
148  else
149  {
150  p = 0;
151 
152  do
153  {
154  if( val > 0.0 )
155  {
156  assert(!SCIPisInfinity(scip, -lbdual[p][row]));
157  mincolactivity += val * lbdual[p][row];
158  }
159  else if( val < 0.0 )
160  {
161  assert(!SCIPisInfinity(scip, ubdual[p][row]));
162  mincolactivity += val * ubdual[p][row];
163  }
164 
165  val = -val;
166  p++;
167  }
168  while ( !SCIPmatrixIsRowRhsInfinity(matrix, row) && p < 2 );
169  }
170  }
171 
172  /* consider variable bounds */
173  if( !SCIPisInfinity(scip, SCIPvarGetUbGlobal(var)) )
174  {
175  /* upper bound */
176  assert(!SCIPisInfinity(scip, ubdualbounds[0][col]));
177  mincolactivity += -ubdualbounds[0][col];
178  }
179  if( !SCIPisInfinity(scip, -SCIPvarGetLbGlobal(var)) )
180  {
181  /* lower bound */
182  assert(!SCIPisInfinity(scip, -lbdualbounds[1][col]));
183  mincolactivity += lbdualbounds[1][col];
184  }
185 
186  return mincolactivity;
187 }
188 
189 /** calculate minimal column activity from one continuous variable without one row for explicit bounds */
190 static
192  SCIP* scip, /**< SCIP main data structure */
193  SCIP_MATRIX* matrix, /**< matrix containing the constraints */
194  int col, /**< column index */
195  SCIP_Real* lbdual[2], /**< lower bounds of dual variables */
196  SCIP_Real* ubdual[2], /**< upper bounds of dual variables */
197  SCIP_Real* lbdualbounds[2], /**< lower bounds of dual variables corresponding to primal variable bounds */
198  SCIP_Real* ubdualbounds[2], /**< upper bounds of dual variables corresponding to primal variable bounds */
199  SCIP_Bool explicitub, /**< is this the explicit upper bound constraint */
200  SCIP_Bool explicitlb /**< is this the explicit lower bound constraint */
201  )
202 {
203  SCIP_VAR* var;
204  SCIP_Real* valpnt;
205  int* colpnt;
206  int* colend;
207  SCIP_Real val;
208  SCIP_Real mincolactivity;
209  int row;
210  int p;
211 
212  assert(scip != NULL);
213  assert(matrix != NULL);
214  assert(lbdual[0] != NULL);
215  assert(ubdual[0] != NULL);
216  assert(lbdual[1] != NULL);
217  assert(ubdual[1] != NULL);
218  assert(lbdualbounds[0] != NULL);
219  assert(ubdualbounds[0] != NULL);
220  assert(lbdualbounds[1] != NULL);
221  assert(ubdualbounds[1] != NULL);
222 
223  var = SCIPmatrixGetVar(matrix, col);
224 
225  assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
226  assert((explicitub && !explicitlb) || (!explicitub && explicitlb));
227 
228  mincolactivity = 0;
229 
230  colpnt = SCIPmatrixGetColIdxPtr(matrix, col);
231  colend = colpnt + SCIPmatrixGetColNNonzs(matrix, col);
232  valpnt = SCIPmatrixGetColValPtr(matrix, col);
233 
234  for(; (colpnt < colend); colpnt++, valpnt++ )
235  {
236  row = *colpnt;
237  val = *valpnt;
238 
239  p = 0;
240  do
241  {
242  if( val > 0.0 )
243  {
244  assert(!SCIPisInfinity(scip, -lbdual[p][row]));
245  mincolactivity += val * lbdual[p][row];
246  }
247  else if( val < 0.0 )
248  {
249  assert(!SCIPisInfinity(scip, ubdual[p][row]));
250  mincolactivity += val * ubdual[p][row];
251  }
252 
253  val = -val;
254  p++;
255  }
256  while ( !SCIPmatrixIsRowRhsInfinity(matrix, row) && p < 2 );
257  }
258 
259  /* consider variable bounds */
260  if( !explicitub && !SCIPisInfinity(scip, SCIPvarGetUbGlobal(var)) )
261  {
262  /* upper bound */
263  assert(!SCIPisInfinity(scip, ubdualbounds[0][col]));
264  mincolactivity += -ubdualbounds[0][col];
265  }
266  if( !explicitlb && !SCIPisInfinity(scip, -SCIPvarGetLbGlobal(var)) )
267  {
268  /* lower bound */
269  assert(!SCIPisInfinity(scip, -lbdualbounds[1][col]));
270  mincolactivity += lbdualbounds[1][col];
271  }
272 
273  return mincolactivity;
274 }
275 
276 /** calculate minimal/maximal column residual activities */
277 static
279  SCIP* scip, /**< SCIP main data structure */
280  SCIP_MATRIX* matrix, /**< matrix containing the constraints */
281  int col, /**< column index */
282  int row, /**< row index */
283  SCIP_Real val, /**< matrix coefficient */
284  SCIP_Real* lbdual[2], /**< lower bounds of dual variables */
285  SCIP_Real* ubdual[2], /**< upper bounds of dual variables */
286  int part, /**< which of part of the dual variables is active */
287  SCIP_Real* lbdualbounds[2], /**< lower bounds of dual variables corresponding to primal variable bounds */
288  SCIP_Real* ubdualbounds[2], /**< upper bounds of dual variables corresponding to primal variable bounds */
289  SCIP_Real* mincolact, /**< minimal column activities */
290  SCIP_Real* maxcolact, /**< maximal column activities */
291  int* maxcolactinf, /**< number of (positive) infinite contributions to maximal column activity */
292  int* mincolactinf, /**< number of (negative) infinite contributions to minimal column activity */
293  SCIP_Real* mincolresact /**< minimal column residual activity */
294  )
295 {
296  assert(scip != NULL);
297  assert(matrix != NULL);
298  assert(lbdual[0] != NULL);
299  assert(ubdual[0] != NULL);
300  assert(lbdual[1] != NULL);
301  assert(ubdual[1] != NULL);
302  assert(lbdualbounds[0] != NULL);
303  assert(ubdualbounds[0] != NULL);
304  assert(lbdualbounds[1] != NULL);
305  assert(ubdualbounds[1] != NULL);
306  assert(mincolact != NULL);
307  assert(maxcolact != NULL);
308  assert(maxcolactinf != NULL);
309  assert(mincolactinf != NULL);
310  assert(mincolresact != NULL);
311 
313 
314  if( !SCIPmatrixIsRowRhsInfinity(matrix, row) && part == 1 )
315  val = -val;
316 
317  if( val > 0.0 )
318  {
319  if( SCIPisInfinity(scip, -lbdual[part][row]) )
320  {
321  assert(mincolactinf[col] >= 1);
322  if( mincolactinf[col] == 1 )
323  *mincolresact = getMinColActWithoutRow(scip, matrix, col, row, lbdual, ubdual, part, lbdualbounds, ubdualbounds);
324  else
325  *mincolresact = -SCIPinfinity(scip);
326  }
327  else
328  {
329  if( mincolactinf[col] > 0 )
330  *mincolresact = -SCIPinfinity(scip);
331  else
332  *mincolresact = mincolact[col] - val * lbdual[part][row];
333  }
334  }
335  else if( val < 0.0 )
336  {
337  if( SCIPisInfinity(scip, ubdual[part][row]) )
338  {
339  assert(mincolactinf[col] >= 1);
340  if( mincolactinf[col] == 1 )
341  *mincolresact = getMinColActWithoutRow(scip, matrix, col, row, lbdual, ubdual, part, lbdualbounds, ubdualbounds);
342  else
343  *mincolresact = -SCIPinfinity(scip);
344  }
345  else
346  {
347  if( mincolactinf[col] > 0 )
348  *mincolresact = -SCIPinfinity(scip);
349  else
350  *mincolresact = mincolact[col] - val * ubdual[part][row];
351  }
352  }
353 }
354 
355 /** calculate minimal/maximal column residual activities of explicit bounds */
356 static
358  SCIP* scip, /**< SCIP main data structure */
359  SCIP_MATRIX* matrix, /**< matrix containing the constraints */
360  int col, /**< column index */
361  SCIP_Real* lbdual[2], /**< lower bounds of dual variables */
362  SCIP_Real* ubdual[2], /**< upper bounds of dual variables */
363  SCIP_Real* lbdualbounds[2], /**< lower bounds of dual variables corresponding to primal variable bounds */
364  SCIP_Real* ubdualbounds[2], /**< upper bounds of dual variables corresponding to primal variable bounds */
365  SCIP_Bool explicitub, /**< is this the constraint for the explicit upper bound */
366  SCIP_Bool explicitlb, /**< is this the constraint for the explicit lower bound */
367  SCIP_Real* mincolact, /**< minimal column activities */
368  SCIP_Real* maxcolact, /**< maximal column activities */
369  int* maxcolactinf, /**< number of (positive) infinite contributions to maximal column activity */
370  int* mincolactinf, /**< number of (negative) infinite contributions to minimal column activity */
371  SCIP_Real* mincolresact /**< minimal column residual activity */
372  )
373 {
374  SCIP_VAR* var;
375 
376  assert(scip != NULL);
377  assert(matrix != NULL);
378  assert(lbdual[0] != NULL);
379  assert(ubdual[0] != NULL);
380  assert(lbdual[1] != NULL);
381  assert(ubdual[1] != NULL);
382  assert(mincolact != NULL);
383  assert(maxcolact != NULL);
384  assert(maxcolactinf != NULL);
385  assert(mincolactinf != NULL);
386  assert(mincolresact != NULL);
387 
388  var = SCIPmatrixGetVar(matrix, col);
389 
390  assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
391  assert((explicitub && !explicitlb) || (!explicitub && explicitlb));
392 
393  if( explicitub )
394  {
395  if( !SCIPisInfinity(scip, SCIPvarGetUbGlobal(var)) )
396  {
397  /* -1.0 * x >= -ub */
398  if( SCIPisInfinity(scip, ubdualbounds[0][col]) )
399  {
400  assert(mincolactinf[col] >= 1);
401 
402  if( mincolactinf[col] == 1 )
403  *mincolresact = getMinColActWithoutBound(scip, matrix, col, lbdual, ubdual, lbdualbounds, ubdualbounds, explicitub, explicitlb);
404  else
405  *mincolresact = -SCIPinfinity(scip);
406  }
407  else
408  {
409  if( mincolactinf[col] > 0 )
410  *mincolresact = -SCIPinfinity(scip);
411  else
412  *mincolresact = mincolact[col] + ubdualbounds[0][col];
413  }
414  }
415  }
416  else
417  {
418  if( !SCIPisInfinity(scip, -SCIPvarGetLbGlobal(var)) )
419  {
420  /* 1.0 * y >= lb */
421  if( SCIPisInfinity(scip, -lbdualbounds[1][col]) )
422  {
423  assert(mincolactinf[col] >= 1);
424  if( mincolactinf[col] == 1 )
425  *mincolresact = getMinColActWithoutBound(scip, matrix, col, lbdual, ubdual, lbdualbounds, ubdualbounds, explicitub, explicitlb);
426  else
427  *mincolresact = -SCIPinfinity(scip);
428  }
429  else
430  {
431  if( mincolactinf[col] > 0 )
432  *mincolresact = -SCIPinfinity(scip);
433  else
434  *mincolresact = mincolact[col] - lbdualbounds[1][col];
435  }
436  }
437  }
438 }
439 
440 
441 /** calculate minimal/maximal column activity on continuous variables */
442 static
444  SCIP* scip, /**< SCIP main data structure */
445  SCIP_MATRIX* matrix, /**< matrix containing the constraints */
446  int startcol, /**< start column index */
447  int stopcol, /**< stop column index */
448  SCIP_Real* lbdual[2], /**< lower bounds of dual variables */
449  SCIP_Real* ubdual[2], /**< upper bounds of dual variables */
450  SCIP_Real* lbdualbounds[2], /**< lower bounds of dual variables corresponding to primal variable bounds */
451  SCIP_Real* ubdualbounds[2], /**< upper bounds of dual variables corresponding to primal variable bounds */
452  SCIP_Real* mincolact, /**< minimal column activities */
453  SCIP_Real* maxcolact, /**< maximal column activities */
454  int* maxcolactinf, /**< number of (positive) infinite contributions to maximal column activity */
455  int* mincolactinf /**< number of (negative) infinite contributions to minimal column activity */
456  )
457 {
458  SCIP_VAR* var;
459  SCIP_Real* valpnt;
460  int* colpnt;
461  int* colend;
462  SCIP_Real val;
463  int row;
464  int c;
465  int part;
466 
467  assert(scip != NULL);
468  assert(matrix != NULL);
469  assert(lbdual[0] != NULL);
470  assert(ubdual[0] != NULL);
471  assert(lbdual[1] != NULL);
472  assert(ubdual[1] != NULL);
473  assert(lbdualbounds[0] != NULL);
474  assert(ubdualbounds[0] != NULL);
475  assert(lbdualbounds[1] != NULL);
476  assert(ubdualbounds[1] != NULL);
477  assert(mincolact != NULL);
478  assert(maxcolact != NULL);
479  assert(maxcolactinf != NULL);
480  assert(mincolactinf != NULL);
481 
482  for( c = startcol; c < stopcol; c++ )
483  {
484  mincolact[c] = 0;
485  maxcolact[c] = 0;
486  maxcolactinf[c] = 0;
487  mincolactinf[c] = 0;
488 
489  colpnt = SCIPmatrixGetColIdxPtr(matrix, c);
490  colend = colpnt + SCIPmatrixGetColNNonzs(matrix, c);
491  valpnt = SCIPmatrixGetColValPtr(matrix, c);
492  var = SCIPmatrixGetVar(matrix, c);
493 
494  /* calculate column activities */
495  for( ; colpnt < colend; colpnt++, valpnt++ )
496  {
497  row = *colpnt;
498  val = *valpnt;
499  part = 0;
500 
501  do
502  {
503  if( val > 0 )
504  {
505  if(SCIPisInfinity(scip, ubdual[part][row]))
506  maxcolactinf[c]++;
507  else
508  maxcolact[c] += val * ubdual[part][row];
509 
510  if(SCIPisInfinity(scip, -lbdual[part][row]))
511  mincolactinf[c]++;
512  else
513  mincolact[c] += val * lbdual[part][row];
514  }
515  else if( val < 0.0 )
516  {
517  if(SCIPisInfinity(scip, -lbdual[part][row]))
518  maxcolactinf[c]++;
519  else
520  maxcolact[c] += val * lbdual[part][row];
521 
522  if(SCIPisInfinity(scip, ubdual[part][row]))
523  mincolactinf[c]++;
524  else
525  mincolact[c] += val * ubdual[part][row];
526  }
527 
528  val = -val;
529  part++;
530 
531  }
532  while( !SCIPmatrixIsRowRhsInfinity(matrix, row) && part < 2 );
533  }
534 
536  {
537  /* consider variable bounds */
538  if( !SCIPisInfinity(scip, SCIPvarGetUbGlobal(var)) )
539  {
540  /* upper bound */
541  if(SCIPisInfinity(scip, -lbdualbounds[0][c]))
542  maxcolactinf[c]++;
543  else
544  maxcolact[c] += -lbdualbounds[0][c];
545 
546  if(SCIPisInfinity(scip, ubdualbounds[0][c]))
547  mincolactinf[c]++;
548  else
549  mincolact[c] += -ubdualbounds[0][c];
550  }
551 
552  if( !SCIPisInfinity(scip, -SCIPvarGetLbGlobal(var)) )
553  {
554  /* lower bound */
555 
556  if(SCIPisInfinity(scip, ubdualbounds[1][c]))
557  maxcolactinf[c]++;
558  else
559  maxcolact[c] += ubdualbounds[1][c];
560 
561  if(SCIPisInfinity(scip, -lbdualbounds[1][c]))
562  mincolactinf[c]++;
563  else
564  mincolact[c] += lbdualbounds[1][c];
565  }
566  }
567 
568  /* update column activities */
569  if( mincolactinf[c] > 0 )
570  mincolact[c] = -SCIPinfinity(scip);
571  if( maxcolactinf[c] > 0 )
572  maxcolact[c] = SCIPinfinity(scip);
573  }
574 }
575 
576 
577 /** update bounds on dual variables */
578 static
580  SCIP* scip, /**< SCIP main data structure */
581  SCIP_MATRIX* matrix, /**< matrix containing the constraints */
582  SCIP_Real objval, /**< objective function value */
583  SCIP_Real val, /**< matrix coefficient */
584  int row, /**< row index */
585  SCIP_Real mincolresact, /**< minimal column residual activity */
586  SCIP_Real* lbdual[2], /**< dual lower bounds (ranged, equality) */
587  SCIP_Real* ubdual[2], /**< dual upper bounds (ranged, equatity)*/
588  int part, /**< which of part of the dual variables is active */
589  int* boundchanges, /**< number of bound changes */
590  SCIP_Bool* updateinfcnt /**< flag indicating to update infinity counters */
591  )
592 {
593  SCIP_Real newlbdual;
594  SCIP_Real newubdual;
595 
596  assert(scip != NULL);
597  assert(matrix != NULL);
598  assert(lbdual[0] != NULL);
599  assert(ubdual[0] != NULL);
600  assert(lbdual[1] != NULL);
601  assert(ubdual[1] != NULL);
602  assert(boundchanges != NULL);
603  assert(updateinfcnt != NULL);
604 
605  *updateinfcnt = FALSE;
606 
607  if( !SCIPmatrixIsRowRhsInfinity(matrix, row) && part == 1 )
608  val = -val;
609 
610  if( val > 0 )
611  {
612  if( !SCIPisInfinity(scip, mincolresact) && !SCIPisInfinity(scip, -mincolresact) )
613  {
614  newubdual = (objval - mincolresact) / val;
615  if( newubdual < ubdual[part][row] )
616  {
617  if( SCIPisInfinity(scip, ubdual[part][row]) )
618  *updateinfcnt = TRUE;
619 
620  ubdual[part][row] = newubdual;
621  (*boundchanges)++;
622  }
623  }
624  }
625  else if( val < 0 )
626  {
627  if( !SCIPisInfinity(scip, mincolresact) && !SCIPisInfinity(scip, -mincolresact) )
628  {
629  newlbdual = (objval - mincolresact) / val;
630  if( newlbdual > lbdual[part][row] )
631  {
632  if( SCIPisInfinity(scip, -lbdual[part][row]) )
633  *updateinfcnt = TRUE;
634 
635  lbdual[part][row] = newlbdual;
636  (*boundchanges)++;
637  }
638  }
639  }
640 }
641 
642 /** update bounds on dual variables of explicit bounds */
643 static
645  SCIP* scip, /**< SCIP main data structure */
646  SCIP_MATRIX* matrix, /**< matrix containing the constraints */
647  SCIP_Real objval, /**< objective function value */
648  int col, /**< column index */
649  SCIP_Real mincolresact, /**< minimal column residual activity */
650  SCIP_Real* lbdualbounds[2], /**< lower bounds of dual variables corresponding to variable bounds */
651  SCIP_Real* ubdualbounds[2], /**< upper bounds of dual variables corresponding to variable bounds */
652  SCIP_Bool explicitub, /**< flag indicating if explicit upper bound is active */
653  SCIP_Bool explicitlb, /**< flag indicating if explicit lower bound is active */
654  int* boundchanges, /**< number of bound changes */
655  SCIP_Bool* updateinfcnt /**< flag indicating to update infinity counters */
656  )
657 {
658  SCIP_VAR* var;
659  SCIP_Real newlbdual;
660  SCIP_Real newubdual;
661 
662  assert(scip != NULL);
663  assert(matrix != NULL);
664  assert(lbdualbounds[0] != NULL);
665  assert(ubdualbounds[0] != NULL);
666  assert(lbdualbounds[1] != NULL);
667  assert(ubdualbounds[1] != NULL);
668  assert(boundchanges != NULL);
669  assert(updateinfcnt != NULL);
670 
671  assert((explicitub && !explicitlb) || (!explicitub && explicitlb));
672 
673  var = SCIPmatrixGetVar(matrix, col);
674  *updateinfcnt = FALSE;
675 
676  if( explicitlb )
677  {
678  if( !SCIPisInfinity(scip, -SCIPvarGetLbGlobal(var)) )
679  {
680  if( !SCIPisInfinity(scip, mincolresact) && !SCIPisInfinity(scip, -mincolresact) )
681  {
682  newubdual = (objval - mincolresact);
683  if( newubdual < ubdualbounds[1][col] )
684  {
685  if( SCIPisInfinity(scip, ubdualbounds[1][col]) )
686  *updateinfcnt = TRUE;
687 
688  ubdualbounds[1][col] = newubdual;
689  (*boundchanges)++;
690  }
691  }
692  }
693  }
694  else
695  {
696  if( !SCIPisInfinity(scip, SCIPvarGetUbGlobal(var)) )
697  {
698  if( !SCIPisInfinity(scip, mincolresact) && !SCIPisInfinity(scip, -mincolresact) )
699  {
700  newlbdual = -(objval - mincolresact);
701  if( newlbdual > lbdualbounds[0][col] )
702  {
703  if( SCIPisInfinity(scip, -lbdualbounds[0][col]) )
704  *updateinfcnt = TRUE;
705 
706  lbdualbounds[0][col] = newlbdual;
707  (*boundchanges)++;
708  }
709  }
710  }
711  }
712 }
713 
714 /** update minimal/maximal column activity infinity counters */
715 static
717  SCIP* scip, /**< SCIP main data structure */
718  SCIP_MATRIX* matrix, /**< matrix containing the constraints */
719  SCIP_Real val, /**< matrix coefficient */
720  int row, /**< row index */
721  SCIP_Real* lbdual[2], /**< lower bounds of dual variables */
722  SCIP_Real* ubdual[2], /**< upper bounds of dual variables */
723  SCIP_Real* lbdualbounds[2], /**< lower bounds of dual variables corresponding to primal variable bounds */
724  SCIP_Real* ubdualbounds[2], /**< upper bounds of dual variables corresponding to primal variable bounds */
725  int part, /**< which part of the dual variables is active */
726  SCIP_Real* mincolact, /**< minimal column activities */
727  SCIP_Real* maxcolact, /**< maximal column activities */
728  int* maxcolactinf, /**< number of (positive) infinity contributions to maximal column activity */
729  int* mincolactinf /**< number of (negative) infinity contributions to minimal column activity */
730  )
731 {
732  SCIP_Real* valpnt;
733  int* rowpnt;
734  int* rowend;
735  SCIP_Real aij;
736  int c;
737 
738  assert(scip != NULL);
739  assert(matrix != NULL);
740  assert(lbdual[0] != NULL);
741  assert(ubdual[0] != NULL);
742  assert(lbdual[1] != NULL);
743  assert(ubdual[1] != NULL);
744  assert(lbdualbounds[0] != NULL);
745  assert(ubdualbounds[0] != NULL);
746  assert(lbdualbounds[1] != NULL);
747  assert(ubdualbounds[1] != NULL);
748  assert(mincolact != NULL);
749  assert(maxcolact != NULL);
750  assert(maxcolactinf != NULL);
751  assert(mincolactinf != NULL);
752 
753  rowpnt = SCIPmatrixGetRowIdxPtr(matrix, row);
754  rowend = rowpnt + SCIPmatrixGetRowNNonzs(matrix, row);
755  valpnt = SCIPmatrixGetRowValPtr(matrix, row);
756 
757  if( !SCIPmatrixIsRowRhsInfinity(matrix, row) && part == 1 )
758  val = -val;
759 
760  /* look at all columns entries present within row and update the corresponding infinity counters.
761  * if one counter gets to zero, then calculate this column activity completely new */
762  if( val > 0 )
763  {
764  /* finite upper bound change */
765  for(; (rowpnt < rowend); rowpnt++, valpnt++ )
766  {
767  c = *rowpnt;
768  aij = *valpnt;
769 
770  if( aij > 0 )
771  {
772  assert(maxcolactinf[c] > 0);
773  maxcolactinf[c]--;
774 
775  if( maxcolactinf[c] == 0 )
776  calcColActivity(scip, matrix, c, c+1, lbdual, ubdual, lbdualbounds, ubdualbounds, mincolact, maxcolact, maxcolactinf, mincolactinf);
777  }
778  else if( aij < 0 )
779  {
780  assert(mincolactinf[c] > 0);
781  mincolactinf[c]--;
782 
783  if( mincolactinf[c] == 0 )
784  calcColActivity(scip, matrix, c, c+1, lbdual, ubdual, lbdualbounds, ubdualbounds, mincolact, maxcolact, maxcolactinf, mincolactinf);
785  }
786  }
787  }
788  else if( val < 0 )
789  {
790  /* finite lower bound change */
791  for(; (rowpnt < rowend); rowpnt++, valpnt++ )
792  {
793  c = *rowpnt;
794  aij = *valpnt;
795 
796  if( aij > 0 )
797  {
798  assert(mincolactinf[c] > 0);
799  mincolactinf[c]--;
800 
801  if( mincolactinf[c] == 0 )
802  calcColActivity(scip, matrix, c, c+1, lbdual, ubdual, lbdualbounds, ubdualbounds, mincolact, maxcolact, maxcolactinf, mincolactinf);
803  }
804  else if( aij < 0 )
805  {
806  assert(maxcolactinf[c] > 0);
807  maxcolactinf[c]--;
808 
809  if( maxcolactinf[c] == 0 )
810  calcColActivity(scip, matrix, c, c+1, lbdual, ubdual, lbdualbounds, ubdualbounds, mincolact, maxcolact, maxcolactinf, mincolactinf);
811  }
812  }
813  }
814 }
815 
816 /** update minimal/maximal column activity infinity counters for explicit bounds */
817 static
819  SCIP* scip, /**< SCIP main data structure */
820  SCIP_MATRIX* matrix, /**< matrix containing the constraints */
821  int col, /**< column index */
822  SCIP_Real* lbdual[2], /**< lower bounds of dual variables */
823  SCIP_Real* ubdual[2], /**< upper bounds of dual variables */
824  SCIP_Real* lbdualbounds[2], /**< lower bounds of dual variables corresponding to variable bounds */
825  SCIP_Real* ubdualbounds[2], /**< upper bounds of dual variables corresponding to variable bounds */
826  SCIP_Bool explicitub, /**< flag indicating if explicit upper bound is active */
827  SCIP_Bool explicitlb, /**< flag indicating if explicit lower bound is active */
828  SCIP_Real* mincolact, /**< minimal column activities */
829  SCIP_Real* maxcolact, /**< maximal column activities */
830  int* maxcolactinf, /**< number of (positive) infinity contributions to maximal column activity */
831  int* mincolactinf /**< number of (negative) infinity contributions to minimal column activity */
832  )
833 {
834  SCIP_VAR* var;
835 
836  assert(scip != NULL);
837  assert(matrix != NULL);
838  assert(lbdual[0] != NULL);
839  assert(ubdual[0] != NULL);
840  assert(lbdual[1] != NULL);
841  assert(ubdual[1] != NULL);
842  assert(lbdualbounds[0] != NULL);
843  assert(ubdualbounds[0] != NULL);
844  assert(lbdualbounds[1] != NULL);
845  assert(ubdualbounds[1] != NULL);
846  assert(mincolact != NULL);
847  assert(maxcolact != NULL);
848  assert(maxcolactinf != NULL);
849  assert(mincolactinf != NULL);
850 
851  assert((explicitub && !explicitlb) || (!explicitub && explicitlb));
852 
853  var = SCIPmatrixGetVar(matrix, col);
854 
855  if( explicitlb )
856  {
857  if( !SCIPisInfinity(scip, -SCIPvarGetLbGlobal(var)) )
858  {
859  /* finite upper bound change */
860  assert(maxcolactinf[col] > 0);
861  maxcolactinf[col]--;
862 
863  if( maxcolactinf[col] == 0 )
864  calcColActivity(scip, matrix, col, col+1, lbdual, ubdual, lbdualbounds, ubdualbounds, mincolact, maxcolact, maxcolactinf, mincolactinf);
865  }
866  }
867  else
868  {
869  if( !SCIPisInfinity(scip, SCIPvarGetUbGlobal(var)) )
870  {
871  /* finite lower bound change */
872  assert(maxcolactinf[col] > 0);
873  maxcolactinf[col]--;
874 
875  if( maxcolactinf[col] == 0 )
876  calcColActivity(scip, matrix, col, col+1, lbdual, ubdual, lbdualbounds, ubdualbounds, mincolact, maxcolact, maxcolactinf, mincolactinf);
877  }
878  }
879 }
880 
881 
882 /** dual bound strengthening */
883 static
885  SCIP* scip, /**< SCIP main data structure */
886  SCIP_MATRIX* matrix, /**< matrix containing the constraints */
887  FIXINGDIRECTION* varstofix, /**< array holding information for later upper/lower bound fixing */
888  int* npossiblefixings, /**< number of possible fixings */
889  SIDECHANGE* sidestochange, /**< array holding if this is an implied equality */
890  int* npossiblesidechanges/**< number of possible equality changes */
891  )
892 {
893  SCIP_Real* valpnt;
894  SCIP_Real* lbdual[2];
895  SCIP_Real* ubdual[2];
896  SCIP_Real* lbdualbounds[2];
897  SCIP_Real* ubdualbounds[2];
898  SCIP_Real* mincolact;
899  SCIP_Real* maxcolact;
900  SCIP_Bool* varissingcol;
901  int* maxcolactinf;
902  int* mincolactinf;
903  int* colpnt;
904  int* colend;
905  int boundchanges;
906  int loops;
907  int c;
908  int r;
909  int nrows;
910  int ncols;
911 
912  assert(scip != NULL);
913  assert(matrix != NULL);
914  assert(varstofix != NULL);
915  assert(npossiblefixings != NULL);
916  assert(sidestochange != NULL);
917  assert(npossiblesidechanges != NULL);
918 
919  nrows = SCIPmatrixGetNRows(matrix);
920  ncols = SCIPmatrixGetNColumns(matrix);
921 
922  SCIP_CALL( SCIPallocBufferArray(scip, &varissingcol, ncols) );
923  SCIP_CALL( SCIPallocBufferArray(scip, &mincolact, ncols) );
924  SCIP_CALL( SCIPallocBufferArray(scip, &maxcolact, ncols) );
925  SCIP_CALL( SCIPallocBufferArray(scip, &maxcolactinf, ncols) );
926  SCIP_CALL( SCIPallocBufferArray(scip, &mincolactinf, ncols) );
927  SCIP_CALL( SCIPallocBufferArray(scip, &lbdual[0], nrows) );
928  SCIP_CALL( SCIPallocBufferArray(scip, &ubdual[0], nrows) );
929  SCIP_CALL( SCIPallocBufferArray(scip, &lbdual[1], nrows) );
930  SCIP_CALL( SCIPallocBufferArray(scip, &ubdual[1], nrows) );
931  SCIP_CALL( SCIPallocBufferArray(scip, &lbdualbounds[0], ncols) );
932  SCIP_CALL( SCIPallocBufferArray(scip, &ubdualbounds[0], ncols) );
933  SCIP_CALL( SCIPallocBufferArray(scip, &lbdualbounds[1], ncols) );
934  SCIP_CALL( SCIPallocBufferArray(scip, &ubdualbounds[1], ncols) );
935 
936  /* initialize dual bounds */
937  for( r = 0; r < nrows; r++ )
938  {
939  lbdual[0][r] = 0.0;
940  ubdual[0][r] = SCIPinfinity(scip);
941  lbdual[1][r] = 0.0;
942  ubdual[1][r] = SCIPinfinity(scip);
943  }
944 
945  /* intialize dual bounds of primal variable bounds */
946  for( c = 0; c < ncols; c++ )
947  {
948  lbdualbounds[0][c] = 0.0;
949  ubdualbounds[0][c] = SCIPinfinity(scip);
950  lbdualbounds[1][c] = 0.0;
951  ubdualbounds[1][c] = SCIPinfinity(scip);
952  }
953 
954  loops = 0;
955  boundchanges = 1;
956 
957  while( boundchanges && loops < MAX_LOOPS )
958  {
959  loops++;
960  boundchanges = 0;
961 
962  calcColActivity(scip, matrix, 0, ncols, lbdual, ubdual, lbdualbounds, ubdualbounds, mincolact, maxcolact, maxcolactinf, mincolactinf);
963 
964  for( c = 0 ; c < ncols; c++ )
965  {
966  SCIP_Real objval;
967  SCIP_Real mincolresact;
968  SCIP_Bool updateinfcnt;
969  SCIP_VAR* var;
970 
971  var = SCIPmatrixGetVar(matrix, c);
972 
973  /* consider only continuous variables for dual bounds */
975  continue;
976 
977  objval = SCIPvarGetObj(var);
978  colpnt = SCIPmatrixGetColIdxPtr(matrix, c);
979  colend = colpnt + SCIPmatrixGetColNNonzs(matrix, c);
980  valpnt = SCIPmatrixGetColValPtr(matrix, c);
981 
982  for( ; colpnt < colend; colpnt++, valpnt++ )
983  {
984  int row;
985  SCIP_Real val;
986  int part;
987 
988  row = *colpnt;
989  val = *valpnt;
990  mincolresact = -SCIPinfinity(scip);
991 
992  part = 0;
993 
994  do
995  {
996  /* calulate column activity residuals */
997  calcColActResidualCommon(scip, matrix, c, row, val, lbdual, ubdual, part, lbdualbounds, ubdualbounds, mincolact, maxcolact,
998  maxcolactinf, mincolactinf, &mincolresact);
999 
1000  /* update dual bounds */
1001  updateDualBounds(scip, matrix, objval, val, row, mincolresact, lbdual, ubdual, part, &boundchanges, &updateinfcnt);
1002 
1003  /* update infinity counters if bound changed properly */
1004  if( updateinfcnt )
1005  infCntUpdate(scip, matrix, val, row, lbdual, ubdual, lbdualbounds, ubdualbounds, part, mincolact, maxcolact, maxcolactinf, mincolactinf);
1006 
1007  part++;
1008  }
1009  while( !SCIPmatrixIsRowRhsInfinity(matrix, row) && part < 2 );
1010  }
1011 
1012  calcColActResidualExplicitBound(scip, matrix, c, lbdual, ubdual, lbdualbounds, ubdualbounds, TRUE, FALSE, mincolact, maxcolact,
1013  maxcolactinf, mincolactinf, &mincolresact);
1014 
1015  updateDualBoundsExplicit(scip, matrix, objval, c, mincolresact, lbdualbounds, ubdualbounds, TRUE, FALSE, &boundchanges, &updateinfcnt);
1016 
1017  if( updateinfcnt )
1018  infCntUpdateExplicit(scip, matrix, c, lbdual, ubdual, lbdualbounds, ubdualbounds, TRUE, FALSE, mincolact, maxcolact, maxcolactinf, mincolactinf);
1019 
1020  calcColActResidualExplicitBound(scip, matrix, c, lbdual, ubdual, lbdualbounds, ubdualbounds, FALSE, TRUE, mincolact, maxcolact,
1021  maxcolactinf, mincolactinf, &mincolresact);
1022 
1023  updateDualBoundsExplicit(scip, matrix, objval, c, mincolresact, lbdualbounds, ubdualbounds, FALSE, TRUE, &boundchanges, &updateinfcnt);
1024 
1025  if( updateinfcnt )
1026  infCntUpdateExplicit(scip, matrix, c, lbdual, ubdual, lbdualbounds, ubdualbounds, FALSE, TRUE, mincolact, maxcolact, maxcolactinf, mincolactinf);
1027  }
1028  }
1029 
1030  if( boundchanges > 0 )
1031  {
1032  /* calculate minimal/maximal column activity the last time */
1033  calcColActivity(scip, matrix, 0, ncols, lbdual, ubdual, lbdualbounds, ubdualbounds, mincolact, maxcolact, maxcolactinf, mincolactinf);
1034  }
1035 
1036  for( c = 0; c < ncols; c++ )
1037  {
1038  SCIP_Real objval;
1039  SCIP_VAR* var;
1040 
1041  var = SCIPmatrixGetVar(matrix, c);
1042  objval = SCIPvarGetObj(var);
1043 
1044  /* positive reduced costs: c_j - sup{(A_{.j})^T} > 0 => x_j = 0 */
1045  if( SCIPisLT(scip, maxcolact[c], objval) && varstofix[c] == NOFIX )
1046  {
1047  varstofix[c] = FIXATLB;
1048  (*npossiblefixings)++;
1049  }
1050  }
1051 
1052  for( r = 0; r < nrows; r++ )
1053  {
1054  /* implied equality: y_i > 0 => A_{.i}x - b_i = 0 */
1055  if( SCIPmatrixIsRowRhsInfinity(matrix, r) )
1056  {
1057  if( SCIPisGT(scip, lbdual[0][r], 0.0) )
1058  {
1059  sidestochange[r] = RHSTOLHS;
1060  (*npossiblesidechanges)++;
1061  }
1062  }
1063  else
1064  {
1065  if( !SCIPmatrixIsRowRhsInfinity(matrix, r) && !SCIPisEQ(scip,SCIPmatrixGetRowLhs(matrix, r),SCIPmatrixGetRowRhs(matrix, r)) )
1066  {
1067  if( SCIPisGT(scip, lbdual[0][r], 0.0) )
1068  {
1069  assert(sidestochange[r]==NOCHANGE);
1070  sidestochange[r] = RHSTOLHS;
1071  (*npossiblesidechanges)++;
1072  }
1073 
1074  if( SCIPisGT(scip, lbdual[1][r], 0.0) )
1075  {
1076  assert(sidestochange[r]==NOCHANGE);
1077  sidestochange[r] = LHSTORHS;
1078  (*npossiblesidechanges)++;
1079  }
1080  }
1081  }
1082  }
1083 
1084  SCIPfreeBufferArray(scip, &ubdualbounds[1]);
1085  SCIPfreeBufferArray(scip, &lbdualbounds[1]);
1086  SCIPfreeBufferArray(scip, &ubdualbounds[0]);
1087  SCIPfreeBufferArray(scip, &lbdualbounds[0]);
1088  SCIPfreeBufferArray(scip, &ubdual[1]);
1089  SCIPfreeBufferArray(scip, &lbdual[1]);
1090  SCIPfreeBufferArray(scip, &ubdual[0]);
1091  SCIPfreeBufferArray(scip, &lbdual[0]);
1092  SCIPfreeBufferArray(scip, &mincolactinf);
1093  SCIPfreeBufferArray(scip, &maxcolactinf);
1094  SCIPfreeBufferArray(scip, &maxcolact);
1095  SCIPfreeBufferArray(scip, &mincolact);
1096  SCIPfreeBufferArray(scip, &varissingcol);
1097 
1098  return SCIP_OKAY;
1099 }
1100 
1101 /*
1102  * Callback methods of presolver
1103  */
1104 
1105 /** copy method for constraint handler plugins (called when SCIP copies plugins) */
1106 static
1107 SCIP_DECL_PRESOLCOPY(presolCopyDualinfer)
1108 { /*lint --e{715}*/
1109  assert(scip != NULL);
1110  assert(presol != NULL);
1111  assert(strcmp(SCIPpresolGetName(presol), PRESOL_NAME) == 0);
1112 
1113  /* call inclusion method of presolver */
1115 
1116  return SCIP_OKAY;
1117 }
1118 
1119 /** execution method of presolver */
1120 static
1121 SCIP_DECL_PRESOLEXEC(presolExecDualinfer)
1122 { /*lint --e{715}*/
1123  SCIP_MATRIX* matrix;
1124  SCIP_Bool initialized;
1125  SCIP_Bool complete;
1126 
1127  assert(result != NULL);
1128  *result = SCIP_DIDNOTRUN;
1129 
1131  return SCIP_OKAY;
1132 
1133  if( SCIPgetNContVars(scip)==0 )
1134  return SCIP_OKAY;
1135 
1136  if( !SCIPallowDualReds(scip) )
1137  return SCIP_OKAY;
1138 
1139  *result = SCIP_DIDNOTFIND;
1140 
1141  matrix = NULL;
1142  SCIP_CALL( SCIPmatrixCreate(scip, &matrix, &initialized, &complete) );
1143 
1144  if( initialized && complete )
1145  {
1146  FIXINGDIRECTION* varstofix;
1147  int npossiblefixings;
1148  int nconvarsfixed;
1149  int nintvarsfixed;
1150  int nbinvarsfixed;
1151  SIDECHANGE* sidestochange;
1152  int npossiblesidechanges;
1153  int nsideschanged;
1154  int i;
1155  int nrows;
1156  int ncols;
1157 
1158  npossiblefixings = 0;
1159  nconvarsfixed = 0;
1160  nintvarsfixed = 0;
1161  nbinvarsfixed = 0;
1162  npossiblesidechanges = 0;
1163  nsideschanged = 0;
1164 
1165  nrows = SCIPmatrixGetNRows(matrix);
1166  ncols = SCIPmatrixGetNColumns(matrix);
1167 
1168  SCIP_CALL( SCIPallocBufferArray(scip, &varstofix, ncols) );
1169  SCIP_CALL( SCIPallocBufferArray(scip, &sidestochange, nrows) );
1170 
1171  BMSclearMemoryArray(varstofix, ncols);
1172  BMSclearMemoryArray(sidestochange, nrows);
1173 
1174  SCIP_CALL( dualBoundStrengthening(scip, matrix, varstofix, &npossiblefixings, sidestochange, &npossiblesidechanges) );
1175 
1176  if( npossiblefixings > 0 )
1177  {
1178  for( i = ncols - 1; i >= 0; --i )
1179  {
1180  SCIP_Bool infeasible;
1181  SCIP_Bool fixed;
1182  SCIP_VAR* var;
1183 
1184  if( varstofix[i] == FIXATLB )
1185  {
1186  SCIP_Real lb;
1187 
1188  var = SCIPmatrixGetVar(matrix, i);
1189  lb = SCIPvarGetLbLocal(var);
1190 
1191  /* fix at lower bound */
1192  SCIP_CALL( SCIPfixVar(scip, var, lb, &infeasible, &fixed) );
1193  if( infeasible )
1194  {
1195  SCIPdebugMessage(" -> infeasible fixing\n");
1196  *result = SCIP_CUTOFF;
1197  break;
1198  }
1199  assert(fixed);
1200  (*nfixedvars)++;
1201  *result = SCIP_SUCCESS;
1202 
1204  nconvarsfixed++;
1205  else if( SCIPvarGetType(var) == SCIP_VARTYPE_BINARY )
1206  nbinvarsfixed++;
1207  else
1208  nintvarsfixed++;
1209  }
1210  }
1211  }
1212 
1213  if( npossiblesidechanges > 0 )
1214  {
1215  for( i = 0; i < nrows; i++ )
1216  {
1217  SCIP_CONS* cons;
1218  SCIP_CONSHDLR* conshdlr;
1219  const char* conshdlrname;
1220 
1221  if( sidestochange[i] == NOCHANGE )
1222  continue;
1223 
1224  cons = SCIPmatrixGetCons(matrix,i);
1225  conshdlr = SCIPconsGetHdlr(cons);
1226  conshdlrname = SCIPconshdlrGetName(conshdlr);
1227 
1228  if( strcmp(conshdlrname, "linear") == 0 )
1229  {
1230  SCIP_Real lhs;
1231  SCIP_Real rhs;
1232  SCIP_Real matrixlhs;
1233  SCIP_Real matrixrhs;
1234 
1235  lhs = SCIPgetLhsLinear(scip, cons);
1236  rhs = SCIPgetRhsLinear(scip, cons);
1237  matrixlhs = SCIPmatrixGetRowLhs(matrix, i);
1238  matrixrhs = SCIPmatrixGetRowRhs(matrix, i);
1239 
1240  if( sidestochange[i] == RHSTOLHS )
1241  {
1242  assert(!SCIPisEQ(scip, matrixlhs, matrixrhs));
1243 
1244  if( SCIPisEQ(scip, matrixlhs, lhs) )
1245  SCIP_CALL( SCIPchgRhsLinear(scip, cons, matrixlhs) );
1246  else
1247  SCIP_CALL( SCIPchgLhsLinear(scip, cons, -matrixlhs) );
1248 
1249  nsideschanged++;
1250  (*nchgsides)++;
1251  }
1252  else
1253  {
1254  assert(!SCIPisEQ(scip, matrixlhs, matrixrhs));
1255 
1256  if( SCIPisEQ(scip, matrixrhs, rhs) )
1257  SCIP_CALL( SCIPchgLhsLinear(scip, cons, matrixrhs) );
1258  else
1259  SCIP_CALL( SCIPchgRhsLinear(scip, cons, -matrixrhs) );
1260 
1261  nsideschanged++;
1262  (*nchgsides)++;
1263  }
1264  }
1265  else
1266  {
1267  SCIPdebugMessage("Warning: unsupported conshdlr type for side change!");
1268  }
1269  }
1270  }
1271 
1272  SCIPfreeBufferArray(scip, &sidestochange);
1273  SCIPfreeBufferArray(scip, &varstofix);
1274 
1275  if( (nconvarsfixed + nintvarsfixed + nbinvarsfixed) > 0 || npossiblesidechanges > 0)
1276  {
1277  SCIPdebugMessage("### fixed vars [cont: %d, int: %d, bin: %d], chg sides [%d]\n",
1278  nconvarsfixed, nintvarsfixed, nbinvarsfixed, nsideschanged);
1279  }
1280  }
1281 
1282  SCIPmatrixFree(scip, &matrix);
1283 
1284  return SCIP_OKAY;
1285 }
1286 
1287 
1288 /*
1289  * presolver specific interface methods
1290  */
1291 
1292 /** creates the dual inference presolver and includes it in SCIP */
1294  SCIP* scip /**< SCIP data structure */
1295  )
1296 {
1297  SCIP_PRESOLDATA* presoldata;
1298  SCIP_PRESOL* presol;
1299 
1300  presoldata = NULL;
1301 
1302  /* include presolver */
1304  PRESOL_TIMING, presolExecDualinfer, presoldata) );
1305  SCIP_CALL( SCIPsetPresolCopy(scip, presol, presolCopyDualinfer) );
1306 
1307  return SCIP_OKAY;
1308 }
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: scip.c:22777
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41572
static void calcColActivity(SCIP *scip, SCIP_MATRIX *matrix, int startcol, int stopcol, SCIP_Real *lbdual[2], SCIP_Real *ubdual[2], SCIP_Real *lbdualbounds[2], SCIP_Real *ubdualbounds[2], SCIP_Real *mincolact, SCIP_Real *maxcolact, int *maxcolactinf, int *mincolactinf)
struct SCIP_PresolData SCIP_PRESOLDATA
Definition: type_presol.h:37
SCIP_VAR * SCIPmatrixGetVar(SCIP_MATRIX *matrix, int col)
Definition: matrix.c:1325
int SCIPmatrixGetNRows(SCIP_MATRIX *matrix)
Definition: matrix.c:1397
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
Definition: scip.c:41648
#define PRESOL_TIMING
static SCIP_RETCODE dualBoundStrengthening(SCIP *scip, SCIP_MATRIX *matrix, FIXINGDIRECTION *varstofix, int *npossiblefixings, SIDECHANGE *sidestochange, int *npossiblesidechanges)
SCIP_CONS * SCIPmatrixGetCons(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1525
#define NULL
Definition: lpi_spx.cpp:130
SideChange
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17113
SCIP_RETCODE SCIPsetPresolCopy(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLCOPY((*presolcopy)))
Definition: scip.c:6226
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17067
const char * SCIPpresolGetName(SCIP_PRESOL *presol)
Definition: presol.c:553
void SCIPmatrixFree(SCIP *scip, SCIP_MATRIX **matrix)
Definition: matrix.c:782
#define FALSE
Definition: def.h:56
#define TRUE
Definition: def.h:55
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:7640
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
#define SCIP_CALL(x)
Definition: def.h:266
SCIP_Bool SCIPallowDualReds(SCIP *scip)
Definition: scip.c:23083
#define SCIPdebugMessage
Definition: pub_message.h:77
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:85
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:16905
int SCIPgetNContVars(SCIP *scip)
Definition: scip.c:10878
#define PRESOL_MAXROUNDS
static void updateDualBoundsExplicit(SCIP *scip, SCIP_MATRIX *matrix, SCIP_Real objval, int col, SCIP_Real mincolresact, SCIP_Real *lbdualbounds[2], SCIP_Real *ubdualbounds[2], SCIP_Bool explicitub, SCIP_Bool explicitlb, int *boundchanges, SCIP_Bool *updateinfcnt)
SCIP_RETCODE SCIPmatrixCreate(SCIP *scip, SCIP_MATRIX **matrixptr, SCIP_Bool *initialized, SCIP_Bool *complete)
Definition: matrix.c:430
enum Fixingdirection FIXINGDIRECTION
int SCIPmatrixGetRowNNonzs(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1373
static void calcColActResidualCommon(SCIP *scip, SCIP_MATRIX *matrix, int col, int row, SCIP_Real val, SCIP_Real *lbdual[2], SCIP_Real *ubdual[2], int part, SCIP_Real *lbdualbounds[2], SCIP_Real *ubdualbounds[2], SCIP_Real *mincolact, SCIP_Real *maxcolact, int *maxcolactinf, int *mincolactinf, SCIP_Real *mincolresact)
SCIP_Real SCIPmatrixGetRowLhs(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1407
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41585
enum Fixingdirection FIXINGDIRECTION
Definition: presol_domcol.c:77
Fixingdirection
Definition: presol_domcol.c:71
SCIP_Real * SCIPmatrixGetColValPtr(SCIP_MATRIX *matrix, int col)
Definition: matrix.c:1233
static SCIP_Real getMinColActWithoutRow(SCIP *scip, SCIP_MATRIX *matrix, int col, int withoutrow, SCIP_Real *lbdual[2], SCIP_Real *ubdual[2], int part, SCIP_Real *lbdualbounds[2], SCIP_Real *ubdualbounds[2])
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:3897
int * SCIPmatrixGetRowIdxPtr(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1361
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
static SCIP_DECL_PRESOLCOPY(presolCopyDualinfer)
SCIP_Real SCIPinfinity(SCIP *scip)
Definition: scip.c:41637
SCIP_Real * SCIPmatrixGetRowValPtr(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1349
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip.c:32131
static void infCntUpdate(SCIP *scip, SCIP_MATRIX *matrix, SCIP_Real val, int row, SCIP_Real *lbdual[2], SCIP_Real *ubdual[2], SCIP_Real *lbdualbounds[2], SCIP_Real *ubdualbounds[2], int part, SCIP_Real *mincolact, SCIP_Real *maxcolact, int *maxcolactinf, int *mincolactinf)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41611
#define SCIP_Bool
Definition: def.h:53
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip.c:801
int * SCIPmatrixGetColIdxPtr(SCIP_MATRIX *matrix, int col)
Definition: matrix.c:1245
#define PRESOL_NAME
Constraint handler for linear constraints in their most general form, .
public methods for matrix
#define PRESOL_PRIORITY
#define MAX_LOOPS
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:16608
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:20585
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17057
SCIP_RETCODE SCIPchgLhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
dual inference presolver
SCIP_RETCODE SCIPincludePresolDualinfer(SCIP *scip)
SCIP_Real SCIPmatrixGetRowRhs(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1419
enum SideChange SIDECHANGE
SCIP_Bool SCIPmatrixIsRowRhsInfinity(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1431
#define SCIP_Real
Definition: def.h:127
SCIP_RETCODE SCIPchgRhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
static void calcColActResidualExplicitBound(SCIP *scip, SCIP_MATRIX *matrix, int col, SCIP_Real *lbdual[2], SCIP_Real *ubdual[2], SCIP_Real *lbdualbounds[2], SCIP_Real *ubdualbounds[2], SCIP_Bool explicitub, SCIP_Bool explicitlb, SCIP_Real *mincolact, SCIP_Real *maxcolact, int *maxcolactinf, int *mincolactinf, SCIP_Real *mincolresact)
static SCIP_DECL_PRESOLEXEC(presolExecDualinfer)
#define PRESOL_DESC
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:20597
static void infCntUpdateExplicit(SCIP *scip, SCIP_MATRIX *matrix, int col, SCIP_Real *lbdual[2], SCIP_Real *ubdual[2], SCIP_Real *lbdualbounds[2], SCIP_Real *ubdualbounds[2], SCIP_Bool explicitub, SCIP_Bool explicitlb, SCIP_Real *mincolact, SCIP_Real *maxcolact, int *maxcolactinf, int *mincolactinf)
SCIP_RETCODE SCIPincludePresolBasic(SCIP *scip, SCIP_PRESOL **presolptr, const char *name, const char *desc, int priority, int maxrounds, SCIP_PRESOLTIMING timing, SCIP_DECL_PRESOLEXEC((*presolexec)), SCIP_PRESOLDATA *presoldata)
Definition: scip.c:6191
int SCIPmatrixGetNColumns(SCIP_MATRIX *matrix)
Definition: matrix.c:1269
static SCIP_Real getMinColActWithoutBound(SCIP *scip, SCIP_MATRIX *matrix, int col, SCIP_Real *lbdual[2], SCIP_Real *ubdual[2], SCIP_Real *lbdualbounds[2], SCIP_Real *ubdualbounds[2], SCIP_Bool explicitub, SCIP_Bool explicitlb)
static void updateDualBounds(SCIP *scip, SCIP_MATRIX *matrix, SCIP_Real objval, SCIP_Real val, int row, SCIP_Real mincolresact, SCIP_Real *lbdual[2], SCIP_Real *ubdual[2], int part, int *boundchanges, SCIP_Bool *updateinfcnt)
int SCIPmatrixGetColNNonzs(SCIP_MATRIX *matrix, int col)
Definition: matrix.c:1257