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