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