Scippy

SCIP

Solving Constraint Integer Programs

presol_sparsify.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-2018 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 visit scip.zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file presol_sparsify.c
17  * @brief cancel non-zeros of the constraint matrix
18  * @author Dieter Weninger
19  * @author Robert Lion Gottwald
20  * @author Ambros Gleixner
21  *
22  * This presolver attempts to cancel non-zero entries of the constraint
23  * matrix by adding scaled equalities to other constraints.
24  */
25 
26 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
27 
28 #include "blockmemshell/memory.h"
29 #include "scip/cons_linear.h"
30 #include "scip/presol_sparsify.h"
31 #include "scip/pub_cons.h"
32 #include "scip/pub_matrix.h"
33 #include "scip/pub_message.h"
34 #include "scip/pub_misc.h"
35 #include "scip/pub_misc_sort.h"
36 #include "scip/pub_presol.h"
37 #include "scip/pub_var.h"
38 #include "scip/scip_cons.h"
39 #include "scip/scip_general.h"
40 #include "scip/scip_mem.h"
41 #include "scip/scip_message.h"
42 #include "scip/scip_nlp.h"
43 #include "scip/scip_numerics.h"
44 #include "scip/scip_param.h"
45 #include "scip/scip_presol.h"
46 #include "scip/scip_pricer.h"
47 #include "scip/scip_prob.h"
48 #include "scip/scip_probing.h"
49 #include "scip/scip_timing.h"
50 #include <string.h>
51 
52 #define PRESOL_NAME "sparsify"
53 #define PRESOL_DESC "eliminate non-zero coefficients"
54 
55 #define PRESOL_PRIORITY -24000 /**< priority of the presolver (>= 0: before, < 0: after constraint handlers) */
56 #define PRESOL_MAXROUNDS -1 /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */
57 #define PRESOL_TIMING SCIP_PRESOLTIMING_EXHAUSTIVE /* timing of the presolver (fast, medium, or exhaustive) */
58 
59 #define DEFAULT_ENABLECOPY TRUE /**< should sparsify presolver be copied to sub-SCIPs? */
60 #define DEFAULT_CANCELLINEAR TRUE /**< should we cancel nonzeros in constraints of the linear constraint handler? */
61 #define DEFAULT_PRESERVEINTCOEFS TRUE /**< should we forbid cancellations that destroy integer coefficients? */
62 #define DEFAULT_MAX_CONT_FILLIN 0 /**< default value for the maximal fillin for continuous variables */
63 #define DEFAULT_MAX_BIN_FILLIN 0 /**< default value for the maximal fillin for binary variables */
64 #define DEFAULT_MAX_INT_FILLIN 0 /**< default value for the maximal fillin for integer variables (including binary) */
65 #define DEFAULT_MAXNONZEROS -1 /**< maximal support of one equality to be used for cancelling (-1: no limit) */
66 #define DEFAULT_MAXCONSIDEREDNONZEROS 70 /**< maximal number of considered non-zeros within one row (-1: no limit) */
67 #define DEFAULT_ROWSORT 'd' /**< order in which to process inequalities ('n'o sorting, 'i'ncreasing nonzeros, 'd'ecreasing nonzeros) */
68 #define DEFAULT_MAXRETRIEVEFAC 100.0 /**< limit on the number of useless vs. useful hashtable retrieves as a multiple of the number of constraints */
69 #define DEFAULT_WAITINGFAC 2.0 /**< number of calls to wait until next execution as a multiple of the number of useless calls */
70 
71 #define MAXSCALE 1000.0 /**< maximal allowed scale for cancelling non-zeros */
72 
73 
74 /*
75  * Data structures
76  */
77 
78 /** presolver data */
79 struct SCIP_PresolData
80 {
81  int ncancels; /**< total number of canceled nonzeros (net value, i.e., removed minus added nonzeros) */
82  int nfillin; /**< total number of added nonzeros */
83  int nfailures; /**< number of calls to presolver without success */
84  int nwaitingcalls; /**< number of presolver calls until next real execution */
85  int maxcontfillin; /**< maximal fillin for continuous variables */
86  int maxintfillin; /**< maximal fillin for integer variables*/
87  int maxbinfillin; /**< maximal fillin for binary variables */
88  int maxnonzeros; /**< maximal support of one equality to be used for cancelling (-1: no limit) */
89  int maxconsiderednonzeros;/**< maximal number of considered non-zeros within one row (-1: no limit) */
90  SCIP_Real maxretrievefac; /**< limit on the number of useless vs. useful hashtable retrieves as a multiple of the number of constraints */
91  SCIP_Real waitingfac; /**< number of calls to wait until next execution as a multiple of the number of useless calls */
92  char rowsort; /**< order in which to process inequalities ('n'o sorting, 'i'ncreasing nonzeros, 'd'ecreasing nonzeros) */
93  SCIP_Bool enablecopy; /**< should sparsify presolver be copied to sub-SCIPs? */
94  SCIP_Bool cancellinear; /**< should we cancel nonzeros in constraints of the linear constraint handler? */
95  SCIP_Bool preserveintcoefs; /**< should we forbid cancellations that destroy integer coefficients? */
96 };
97 
98 /** structure representing a pair of variables in a row; used for lookup in a hashtable */
99 struct RowVarPair
100 {
101  int rowindex;
106 };
107 
108 typedef struct RowVarPair ROWVARPAIR;
109 
110 /*
111  * Local methods
112  */
113 
114 /** returns TRUE iff both keys are equal */
115 static
116 SCIP_DECL_HASHKEYEQ(varPairsEqual)
117 { /*lint --e{715}*/
118  SCIP* scip;
119  ROWVARPAIR* varpair1;
120  ROWVARPAIR* varpair2;
121  SCIP_Real ratio1;
122  SCIP_Real ratio2;
123 
124  scip = (SCIP*) userptr;
125  varpair1 = (ROWVARPAIR*) key1;
126  varpair2 = (ROWVARPAIR*) key2;
127 
128  if( varpair1->varindex1 != varpair2->varindex1 )
129  return FALSE;
130 
131  if( varpair1->varindex2 != varpair2->varindex2 )
132  return FALSE;
133 
134  ratio1 = varpair1->varcoef2 / varpair1->varcoef1;
135  ratio2 = varpair2->varcoef2 / varpair2->varcoef1;
136 
137  return SCIPisEQ(scip, ratio1, ratio2);
138 }
139 
140 /** returns the hash value of the key */
141 static
142 SCIP_DECL_HASHKEYVAL(varPairHashval)
143 { /*lint --e{715}*/
144  ROWVARPAIR* varpair;
145 
146  varpair = (ROWVARPAIR*) key;
147 
148  return SCIPhashTwo(SCIPcombineTwoInt(varpair->varindex1, varpair->varindex2),
149  SCIPrealHashCode(varpair->varcoef2 / varpair->varcoef1));
150 }
151 
152 /** try non-zero cancellation for given row */
153 static
155  SCIP* scip, /**< SCIP datastructure */
156  SCIP_MATRIX* matrix, /**< the constraint matrix */
157  SCIP_HASHTABLE* pairtable, /**< the hashtable containing ROWVARPAIR's of equations */
158  int rowidx, /**< index of row to try non-zero cancellation for */
159  int maxcontfillin, /**< maximal fill-in allowed for continuous variables */
160  int maxintfillin, /**< maximal fill-in allowed for integral variables */
161  int maxbinfillin, /**< maximal fill-in allowed for binary variables */
162  int maxconsiderednonzeros, /**< maximal number of non-zeros to consider for cancellation */
163  SCIP_Bool preserveintcoefs, /**< only perform non-zero cancellation if integrality of coefficients is preserved? */
164  SCIP_Longint* nuseless, /**< pointer to update number of useless hashtable retrieves */
165  int* nchgcoefs, /**< pointer to update number of changed coefficients */
166  int* ncanceled, /**< pointer to update number of canceled nonzeros */
167  int* nfillin /**< pointer to update the produced fill-in */
168  )
169 {
170  int* cancelrowinds;
171  SCIP_Real* cancelrowvals;
172  SCIP_Real cancellhs;
173  SCIP_Real cancelrhs;
174  SCIP_Real bestcancelrate;
175  int* tmpinds;
176  int* locks;
177  SCIP_Real* tmpvals;
178  int cancelrowlen;
179  int* rowidxptr;
180  SCIP_Real* rowvalptr;
181  int nchgcoef;
182  int nretrieves;
183  int bestnfillin;
184  SCIP_Real mincancelrate;
185  SCIP_Bool rowiseq;
186  SCIP_CONS* cancelcons;
187 
188  rowiseq = SCIPisEQ(scip, SCIPmatrixGetRowLhs(matrix, rowidx), SCIPmatrixGetRowRhs(matrix, rowidx));
189 
190  cancelrowlen = SCIPmatrixGetRowNNonzs(matrix, rowidx);
191  rowidxptr = SCIPmatrixGetRowIdxPtr(matrix, rowidx);
192  rowvalptr = SCIPmatrixGetRowValPtr(matrix, rowidx);
193 
194  cancelcons = SCIPmatrixGetCons(matrix, rowidx);
195 
196  mincancelrate = 0.0;
197 
198  /* for set packing and logicor constraints, only accept equalities where all modified coefficients are cancelled */
199  if( SCIPconsGetHdlr(cancelcons) == SCIPfindConshdlr(scip, "setppc") ||
200  SCIPconsGetHdlr(cancelcons) == SCIPfindConshdlr(scip, "logicor") )
201  mincancelrate = 1.0;
202 
203  SCIP_CALL( SCIPduplicateBufferArray(scip, &cancelrowinds, rowidxptr, cancelrowlen) );
204  SCIP_CALL( SCIPduplicateBufferArray(scip, &cancelrowvals, rowvalptr, cancelrowlen) );
205  SCIP_CALL( SCIPallocBufferArray(scip, &tmpinds, cancelrowlen) );
206  SCIP_CALL( SCIPallocBufferArray(scip, &tmpvals, cancelrowlen) );
207  SCIP_CALL( SCIPallocBufferArray(scip, &locks, cancelrowlen) );
208 
209  cancellhs = SCIPmatrixGetRowLhs(matrix, rowidx);
210  cancelrhs = SCIPmatrixGetRowRhs(matrix, rowidx);
211 
212  nchgcoef = 0;
213  nretrieves = 0;
214  while( TRUE ) /*lint !e716 */
215  {
216  SCIP_Real bestscale;
217  int bestcand;
218  int i;
219  int j;
220  ROWVARPAIR rowvarpair;
221  int maxlen;
222 
223  bestscale = 1.0;
224  bestcand = -1;
225  bestnfillin = 0;
226  bestcancelrate = 0.0;
227 
228  for( i = 0; i < cancelrowlen; ++i )
229  {
230  tmpinds[i] = i;
231  locks[i] = SCIPmatrixGetColNDownlocks(matrix, cancelrowinds[i]) + SCIPmatrixGetColNUplocks(matrix, cancelrowinds[i]);
232  }
233 
234  SCIPsortIntInt(locks, tmpinds, cancelrowlen);
235 
236  maxlen = cancelrowlen;
237  if( maxconsiderednonzeros >= 0 )
238  maxlen = MIN(cancelrowlen, maxconsiderednonzeros);
239 
240  for( i = 0; i < maxlen; ++i )
241  {
242  for( j = i + 1; j < maxlen; ++j )
243  {
244  int a,b;
245  int ncancel;
246  int ncontfillin;
247  int nintfillin;
248  int nbinfillin;
249  int ntotfillin;
250  int eqrowlen;
251  ROWVARPAIR* eqrowvarpair;
252  SCIP_Real* eqrowvals;
253  int* eqrowinds;
254  SCIP_Real scale;
255  SCIP_Real cancelrate;
256  int i1,i2;
257  SCIP_Bool abortpair;
258 
259  i1 = tmpinds[i];
260  i2 = tmpinds[j];
261 
262  assert(cancelrowinds[i] < cancelrowinds[j]);
263 
264  if( cancelrowinds[i1] < cancelrowinds[i2] )
265  {
266  rowvarpair.varindex1 = cancelrowinds[i1];
267  rowvarpair.varindex2 = cancelrowinds[i2];
268  rowvarpair.varcoef1 = cancelrowvals[i1];
269  rowvarpair.varcoef2 = cancelrowvals[i2];
270  }
271  else
272  {
273  rowvarpair.varindex1 = cancelrowinds[i2];
274  rowvarpair.varindex2 = cancelrowinds[i1];
275  rowvarpair.varcoef1 = cancelrowvals[i2];
276  rowvarpair.varcoef2 = cancelrowvals[i1];
277  }
278 
279  eqrowvarpair = (ROWVARPAIR*)SCIPhashtableRetrieve(pairtable, (void*) &rowvarpair);
280  nretrieves++;
281 
282  if( eqrowvarpair == NULL || eqrowvarpair->rowindex == rowidx )
283  continue;
284 
285  /* if the row we want to cancel is an equality, we will only use equalities
286  * for canceling with less non-zeros and if the number of non-zeros is equal we use the
287  * rowindex as tie-breaker to avoid cyclic non-zero cancellation
288  */
289  eqrowlen = SCIPmatrixGetRowNNonzs(matrix, eqrowvarpair->rowindex);
290  if( rowiseq && (cancelrowlen < eqrowlen || (cancelrowlen == eqrowlen && rowidx < eqrowvarpair->rowindex)) )
291  continue;
292 
293  eqrowvals = SCIPmatrixGetRowValPtr(matrix, eqrowvarpair->rowindex);
294  eqrowinds = SCIPmatrixGetRowIdxPtr(matrix, eqrowvarpair->rowindex);
295 
296  scale = -rowvarpair.varcoef1 / eqrowvarpair->varcoef1;
297 
298  if( REALABS(scale) > MAXSCALE )
299  continue;
300 
301  a = 0;
302  b = 0;
303  ncancel = 0;
304 
305  ncontfillin = 0;
306  nintfillin = 0;
307  nbinfillin = 0;
308  abortpair = FALSE;
309  while( a < cancelrowlen && b < eqrowlen )
310  {
311  if( cancelrowinds[a] == eqrowinds[b] )
312  {
313  SCIP_Real newcoef;
314 
315  newcoef = cancelrowvals[a] + scale * eqrowvals[b];
316 
317  /* check if coefficient is cancelled */
318  if( SCIPisZero(scip, newcoef) )
319  {
320  ++ncancel;
321  }
322  /* otherwise, check if integral coefficients are preserved if the column is integral */
323  else if( (preserveintcoefs && SCIPvarIsIntegral(SCIPmatrixGetVar(matrix, cancelrowinds[a])) &&
324  SCIPisIntegral(scip, cancelrowvals[a]) && !SCIPisIntegral(scip, newcoef)) )
325  {
326  abortpair = TRUE;
327  break;
328  }
329  /* finally, check if locks could be modified in a bad way due to flipped signs */
330  else if( (SCIPisInfinity(scip, cancelrhs) || SCIPisInfinity(scip, -cancellhs)) &&
331  COPYSIGN(1.0, newcoef) != COPYSIGN(1.0, cancelrowvals[a]) ) /*lint !e777*/
332  {
333  /* do not flip signs for non-canceled coefficients if this adds a lock to a variable that had at most one lock
334  * in that direction before, except if the other direction gets unlocked
335  */
336  if( (cancelrowvals[a] > 0.0 && ! SCIPisInfinity(scip, cancelrhs)) ||
337  (cancelrowvals[a] < 0.0 && ! SCIPisInfinity(scip, -cancellhs)) )
338  {
339  /* if we get into this case the variable had a positive coefficient in a <= constraint or a negative
340  * coefficient in a >= constraint, e.g. an uplock. If this was the only uplock we do not abort their
341  * cancelling, otherwise we abort if we had a single or no downlock and add one
342  */
343  if( SCIPmatrixGetColNUplocks(matrix, cancelrowinds[a]) > 1 &&
344  SCIPmatrixGetColNDownlocks(matrix, cancelrowinds[a]) <= 1 )
345  {
346  abortpair = TRUE;
347  break;
348  }
349  }
350 
351  if( (cancelrowvals[a] < 0.0 && ! SCIPisInfinity(scip, cancelrhs)) ||
352  (cancelrowvals[a] > 0.0 && ! SCIPisInfinity(scip, -cancellhs)) )
353  {
354  /* symmetric case where the variable had a downlock */
355  if( SCIPmatrixGetColNDownlocks(matrix, cancelrowinds[a]) > 1 &&
356  SCIPmatrixGetColNUplocks(matrix, cancelrowinds[a]) <= 1 )
357  {
358  abortpair = TRUE;
359  break;
360  }
361  }
362  }
363 
364  ++a;
365  ++b;
366  }
367  else if( cancelrowinds[a] < eqrowinds[b] )
368  {
369  ++a;
370  }
371  else
372  {
373  SCIP_Real newcoef;
374  SCIP_VAR* var;
375 
376  var = SCIPmatrixGetVar(matrix, eqrowinds[b]);
377  newcoef = scale * eqrowvals[b];
378 
379  if( (newcoef > 0.0 && ! SCIPisInfinity(scip, cancelrhs)) ||
380  (newcoef < 0.0 && ! SCIPisInfinity(scip, -cancellhs)) )
381  {
382  if( SCIPmatrixGetColNUplocks(matrix, eqrowinds[b]) <= 1 )
383  {
384  abortpair = TRUE;
385  ++b;
386  break;
387  }
388  }
389 
390  if( (newcoef < 0.0 && ! SCIPisInfinity(scip, cancelrhs)) ||
391  (newcoef > 0.0 && ! SCIPisInfinity(scip, -cancellhs)) )
392  {
393  if( SCIPmatrixGetColNDownlocks(matrix, eqrowinds[b]) <= 1 )
394  {
395  abortpair = TRUE;
396  ++b;
397  break;
398  }
399  }
400 
401  ++b;
402 
403  if( SCIPvarIsIntegral(var) )
404  {
405  if( SCIPvarIsBinary(var) && ++nbinfillin > maxbinfillin )
406  {
407  abortpair = TRUE;
408  break;
409  }
410 
411  if( ++nintfillin > maxintfillin )
412  {
413  abortpair = TRUE;
414  break;
415  }
416  }
417  else
418  {
419  if( ++ncontfillin > maxcontfillin )
420  {
421  abortpair = TRUE;
422  break;
423  }
424  }
425  }
426  }
427 
428  if( abortpair )
429  continue;
430 
431  while( b < eqrowlen )
432  {
433  SCIP_VAR* var = SCIPmatrixGetVar(matrix, eqrowinds[b]);
434  ++b;
435  if( SCIPvarIsIntegral(var) )
436  {
437  if( SCIPvarIsBinary(var) && ++nbinfillin > maxbinfillin )
438  break;
439  if( ++nintfillin > maxintfillin )
440  break;
441  }
442  else
443  {
444  if( ++ncontfillin > maxcontfillin )
445  break;
446  }
447  }
448 
449  if( ncontfillin > maxcontfillin || nbinfillin > maxbinfillin || nintfillin > maxintfillin )
450  continue;
451 
452  ntotfillin = nintfillin + ncontfillin;
453 
454  if( ntotfillin >= ncancel )
455  continue;
456 
457  cancelrate = (ncancel - ntotfillin) / (SCIP_Real) eqrowlen;
458 
459  if( cancelrate < mincancelrate )
460  continue;
461 
462  if( cancelrate > bestcancelrate )
463  {
464  bestnfillin = ntotfillin;
465  bestcand = eqrowvarpair->rowindex;
466  bestscale = scale;
467  bestcancelrate = cancelrate;
468 
469  /* stop looking if the current candidate does not create any fill-in or alter coefficients */
470  if( cancelrate == 1.0 )
471  break;
472  }
473 
474  /* we accept the best candidate immediately if it does not create any fill-in or alter coefficients */
475  if( bestcand != -1 && bestcancelrate == 1.0 )
476  break;
477  }
478  }
479 
480  if( bestcand != -1 )
481  {
482  int a;
483  int b;
484  SCIP_Real* eqrowvals;
485  int* eqrowinds;
486  int eqrowlen;
487  int tmprowlen;
488  SCIP_Real eqrhs;
489 
490  eqrowvals = SCIPmatrixGetRowValPtr(matrix, bestcand);
491  eqrowinds = SCIPmatrixGetRowIdxPtr(matrix, bestcand);
492  eqrowlen = SCIPmatrixGetRowNNonzs(matrix, bestcand);
493  eqrhs = SCIPmatrixGetRowRhs(matrix, bestcand);
494 
495  a = 0;
496  b = 0;
497  tmprowlen = 0;
498 
499  if( !SCIPisZero(scip, eqrhs) )
500  {
501  if( !SCIPisInfinity(scip, -cancellhs) )
502  cancellhs += bestscale * eqrhs;
503  if( !SCIPisInfinity(scip, cancelrhs) )
504  cancelrhs += bestscale * eqrhs;
505  }
506 
507  while( a < cancelrowlen && b < eqrowlen )
508  {
509  if( cancelrowinds[a] == eqrowinds[b] )
510  {
511  SCIP_Real val = cancelrowvals[a] + bestscale * eqrowvals[b];
512 
513  if( !SCIPisZero(scip, val) )
514  {
515  tmpinds[tmprowlen] = cancelrowinds[a];
516  tmpvals[tmprowlen] = val;
517  ++tmprowlen;
518  }
519  ++nchgcoef;
520 
521  ++a;
522  ++b;
523  }
524  else if( cancelrowinds[a] < eqrowinds[b] )
525  {
526  tmpinds[tmprowlen] = cancelrowinds[a];
527  tmpvals[tmprowlen] = cancelrowvals[a];
528  ++tmprowlen;
529  ++a;
530  }
531  else
532  {
533  tmpinds[tmprowlen] = eqrowinds[b];
534  tmpvals[tmprowlen] = eqrowvals[b] * bestscale;
535  ++nchgcoef;
536  ++tmprowlen;
537  ++b;
538  }
539  }
540 
541  while( a < cancelrowlen )
542  {
543  tmpinds[tmprowlen] = cancelrowinds[a];
544  tmpvals[tmprowlen] = cancelrowvals[a];
545  ++tmprowlen;
546  ++a;
547  }
548 
549  while( b < eqrowlen )
550  {
551  tmpinds[tmprowlen] = eqrowinds[b];
552  tmpvals[tmprowlen] = eqrowvals[b] * bestscale;
553  ++nchgcoef;
554  ++tmprowlen;
555  ++b;
556  }
557 
558  /* update fill-in counter */
559  *nfillin += bestnfillin;
560 
561  /* swap the temporary arrays so that the cancelrowinds and cancelrowvals arrays, contain the new
562  * changed row, and the tmpinds and tmpvals arrays can be overwritten in the next iteration
563  */
564  SCIPswapPointers((void**) &tmpinds, (void**) &cancelrowinds);
565  SCIPswapPointers((void**) &tmpvals, (void**) &cancelrowvals);
566  cancelrowlen = tmprowlen;
567  }
568  else
569  break;
570  }
571 
572  if( nchgcoef != 0 )
573  {
574  SCIP_CONS* cons;
575  SCIP_VAR** consvars;
576 
577  int i;
578 
579  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, cancelrowlen) );
580 
581  for( i = 0; i < cancelrowlen; ++i )
582  consvars[i] = SCIPmatrixGetVar(matrix, cancelrowinds[i]);
583 
584  /* create sparsified constraint and add it to scip */
585  SCIP_CALL( SCIPcreateConsLinear(scip, &cons, SCIPmatrixGetRowName(matrix, rowidx), cancelrowlen, consvars, cancelrowvals,
586  cancellhs, cancelrhs, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
587  SCIP_CALL( SCIPdelCons(scip, SCIPmatrixGetCons(matrix, rowidx)) );
588  SCIP_CALL( SCIPaddCons(scip, cons) );
589 
590 #ifdef SCIP_MORE_DEBUG
591  SCIPdebugMsg(scip, "########\n");
592  SCIPdebugMsg(scip, "old:\n");
593  SCIPmatrixPrintRow(scip, matrix, rowidx);
594  SCIPdebugMsg(scip, "new:\n");
595  SCIPdebugPrintCons(scip, cons, NULL);
596  SCIPdebugMsg(scip, "########\n");
597 #endif
598 
599  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
600 
601  /* update counters */
602  *nchgcoefs += nchgcoef;
603  *ncanceled += SCIPmatrixGetRowNNonzs(matrix, rowidx) - cancelrowlen;
604 
605  /* if successful, decrease the useless hashtable retrieves counter; the rationale here is that we want to keep
606  * going if, after many useless calls that almost exceeded the budget, we finally reach a useful section; but we
607  * don't allow a negative build-up for the case that the useful section is all at the beginning and we just want
608  * to quit quickly afterwards
609  */
610  *nuseless -= nretrieves;
611  *nuseless = MAX(*nuseless, 0);
612 
613  SCIPfreeBufferArray(scip, &consvars);
614  }
615  else
616  {
617  /* if not successful, increase useless hashtable retrieves counter */
618  *nuseless += nretrieves;
619  }
620 
621  SCIPfreeBufferArray(scip, &locks);
622  SCIPfreeBufferArray(scip, &tmpvals);
623  SCIPfreeBufferArray(scip, &tmpinds);
624  SCIPfreeBufferArray(scip, &cancelrowvals);
625  SCIPfreeBufferArray(scip, &cancelrowinds);
626 
627  return SCIP_OKAY;
628 }
629 
630 /** updates failure counter after one execution */
631 static
633  SCIP_PRESOLDATA* presoldata, /**< presolver data */
634  SCIP_Bool success /**< was this execution successful? */
635  )
636 {
637  assert(presoldata != NULL);
638 
639  if( success )
640  {
641  presoldata->nfailures = 0;
642  presoldata->nwaitingcalls = 0;
643  }
644  else
645  {
646  presoldata->nfailures++;
647  presoldata->nwaitingcalls = (int)(presoldata->waitingfac*(SCIP_Real)presoldata->nfailures);
648  }
649 }
650 
651 
652 /*
653  * Callback methods of presolver
654  */
655 
656 /** copy method for constraint handler plugins (called when SCIP copies plugins) */
657 static
658 SCIP_DECL_PRESOLCOPY(presolCopySparsify)
659 {
660  SCIP_PRESOLDATA* presoldata;
661 
662  assert(scip != NULL);
663  assert(presol != NULL);
664  assert(strcmp(SCIPpresolGetName(presol), PRESOL_NAME) == 0);
665 
666  /* call inclusion method of presolver if copying is enabled */
667  presoldata = SCIPpresolGetData(presol);
668  assert(presoldata != NULL);
669  if( presoldata->enablecopy )
670  {
672  }
673 
674  return SCIP_OKAY;
675 }
676 
677 /** execution method of presolver */
678 static
679 SCIP_DECL_PRESOLEXEC(presolExecSparsify)
680 { /*lint --e{715}*/
681  SCIP_MATRIX* matrix;
682  SCIP_Bool initialized;
683  SCIP_Bool complete;
684  int nrows;
685  int r;
686  int i;
687  int j;
688  int numcancel;
689  int oldnchgcoefs;
690  int nfillin;
691  int* locks;
692  int* perm;
693  int* rowidxsorted;
694  int* rowsparsity;
695  SCIP_HASHTABLE* pairtable;
696  ROWVARPAIR* varpairs;
697  int nvarpairs;
698  int varpairssize;
699  SCIP_PRESOLDATA* presoldata;
700  SCIP_Longint maxuseless;
701  SCIP_Longint nuseless;
702  SCIP_CONSHDLR* linearhdlr;
703 
704  assert(result != NULL);
705 
706  *result = SCIP_DIDNOTRUN;
707 
709  return SCIP_OKAY;
710 
712  return SCIP_OKAY;
713 
714  presoldata = SCIPpresolGetData(presol);
715 
716  if( presoldata->nwaitingcalls > 0 )
717  {
718  presoldata->nwaitingcalls--;
719  SCIPdebugMsg(scip, "skipping sparsify: nfailures=%d, nwaitingcalls=%d\n", presoldata->nfailures,
720  presoldata->nwaitingcalls);
721  return SCIP_OKAY;
722  }
723 
724  /* if we want to cancel only from specialized constraints according to the parameter, then we can skip execution if
725  * only linear constraints are present
726  */
727  linearhdlr = SCIPfindConshdlr(scip, "linear");
728  if( !presoldata->cancellinear && linearhdlr != NULL && SCIPconshdlrGetNConss(linearhdlr) >= SCIPgetNConss(scip) )
729  {
730  SCIPdebugMsg(scip, "skipping sparsify: only linear constraints found\n");
731  return SCIP_OKAY;
732  }
733 
734  SCIPdebugMsg(scip, "starting sparsify. . .\n");
735  *result = SCIP_DIDNOTFIND;
736 
737  matrix = NULL;
738  SCIP_CALL( SCIPmatrixCreate(scip, &matrix, &initialized, &complete) );
739 
740  /* we only work on pure MIPs currently */
741  if( initialized && complete )
742  {
743  nrows = SCIPmatrixGetNRows(matrix);
744 
745  /* sort rows by column indices */
746  for( i = 0; i < nrows; i++ )
747  {
748  int* rowpnt = SCIPmatrixGetRowIdxPtr(matrix, i);
749  SCIP_Real* valpnt = SCIPmatrixGetRowValPtr(matrix, i);
750  SCIPsortIntReal(rowpnt, valpnt, SCIPmatrixGetRowNNonzs(matrix, i));
751  }
752 
755 
756  /* loop over all rows and create var pairs */
757  numcancel = 0;
758  nfillin = 0;
759  varpairssize = 0;
760  nvarpairs = 0;
761  varpairs = NULL;
762  SCIP_CALL( SCIPhashtableCreate(&pairtable, SCIPblkmem(scip), 1, SCIPhashGetKeyStandard, varPairsEqual, varPairHashval, (void*) scip) );
763 
764  /* collect equalities and their number of non-zeros */
765  for( r = 0; r < nrows; r++ )
766  {
767  int nnonz;
768 
769  nnonz = SCIPmatrixGetRowNNonzs(matrix, r);
770 
771  /* consider equalities with support at most maxnonzeros; skip singleton equalities, because these are faster
772  * processed by trivial presolving
773  */
774  if( nnonz >= 2 && (presoldata->maxnonzeros < 0 || nnonz <= presoldata->maxnonzeros)
775  && SCIPisEQ(scip, SCIPmatrixGetRowRhs(matrix, r), SCIPmatrixGetRowLhs(matrix, r)) )
776  {
777  int* rowinds;
778  SCIP_Real* rowvals;
779  int npairs;
780  int failshift;
781 
782  rowinds = SCIPmatrixGetRowIdxPtr(matrix, r);
783  rowvals = SCIPmatrixGetRowValPtr(matrix, r);
784 
785  for( i = 0; i < nnonz; ++i )
786  {
787  perm[i] = i;
788  locks[i] = SCIPmatrixGetColNDownlocks(matrix, rowinds[i]) + SCIPmatrixGetColNUplocks(matrix, rowinds[i]);
789  }
790 
791  SCIPsortIntInt(locks, perm, nnonz);
792 
793  if( presoldata->maxconsiderednonzeros >= 0 )
794  nnonz = MIN(nnonz, presoldata->maxconsiderednonzeros);
795 
796  npairs = (nnonz * (nnonz - 1)) / 2;
797  if( nvarpairs + npairs > varpairssize )
798  {
799  int newsize = SCIPcalcMemGrowSize(scip, nvarpairs + npairs);
800  SCIP_CALL( SCIPreallocBufferArray(scip, &varpairs, newsize) );
801  varpairssize = newsize;
802  }
803 
804  /* if we are called after one or more failures, i.e., executions without finding cancellations, then we
805  * shift the section of nonzeros considered; in the case that the maxconsiderednonzeros limit is hit, this
806  * results in different variable pairs being tried and avoids trying the same useless cancellations
807  * repeatedly
808  */
809  failshift = presoldata->nfailures*presoldata->maxconsiderednonzeros;
810 
811  for( i = 0; i < nnonz; ++i )
812  {
813  for( j = i + 1; j < nnonz; ++j )
814  {
815  int i1;
816  int i2;
817 
818  assert(nvarpairs < varpairssize);
819  assert(varpairs != NULL);
820 
821  i1 = perm[(i + failshift) % nnonz];
822  i2 = perm[(j + failshift) % nnonz];
823  varpairs[nvarpairs].rowindex = r;
824 
825  if( rowinds[i1] < rowinds[i2])
826  {
827  varpairs[nvarpairs].varindex1 = rowinds[i1];
828  varpairs[nvarpairs].varindex2 = rowinds[i2];
829  varpairs[nvarpairs].varcoef1 = rowvals[i1];
830  varpairs[nvarpairs].varcoef2 = rowvals[i2];
831  }
832  else
833  {
834  varpairs[nvarpairs].varindex1 = rowinds[i2];
835  varpairs[nvarpairs].varindex2 = rowinds[i1];
836  varpairs[nvarpairs].varcoef1 = rowvals[i2];
837  varpairs[nvarpairs].varcoef2 = rowvals[i1];
838  }
839  ++nvarpairs;
840  }
841  }
842  }
843  }
844 
845  /* insert varpairs into hash table */
846  for( r = 0; r < nvarpairs; ++r )
847  {
848  SCIP_Bool insert;
849  ROWVARPAIR* othervarpair;
850 
851  assert(varpairs != NULL);
852 
853  insert = TRUE;
854 
855  /* check if this pair is already contained in the hash table;
856  * The loop is required due to the non-transitivity of the hash functions
857  */
858  while( (othervarpair = (ROWVARPAIR*)SCIPhashtableRetrieve(pairtable, (void*) &varpairs[r])) != NULL )
859  {
860  /* if the previous variable pair has fewer or the same number of non-zeros in the attached row
861  * we keep that pair and skip this one
862  */
863  if( SCIPmatrixGetRowNNonzs(matrix, othervarpair->rowindex) <= SCIPmatrixGetRowNNonzs(matrix, varpairs[r].rowindex) )
864  {
865  insert = FALSE;
866  break;
867  }
868 
869  /* this pairs row has fewer non-zeros, so remove the other pair from the hash table and loop */
870  SCIP_CALL( SCIPhashtableRemove(pairtable, (void*) othervarpair) );
871  }
872 
873  if( insert )
874  {
875  SCIP_CALL( SCIPhashtableInsert(pairtable, (void*) &varpairs[r]) );
876  }
877  }
878 
879  /* sort rows according to parameter value */
880  if( presoldata->rowsort == 'i' || presoldata->rowsort == 'd' )
881  {
882  SCIP_CALL( SCIPallocBufferArray(scip, &rowidxsorted, nrows) );
883  SCIP_CALL( SCIPallocBufferArray(scip, &rowsparsity, nrows) );
884  for( r = 0; r < nrows; ++r )
885  rowidxsorted[r] = r;
886  if( presoldata->rowsort == 'i' )
887  {
888  for( r = 0; r < nrows; ++r )
889  rowsparsity[r] = SCIPmatrixGetRowNNonzs(matrix, r);
890  }
891  else if( presoldata->rowsort == 'd' )
892  {
893  for( r = 0; r < nrows; ++r )
894  rowsparsity[r] = -SCIPmatrixGetRowNNonzs(matrix, r);
895  }
896  SCIPsortIntInt(rowsparsity, rowidxsorted, nrows);
897  }
898  else
899  {
900  assert(presoldata->rowsort == 'n');
901  rowidxsorted = NULL;
902  rowsparsity = NULL;
903  }
904 
905  /* loop over the rows and cancel non-zeros until maximum number of retrieves is reached */
906  maxuseless = (SCIP_Longint)(presoldata->maxretrievefac * (SCIP_Real)nrows);
907  nuseless = 0;
908  oldnchgcoefs = *nchgcoefs;
909  for( r = 0; r < nrows && nuseless <= maxuseless; r++ )
910  {
911  int rowidx;
912 
913  rowidx = rowidxsorted != NULL ? rowidxsorted[r] : r;
914 
915  /* check whether we want to cancel only from specialized constraints; one reasoning behind this may be that
916  * cancelling fractional coefficients requires more numerical care than is currently implemented in method
917  * cancelRow()
918  */
919  assert(SCIPmatrixGetCons(matrix, rowidx) != NULL);
920  if( !presoldata->cancellinear && SCIPconsGetHdlr(SCIPmatrixGetCons(matrix, rowidx)) == linearhdlr )
921  continue;
922 
923  /* since the function parameters for the max fillin are unsigned we do not need to handle the
924  * unlimited (-1) case due to implicit conversion rules */
925  SCIP_CALL( cancelRow(scip, matrix, pairtable, rowidx, \
926  presoldata->maxcontfillin == -1 ? INT_MAX : presoldata->maxcontfillin, \
927  presoldata->maxintfillin == -1 ? INT_MAX : presoldata->maxintfillin, \
928  presoldata->maxbinfillin == -1 ? INT_MAX : presoldata->maxbinfillin, \
929  presoldata->maxconsiderednonzeros, presoldata->preserveintcoefs, \
930  &nuseless, nchgcoefs, &numcancel, &nfillin) );
931  }
932 
933  SCIPfreeBufferArrayNull(scip, &rowsparsity);
934  SCIPfreeBufferArrayNull(scip, &rowidxsorted);
935 
936  SCIPhashtableFree(&pairtable);
937  SCIPfreeBufferArrayNull(scip, &varpairs);
938 
939  SCIPfreeBufferArray(scip, &perm);
940  SCIPfreeBufferArray(scip, &locks);
941 
942  /* update result */
943  presoldata->ncancels += numcancel;
944  presoldata->nfillin += nfillin;
945 
946  if( numcancel > 0 )
947  {
949  " (%.1fs) sparsify %s: %d/%d (%.1f%%) nonzeros canceled"
950  " - in total %d canceled nonzeros, %d changed coefficients, %d added nonzeros\n",
951  SCIPgetSolvingTime(scip), (nuseless > maxuseless ? "aborted" : "finished"), numcancel,
952  SCIPmatrixGetNNonzs(matrix), 100.0*(SCIP_Real)numcancel/(SCIP_Real)SCIPmatrixGetNNonzs(matrix),
953  presoldata->ncancels, SCIPpresolGetNChgCoefs(presol) + *nchgcoefs - oldnchgcoefs, presoldata->nfillin);
954  *result = SCIP_SUCCESS;
955  }
956 
957  updateFailureStatistic(presoldata, numcancel > 0);
958 
959  SCIPdebugMsg(scip, "sparsify failure statistic: nfailures=%d, nwaitingcalls=%d\n", presoldata->nfailures,
960  presoldata->nwaitingcalls);
961  }
962  /* if matrix construction fails once, we do not ever want to be called again */
963  else
964  {
965  updateFailureStatistic(presoldata, FALSE);
966  presoldata->nwaitingcalls = INT_MAX;
967  }
968 
969  SCIPmatrixFree(scip, &matrix);
970 
971  return SCIP_OKAY;
972 }
973 
974 /*
975  * presolver specific interface methods
976  */
977 
978 /** destructor of presolver to free user data (called when SCIP is exiting) */
979 static
980 SCIP_DECL_PRESOLFREE(presolFreeSparsify)
981 { /*lint --e{715}*/
982  SCIP_PRESOLDATA* presoldata;
983 
984  /* free presolver data */
985  presoldata = SCIPpresolGetData(presol);
986  assert(presoldata != NULL);
987 
988  SCIPfreeBlockMemory(scip, &presoldata);
989  SCIPpresolSetData(presol, NULL);
990 
991  return SCIP_OKAY;
992 }
993 
994 /** initialization method of presolver (called after problem was transformed) */
995 static
996 SCIP_DECL_PRESOLINIT(presolInitSparsify)
997 {
998  SCIP_PRESOLDATA* presoldata;
999 
1000  /* set the counters in the init (and not in the initpre) callback such that they persist across restarts */
1001  presoldata = SCIPpresolGetData(presol);
1002  presoldata->ncancels = 0;
1003  presoldata->nfillin = 0;
1004  presoldata->nfailures = 0;
1005  presoldata->nwaitingcalls = 0;
1006 
1007  return SCIP_OKAY;
1008 }
1009 
1010 /** creates the sparsify presolver and includes it in SCIP */
1012  SCIP* scip /**< SCIP data structure */
1013  )
1014 {
1015  SCIP_PRESOLDATA* presoldata;
1016  SCIP_PRESOL* presol;
1017 
1018  /* create sparsify presolver data */
1019  SCIP_CALL( SCIPallocBlockMemory(scip, &presoldata) );
1020 
1021  /* include presolver */
1023  PRESOL_TIMING, presolExecSparsify, presoldata) );
1024 
1025  SCIP_CALL( SCIPsetPresolCopy(scip, presol, presolCopySparsify) );
1026  SCIP_CALL( SCIPsetPresolFree(scip, presol, presolFreeSparsify) );
1027  SCIP_CALL( SCIPsetPresolInit(scip, presol, presolInitSparsify) );
1028 
1030  "presolving/sparsify/enablecopy",
1031  "should sparsify presolver be copied to sub-SCIPs?",
1032  &presoldata->enablecopy, TRUE, DEFAULT_ENABLECOPY, NULL, NULL) );
1033 
1035  "presolving/sparsify/cancellinear",
1036  "should we cancel nonzeros in constraints of the linear constraint handler?",
1037  &presoldata->cancellinear, TRUE, DEFAULT_CANCELLINEAR, NULL, NULL) );
1038 
1040  "presolving/sparsify/preserveintcoefs",
1041  "should we forbid cancellations that destroy integer coefficients?",
1042  &presoldata->preserveintcoefs, TRUE, DEFAULT_PRESERVEINTCOEFS, NULL, NULL) );
1043 
1044  SCIP_CALL( SCIPaddIntParam(scip,
1045  "presolving/sparsify/maxcontfillin",
1046  "maximal fillin for continuous variables (-1: unlimited)",
1047  &presoldata->maxcontfillin, FALSE, DEFAULT_MAX_CONT_FILLIN, -1, INT_MAX, NULL, NULL) );
1048 
1049  SCIP_CALL( SCIPaddIntParam(scip,
1050  "presolving/sparsify/maxbinfillin",
1051  "maximal fillin for binary variables (-1: unlimited)",
1052  &presoldata->maxbinfillin, FALSE, DEFAULT_MAX_BIN_FILLIN, -1, INT_MAX, NULL, NULL) );
1053 
1054  SCIP_CALL( SCIPaddIntParam(scip,
1055  "presolving/sparsify/maxintfillin",
1056  "maximal fillin for integer variables including binaries (-1: unlimited)",
1057  &presoldata->maxintfillin, FALSE, DEFAULT_MAX_INT_FILLIN, -1, INT_MAX, NULL, NULL) );
1058 
1059  SCIP_CALL( SCIPaddIntParam(scip,
1060  "presolving/sparsify/maxnonzeros",
1061  "maximal support of one equality to be used for cancelling (-1: no limit)",
1062  &presoldata->maxnonzeros, TRUE, DEFAULT_MAXNONZEROS, -1, INT_MAX, NULL, NULL) );
1063 
1064  SCIP_CALL( SCIPaddIntParam(scip,
1065  "presolving/sparsify/maxconsiderednonzeros",
1066  "maximal number of considered non-zeros within one row (-1: no limit)",
1067  &presoldata->maxconsiderednonzeros, TRUE, DEFAULT_MAXCONSIDEREDNONZEROS, -1, INT_MAX, NULL, NULL) );
1068 
1070  "presolving/sparsify/rowsort",
1071  "order in which to process inequalities ('n'o sorting, 'i'ncreasing nonzeros, 'd'ecreasing nonzeros)",
1072  &presoldata->rowsort, TRUE, DEFAULT_ROWSORT, "nid", NULL, NULL) );
1073 
1075  "presolving/sparsify/maxretrievefac",
1076  "limit on the number of useless vs. useful hashtable retrieves as a multiple of the number of constraints",
1077  &presoldata->maxretrievefac, TRUE, DEFAULT_MAXRETRIEVEFAC, 0.0, SCIP_REAL_MAX, NULL, NULL) );
1078 
1080  "presolving/sparsify/waitingfac",
1081  "number of calls to wait until next execution as a multiple of the number of useless calls",
1082  &presoldata->waitingfac, TRUE, DEFAULT_WAITINGFAC, 0.0, SCIP_REAL_MAX, NULL, NULL) );
1083 
1084  return SCIP_OKAY;
1085 }
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_presol.c:174
void SCIPmatrixPrintRow(SCIP *scip, SCIP_MATRIX *matrix, int row)
Definition: matrix.c:927
SCIP_Real SCIPgetSolvingTime(SCIP *scip)
Definition: scip_timing.c:436
struct SCIP_PresolData SCIP_PRESOLDATA
Definition: type_presol.h:37
SCIP_VAR * SCIPmatrixGetVar(SCIP_MATRIX *matrix, int col)
Definition: matrix.c:1407
#define NULL
Definition: def.h:239
int SCIPmatrixGetNRows(SCIP_MATRIX *matrix)
Definition: matrix.c:1479
SCIP_RETCODE SCIPsetPresolFree(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLFREE((*presolfree)))
Definition: scip_presol.c:225
public methods for SCIP parameter handling
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:412
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2265
public methods for memory management
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:954
#define DEFAULT_MAXRETRIEVEFAC
SCIP_CONS * SCIPmatrixGetCons(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1607
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2895
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:210
public methods for timing
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:16909
void SCIPmatrixFree(SCIP *scip, SCIP_MATRIX **matrix)
Definition: matrix.c:864
void SCIPswapPointers(void **pointer1, void **pointer2)
Definition: misc.c:9645
int SCIPpresolGetNChgCoefs(SCIP_PRESOL *presol)
Definition: presol.c:787
#define FALSE
Definition: def.h:65
public methods for presolving plugins
int SCIPgetNActivePricers(SCIP *scip)
Definition: scip_pricer.c:418
#define TRUE
Definition: def.h:64
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_PRESOLDATA * SCIPpresolGetData(SCIP_PRESOL *presol)
Definition: presol.c:502
SCIP_Real varcoef2
public methods for problem variables
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:114
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip_mem.h:138
static SCIP_DECL_HASHKEYEQ(varPairsEqual)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:142
#define DEFAULT_ENABLECOPY
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:97
#define SCIPdebugPrintCons(x, y, z)
Definition: pub_message.h:83
#define DEFAULT_WAITINGFAC
SCIP_RETCODE SCIPmatrixCreate(SCIP *scip, SCIP_MATRIX **matrixptr, SCIP_Bool *initialized, SCIP_Bool *complete)
Definition: matrix.c:437
#define SCIPdebugMsg
Definition: scip_message.h:88
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:155
#define DEFAULT_PRESERVEINTCOEFS
public methods for numerical tolerances
SCIP_RETCODE SCIPhashtableCreate(SCIP_HASHTABLE **hashtable, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
Definition: misc.c:2014
int SCIPmatrixGetRowNNonzs(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1455
cancel non-zeros of the constraint matrix
#define DEFAULT_MAXCONSIDEREDNONZEROS
SCIP_Real SCIPmatrixGetRowLhs(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1489
public methods for managing constraints
#define DEFAULT_ROWSORT
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2822
void SCIPsortIntInt(int *intarray1, int *intarray2, int len)
#define COPYSIGN
Definition: def.h:230
#define MAXSCALE
#define DEFAULT_CANCELLINEAR
void SCIPpresolSetData(SCIP_PRESOL *presol, SCIP_PRESOLDATA *presoldata)
Definition: presol.c:512
static INLINE uint32_t SCIPrealHashCode(double x)
Definition: pub_misc.h:490
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip_mem.h:143
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:128
SCIP_RETCODE SCIPsetPresolInit(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLINIT((*presolinit)))
Definition: scip_presol.c:241
int * SCIPmatrixGetRowIdxPtr(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1443
static SCIP_RETCODE cancelRow(SCIP *scip, SCIP_MATRIX *matrix, SCIP_HASHTABLE *pairtable, int rowidx, int maxcontfillin, int maxintfillin, int maxbinfillin, int maxconsiderednonzeros, SCIP_Bool preserveintcoefs, SCIP_Longint *nuseless, int *nchgcoefs, int *ncanceled, int *nfillin)
SCIP_Bool SCIPisNLPEnabled(SCIP *scip)
Definition: scip_nlp.c:246
#define DEFAULT_MAX_BIN_FILLIN
#define REALABS(x)
Definition: def.h:174
const char * SCIPmatrixGetRowName(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1467
static SCIP_DECL_PRESOLCOPY(presolCopySparsify)
#define SCIP_CALL(x)
Definition: def.h:351
#define SCIPhashTwo(a, b)
Definition: pub_misc.h:474
SCIP_RETCODE SCIPhashtableRemove(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2395
SCIP_Real * SCIPmatrixGetRowValPtr(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1431
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip_message.c:296
Definition: grphload.c:88
int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4593
public methods for constraint handler plugins and constraints
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:130
public data structures and miscellaneous methods
#define SCIP_Bool
Definition: def.h:62
#define DEFAULT_MAX_CONT_FILLIN
#define PRESOL_PRIORITY
#define PRESOL_NAME
static SCIP_DECL_HASHKEYVAL(varPairHashval)
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8096
#define MIN(x, y)
Definition: def.h:209
const char * SCIPpresolGetName(SCIP_PRESOL *presol)
Definition: presol.c:589
static SCIP_DECL_PRESOLINIT(presolInitSparsify)
Constraint handler for linear constraints in their most general form, .
void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
Definition: misc.c:2326
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
public methods for matrix
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip_probing.c:152
public methods for variable pricer plugins
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:2064
#define SCIP_REAL_MAX
Definition: def.h:151
public methods for nonlinear relaxations
SCIP_Real * r
Definition: circlepacking.c:50
methods for sorting joint arrays of various types
SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
#define PRESOL_MAXROUNDS
SCIP_VAR ** b
Definition: circlepacking.c:56
public methods for presolvers
general public methods
#define MAX(x, y)
Definition: def.h:208
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPaddCharParam(SCIP *scip, const char *name, const char *desc, char *valueptr, SCIP_Bool isadvanced, char defaultvalue, const char *allowedvalues, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:239
SCIP_Real SCIPmatrixGetRowRhs(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1501
int SCIPgetNConss(SCIP *scip)
Definition: scip_prob.c:3094
public methods for the probing mode
static void updateFailureStatistic(SCIP_PRESOLDATA *presoldata, SCIP_Bool success)
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1187
SCIP_RETCODE SCIPsetPresolCopy(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLCOPY((*presolcopy)))
Definition: scip_presol.c:209
public methods for message output
SCIP_VAR * a
Definition: circlepacking.c:57
#define SCIP_Real
Definition: def.h:150
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip_general.c:739
SCIP_Real varcoef1
public methods for message handling
#define DEFAULT_MAX_INT_FILLIN
int SCIPmatrixGetColNDownlocks(SCIP_MATRIX *matrix, int col)
Definition: matrix.c:1395
#define PRESOL_TIMING
#define SCIP_Longint
Definition: def.h:135
#define DEFAULT_MAXNONZEROS
static SCIP_DECL_PRESOLFREE(presolFreeSparsify)
int SCIPmatrixGetNNonzs(SCIP_MATRIX *matrix)
Definition: matrix.c:1525
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
int SCIPmatrixGetColNUplocks(SCIP_MATRIX *matrix, int col)
Definition: matrix.c:1383
SCIP_RETCODE SCIPincludePresolSparsify(SCIP *scip)
#define SCIPcombineTwoInt(a, b)
Definition: pub_misc.h:480
public methods for global and local (sub)problems
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:16920
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:211
int SCIPmatrixGetNColumns(SCIP_MATRIX *matrix)
Definition: matrix.c:1351
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:129
void SCIPsortIntReal(int *intarray, SCIP_Real *realarray, int len)
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:134
static SCIP_DECL_PRESOLEXEC(presolExecSparsify)
memory allocation routines
#define PRESOL_DESC