Scippy

    SCIP

    Solving Constraint Integer Programs

    presol_dualagg.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-2025 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_dualagg.c
    26 * @ingroup DEFPLUGINS_PRESOL
    27 * @brief aggregate variables by dual arguments
    28 * @author Dieter Weninger
    29 *
    30 * This presolver looks for variables which could not be handled by
    31 * duality fixing because of one up-/downlock.
    32 * If the constraint which delivers the up-/downlock has
    33 * a specific structure, we can aggregate the corresponding variable.
    34 *
    35 * In more detail (for a minimization problem and the case of only one uplock):
    36 *
    37 * Given a variable \f$x_i\f$ with \f$c_i \leq 0\f$ and only one up lock (originating from a constraint c),
    38 * we are looking for a binary variable \f$x_j\f$ such that:
    39 * 1. if \f$x_j = 0\f$, constraint c can only be fulfilled for \f$x_i = lb_i\f$, and
    40 * 2. if \f$x_j = 1\f$, constraint c becomes redundant and \f$x_i\f$ can be dual-fixed to its upper bound \f$ub_i\f$
    41 * (or vice versa). Then we can perform the following aggregation: \f$x_i = lb_i + x_j (ub_i - lb_i)\f$.
    42 *
    43 * Similar arguments apply for the case of only one down lock and \f$c_i \geq 0\f$.
    44 */
    45
    46/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    47
    49#include "scip/presol_dualagg.h"
    50#include "scip/pub_matrix.h"
    51#include "scip/pub_message.h"
    52#include "scip/pub_presol.h"
    53#include "scip/pub_var.h"
    54#include "scip/scip_general.h"
    55#include "scip/scip_mem.h"
    56#include "scip/scip_message.h"
    57#include "scip/scip_nlp.h"
    58#include "scip/scip_numerics.h"
    59#include "scip/scip_presol.h"
    60#include "scip/scip_pricer.h"
    61#include "scip/scip_prob.h"
    62#include "scip/scip_probing.h"
    63#include "scip/scip_var.h"
    64
    65#define PRESOL_NAME "dualagg"
    66#define PRESOL_DESC "aggregate variables by dual arguments"
    67#define PRESOL_PRIORITY -12000 /**< priority of the presolver (>= 0: before, < 0: after constraint handlers) */
    68#define PRESOL_MAXROUNDS 0 /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */
    69#define PRESOL_TIMING SCIP_PRESOLTIMING_EXHAUSTIVE /* timing of the presolver (fast, medium, or exhaustive) */
    70
    71/** type of aggregation */
    73{
    74 BIN0UBOUND = -1, /**< x_j = u_j + (l_j-u_j)x_i with x_i binary and x_j aggregation variable */
    75 NOAGG = 0, /**< do not aggregate */
    76 BIN0LBOUND = 1 /**< x_j = l_j + (u_j-l_j)x_i with x_i binary and x_j aggregation variable */
    77};
    78typedef enum AggrType AGGRTYPE;
    79
    80/*
    81 * Local methods
    82 */
    83
    84/** find row which leads to the uplock of the given variable */
    85static
    87 SCIP_MATRIX* matrix, /**< constraint matrix */
    88 int aggvaridx, /**< index of variable which should be aggregated */
    89 int* rowidx, /**< pointer to store row index of uplock */
    90 SCIP_Real* coef /**< pointer to store coefficient of variable */
    91 )
    92{
    93 int* colpnt;
    94 int* colend;
    95 SCIP_Real* valpnt;
    96
    97 assert(rowidx != NULL);
    98 assert(coef != NULL);
    99 assert(SCIPmatrixGetColNUplocks(matrix, aggvaridx) == 1);
    100
    101 /* get nonzero entries of the variable in the matrix */
    102 colpnt = SCIPmatrixGetColIdxPtr(matrix, aggvaridx);
    103 colend = colpnt + SCIPmatrixGetColNNonzs(matrix, aggvaridx);
    104 valpnt = SCIPmatrixGetColValPtr(matrix, aggvaridx);
    105
    106 /* iterate over all non-zero coefficients of the column */
    107 *rowidx = -1;
    108 for(; (colpnt < colend); colpnt++, valpnt++)
    109 {
    110 /* currently we support only >= relation */
    111 if( !SCIPmatrixIsRowRhsInfinity(matrix, *colpnt) )
    112 break;
    113
    114 /* coef < 0 for >= relation: this row provides an uplock for the variable */
    115 if( *valpnt < 0.0 )
    116 {
    117 *rowidx = *colpnt;
    118 *coef = *valpnt;
    119 break;
    120 }
    121 }
    122#ifndef NDEBUG
    123 /* in debug mode, we check that the lock number is correct */
    124 assert(colpnt < colend);
    125 for(colpnt++, valpnt++; (colpnt < colend); colpnt++, valpnt++)
    126 {
    127 assert(*valpnt > 0.0);
    128 }
    129#endif
    130}
    131
    132/** find row which leads to the downlock of the given variable */
    133static
    135 SCIP_MATRIX* matrix, /**< constraint matrix */
    136 int aggvaridx, /**< index of variable which should be aggregated */
    137 int* rowidx, /**< pointer to store row index of downlock */
    138 SCIP_Real* coef /**< pointer to store coefficient of variable */
    139 )
    140{
    141 int* colpnt;
    142 int* colend;
    143 SCIP_Real* valpnt;
    144
    145 assert(rowidx != NULL);
    146 assert(coef != NULL);
    147 assert(SCIPmatrixGetColNDownlocks(matrix, aggvaridx) == 1);
    148
    149 /* get nonzero entries of the variable in the matrix */
    150 colpnt = SCIPmatrixGetColIdxPtr(matrix, aggvaridx);
    151 colend = colpnt + SCIPmatrixGetColNNonzs(matrix, aggvaridx);
    152 valpnt = SCIPmatrixGetColValPtr(matrix, aggvaridx);
    153
    154 /* iterate over all non-zero coefficients of the column */
    155 *rowidx = -1;
    156 for(; (colpnt < colend); colpnt++, valpnt++)
    157 {
    158 /* currently we support only >= relation */
    159 if( !SCIPmatrixIsRowRhsInfinity(matrix, *colpnt) )
    160 break;
    161
    162 /* coef > 0 for >= relation: this row provides a downlock for the variable */
    163 if( *valpnt > 0.0 )
    164 {
    165 *rowidx = *colpnt;
    166 *coef = *valpnt;
    167 break;
    168 }
    169 }
    170#ifndef NDEBUG
    171 /* in debug mode, we check that the lock number is correct */
    172 assert(colpnt < colend);
    173 for(colpnt++, valpnt++; (colpnt < colend); colpnt++, valpnt++)
    174 {
    175 assert(*valpnt < 0.0);
    176 }
    177#endif
    178}
    179
    180/** find fitting binary variable aggregation for uplock case */
    181static
    183 SCIP* scip, /**< SCIP main data structure */
    184 SCIP_MATRIX* matrix, /**< constraint matrix */
    185 int aggvaridx, /**< index of variable which should be aggregated */
    186 int* binvaridx, /**< pointer to store index of binary variable */
    187 AGGRTYPE* aggtype /**< pointer to store type of aggregation */
    188 )
    189{
    190 int rowidx;
    191 SCIP_Real coef;
    192 int* rowpnt;
    193 int* rowend;
    194 SCIP_Real* valpnt;
    195 SCIP_Real minact;
    196 SCIP_Real maxact;
    197 SCIP_Real lhs;
    198 SCIP_Real lb;
    199
    200 assert(binvaridx != NULL);
    201 assert(aggtype != NULL);
    202
    203 *binvaridx = -1;
    204 *aggtype = NOAGG;
    205
    206 getUplockRowIdx(matrix, aggvaridx, &rowidx, &coef);
    207
    208 if( rowidx < 0 )
    209 return;
    210
    211 assert(coef < 0);
    212 minact = SCIPmatrixGetRowMinActivity(matrix, rowidx);
    213 maxact = SCIPmatrixGetRowMaxActivity(matrix, rowidx);
    214
    215 if( SCIPisInfinity(scip, -minact) || SCIPisInfinity(scip, maxact) )
    216 return;
    217
    218 lhs = SCIPmatrixGetRowLhs(matrix, rowidx);
    219 lb = SCIPmatrixGetColLb(matrix, aggvaridx);
    220
    221 /* search for appropriate binary variables */
    222 rowpnt = SCIPmatrixGetRowIdxPtr(matrix, rowidx);
    223 rowend = rowpnt + SCIPmatrixGetRowNNonzs(matrix, rowidx);
    224 valpnt = SCIPmatrixGetRowValPtr(matrix, rowidx);
    225 for( ; (rowpnt < rowend); rowpnt++, valpnt++ )
    226 {
    227 SCIP_VAR* var;
    228
    229 if( *rowpnt == aggvaridx )
    230 continue;
    231
    232 var = SCIPmatrixGetVar(matrix, *rowpnt);
    233
    234 /* avoid cases where the binary variable has lb=ub=1 or lb=ub=0 */
    236 && SCIPmatrixGetColLb(matrix, *rowpnt) < 0.5 && SCIPmatrixGetColUb(matrix, *rowpnt) > 0.5 )
    237 {
    238 SCIP_Real bincoef;
    239 bincoef = *valpnt;
    240
    241 if( bincoef < 0 )
    242 {
    243 /* binvar = 0 implies that the constraint is redundant */
    244 if( SCIPisGE(scip, minact-bincoef, lhs) )
    245 {
    246 /* binvar = 1 implies that aggvar = lb */
    247 SCIP_Real bnd;
    248 bnd = (lhs - maxact + coef*lb - bincoef) / coef;
    249 if( SCIPisGE(scip, lb, bnd) )
    250 {
    251 *binvaridx = *rowpnt;
    252 *aggtype = BIN0UBOUND;
    253 break;
    254 }
    255 }
    256 }
    257
    258 if( bincoef > 0 )
    259 {
    260 /* binvar = 1 implies that the constraint is redundant */
    261 if( SCIPisGE(scip, minact+bincoef, lhs) )
    262 {
    263 /* binvar = 0 implies that aggvar = lb */
    264 SCIP_Real bnd;
    265 bnd = (lhs - maxact + coef*lb + bincoef) / coef;
    266 if( SCIPisGE(scip, lb, bnd) )
    267 {
    268 *binvaridx = *rowpnt;
    269 *aggtype = BIN0LBOUND;
    270 }
    271 }
    272 }
    273 }
    274 }
    275}
    276
    277/** find fitting binary variable aggregation for downlock case */
    278static
    280 SCIP* scip, /**< SCIP main data structure */
    281 SCIP_MATRIX* matrix, /**< constraint matrix */
    282 int aggvaridx, /**< index of variable which should be aggregated */
    283 int* binvaridx, /**< pointer to store index of binary variable */
    284 AGGRTYPE* aggtype /**< pointer to store type of aggregation */
    285 )
    286{
    287 int rowidx;
    288 SCIP_Real coef;
    289 int* rowpnt;
    290 int* rowend;
    291 SCIP_Real* valpnt;
    292 SCIP_Real minact;
    293 SCIP_Real maxact;
    294 SCIP_Real lhs;
    295 SCIP_Real ub;
    296
    297 assert(binvaridx != NULL);
    298 assert(aggtype != NULL);
    299
    300 *binvaridx = -1;
    301 *aggtype = NOAGG;
    302
    303 getDownlockRowIdx(matrix, aggvaridx, &rowidx, &coef);
    304
    305 if( rowidx < 0 )
    306 return;
    307
    308 assert(coef > 0);
    309 minact = SCIPmatrixGetRowMinActivity(matrix, rowidx);
    310 maxact = SCIPmatrixGetRowMaxActivity(matrix, rowidx);
    311
    312 if( SCIPisInfinity(scip, -minact) || SCIPisInfinity(scip, maxact) )
    313 return;
    314
    315 lhs = SCIPmatrixGetRowLhs(matrix, rowidx);
    316 ub = SCIPmatrixGetColUb(matrix, aggvaridx);
    317
    318 /* search for appropriate binary variables */
    319 rowpnt = SCIPmatrixGetRowIdxPtr(matrix, rowidx);
    320 rowend = rowpnt + SCIPmatrixGetRowNNonzs(matrix, rowidx);
    321 valpnt = SCIPmatrixGetRowValPtr(matrix, rowidx);
    322 for( ; (rowpnt < rowend); rowpnt++, valpnt++ )
    323 {
    324 SCIP_VAR* var;
    325
    326 if( *rowpnt == aggvaridx )
    327 continue;
    328
    329 var = SCIPmatrixGetVar(matrix, *rowpnt);
    330
    331 /* avoid cases where the binary variable has lb=ub=1 or lb=ub=0 */
    333 && SCIPmatrixGetColLb(matrix, *rowpnt) < 0.5 && SCIPmatrixGetColUb(matrix, *rowpnt) > 0.5 )
    334 {
    335 SCIP_Real bincoef;
    336
    337 bincoef = *valpnt;
    338
    339 if( bincoef < 0 )
    340 {
    341 /* binvar = 0 implies that the constraint is redundant */
    342 if( SCIPisGE(scip, minact-bincoef, lhs) )
    343 {
    344 /* binvar = 1 implies that aggvar = ub */
    345 SCIP_Real bnd;
    346 bnd = (lhs - maxact + coef*ub - bincoef) / coef;
    347 if( SCIPisGE(scip, bnd, ub) )
    348 {
    349 *binvaridx = *rowpnt;
    350 *aggtype = BIN0LBOUND;
    351 break;
    352 }
    353 }
    354 }
    355
    356 if( bincoef > 0 )
    357 {
    358 /* binvar = 1 implies that the constraint is redundant */
    359 if( SCIPisGE(scip, minact+bincoef, lhs) )
    360 {
    361 /* binvar = 0 implies that aggvar = ub */
    362 SCIP_Real bnd;
    363 bnd = (lhs - maxact + coef*ub + bincoef) / coef;
    364 if( SCIPisGE(scip, bnd, ub) )
    365 {
    366 *binvaridx = *rowpnt;
    367 *aggtype = BIN0UBOUND;
    368 break;
    369 }
    370 }
    371 }
    372 }
    373 }
    374}
    375
    376/** find variable aggregations for uplock case */
    377static
    379 SCIP* scip, /**< SCIP main data structure */
    380 SCIP_MATRIX* matrix, /**< constraint matrix */
    381 int* nvaragg, /**< number of redundant variables */
    382 AGGRTYPE* aggtypes, /**< type of aggregations (in same order as variables in matrix) */
    383 SCIP_VAR** binvars /**< pointers to the binary variables (in same order as variables in matrix) */
    384 )
    385{
    386 int nvars;
    387 int i;
    388
    389 assert(scip != NULL);
    390 assert(matrix != NULL);
    391 assert(nvaragg != NULL);
    392 assert(aggtypes != NULL);
    393 assert(binvars != NULL);
    394
    395 nvars = SCIPmatrixGetNColumns(matrix);
    396
    397 for( i = 0; i < nvars; i++ )
    398 {
    399 /* column has only one uplock which keeps it from being fixed by duality fixing */
    400 if( SCIPmatrixGetColNUplocks(matrix, i) == 1 &&
    401 SCIPisLE(scip, SCIPvarGetObj(SCIPmatrixGetVar(matrix, i)), 0.0) )
    402 {
    403 SCIP_Real lb;
    404 SCIP_Real ub;
    405
    406 lb = SCIPmatrixGetColLb(matrix, i);
    407 ub = SCIPmatrixGetColUb(matrix, i);
    408 assert(lb == SCIPvarGetLbGlobal(SCIPmatrixGetVar(matrix, i))); /*lint !e777*/
    409 assert(ub == SCIPvarGetUbGlobal(SCIPmatrixGetVar(matrix, i))); /*lint !e777*/
    410
    411 /* the variable needs to have finite bounds to allow an agregation */
    412 if( !SCIPisInfinity(scip, -lb) && !SCIPisInfinity(scip, ub) )
    413 {
    414 int binvaridx;
    415 AGGRTYPE aggtype;
    416
    417 getBinVarIdxInUplockRow(scip, matrix, i, &binvaridx, &aggtype);
    418
    419 if( binvaridx >= 0 )
    420 {
    421 aggtypes[i] = aggtype;
    422 binvars[i] = SCIPmatrixGetVar(matrix, binvaridx);
    423 (*nvaragg)++;
    424 }
    425 }
    426 }
    427 }
    428
    429 return SCIP_OKAY;
    430}
    431
    432/** find variable aggregations for downlock case */
    433static
    435 SCIP* scip, /**< SCIP main data structure */
    436 SCIP_MATRIX* matrix, /**< constraint matrix */
    437 int* nvaragg, /**< number of redundant variables */
    438 AGGRTYPE* aggtypes, /**< type of aggregations (in same order as variables in matrix) */
    439 SCIP_VAR** binvars /**< pointers to the binary variables (in same order as variables in matrix) */
    440 )
    441{
    442 int nvars;
    443 int i;
    444
    445 assert(scip != NULL);
    446 assert(matrix != NULL);
    447 assert(nvaragg != NULL);
    448 assert(aggtypes != NULL);
    449 assert(binvars != NULL);
    450
    451 nvars = SCIPmatrixGetNColumns(matrix);
    452
    453 for( i = 0; i < nvars; i++ )
    454 {
    455 /* column has only one downlock which keeps it from being fixed by duality fixing;
    456 * only handle variable if it was not yet aggregated due to a single uplock
    457 */
    458 if( SCIPmatrixGetColNDownlocks(matrix, i) == 1 &&
    459 SCIPisGE(scip, SCIPvarGetObj(SCIPmatrixGetVar(matrix, i)), 0.0) &&
    460 aggtypes[i] == NOAGG )
    461 {
    462 SCIP_Real lb;
    463 SCIP_Real ub;
    464
    465 lb = SCIPmatrixGetColLb(matrix, i);
    466 ub = SCIPmatrixGetColUb(matrix, i);
    467 assert(lb == SCIPvarGetLbGlobal(SCIPmatrixGetVar(matrix, i))); /*lint !e777*/
    468 assert(ub == SCIPvarGetUbGlobal(SCIPmatrixGetVar(matrix, i))); /*lint !e777*/
    469
    470 /* the variable needs to have finite bounds to allow an agregation */
    471 if( !SCIPisInfinity(scip, -lb) && !SCIPisInfinity(scip, ub) )
    472 {
    473 int binvaridx;
    474 AGGRTYPE aggtype;
    475 getBinVarIdxInDownlockRow(scip, matrix, i, &binvaridx, &aggtype);
    476
    477 if( binvaridx >= 0 )
    478 {
    479 aggtypes[i] = aggtype;
    480 binvars[i] = SCIPmatrixGetVar(matrix, binvaridx);
    481 (*nvaragg)++;
    482 }
    483 }
    484 }
    485 }
    486
    487 return SCIP_OKAY;
    488}
    489
    490/*
    491 * Callback methods of presolver
    492 */
    493
    494/** copy method for presolver plugins (called when SCIP copies plugins) */
    495static
    496SCIP_DECL_PRESOLCOPY(presolCopyDualagg)
    497{ /*lint --e{715}*/
    498 assert(scip != NULL);
    499 assert(presol != NULL);
    500 assert(strcmp(SCIPpresolGetName(presol), PRESOL_NAME) == 0);
    501
    502 /* call inclusion method of presolver */
    504
    505 return SCIP_OKAY;
    506}
    507
    508/** execution method of presolver */
    509static
    510SCIP_DECL_PRESOLEXEC(presolExecDualagg)
    511{ /*lint --e{715}*/
    512 SCIP_MATRIX* matrix;
    513 SCIP_Bool initialized;
    514 SCIP_Bool complete;
    515 SCIP_Bool infeasible;
    516
    517 assert(result != NULL);
    518 *result = SCIP_DIDNOTRUN;
    519
    521 return SCIP_OKAY;
    522
    524 return SCIP_OKAY;
    525
    526 if( SCIPgetNBinVars(scip) == 0 )
    527 return SCIP_OKAY;
    528
    530 return SCIP_OKAY;
    531
    532 *result = SCIP_DIDNOTFIND;
    533
    534 matrix = NULL;
    535
    536 SCIP_CALL( SCIPmatrixCreate(scip, &matrix, TRUE, &initialized, &complete, &infeasible,
    537 naddconss, ndelconss, nchgcoefs, nchgbds, nfixedvars) );
    538
    539 /* if infeasibility was detected during matrix creation, return here */
    540 if( infeasible )
    541 {
    542 if( initialized )
    543 SCIPmatrixFree(scip, &matrix);
    544
    545 *result = SCIP_CUTOFF;
    546 return SCIP_OKAY;
    547 }
    548
    549 /* we only work on pure MIPs currently */
    550 if( initialized && complete )
    551 {
    552 AGGRTYPE* aggtypes;
    553 SCIP_VAR** binvars;
    554 int nvaragg;
    555 int ncols;
    556
    557 ncols = SCIPmatrixGetNColumns(matrix);
    558 nvaragg = 0;
    559
    560 SCIP_CALL( SCIPallocBufferArray(scip, &aggtypes, ncols) );
    561 BMSclearMemoryArray(aggtypes, ncols);
    562
    563 SCIP_CALL( SCIPallocBufferArray(scip, &binvars, ncols) );
    564 SCIPdebug( BMSclearMemoryArray(binvars, ncols) );
    565
    566 /* search for aggregations */
    567 SCIP_CALL( findUplockAggregations(scip, matrix, &nvaragg, aggtypes, binvars) );
    568 SCIP_CALL( findDownlockAggregations(scip, matrix, &nvaragg, aggtypes, binvars) );
    569
    570 /* apply aggregations, if we found any */
    571 if( nvaragg > 0 )
    572 {
    573 int v;
    574
    575 for( v = 0; v < ncols; v++ )
    576 {
    577 if( aggtypes[v] != NOAGG )
    578 {
    579 SCIP_Bool redundant;
    580 SCIP_Bool aggregated;
    581 SCIP_Real ub;
    582 SCIP_Real lb;
    583
    584 ub = SCIPmatrixGetColUb(matrix, v);
    585 lb = SCIPmatrixGetColLb(matrix, v);
    586
    587 /* aggregate variable */
    588 assert(binvars[v] != NULL);
    589 if( aggtypes[v] == BIN0UBOUND )
    590 {
    591 SCIP_CALL( SCIPaggregateVars(scip, SCIPmatrixGetVar(matrix, v), binvars[v], 1.0, ub-lb,
    592 ub, &infeasible, &redundant, &aggregated) );
    593 }
    594 else
    595 {
    596 assert(aggtypes[v] == BIN0LBOUND);
    597 SCIP_CALL( SCIPaggregateVars(scip, SCIPmatrixGetVar(matrix, v), binvars[v], 1.0, lb-ub,
    598 lb, &infeasible, &redundant, &aggregated) );
    599 }
    600
    601 /* infeasible aggregation */
    602 if( infeasible )
    603 {
    604 SCIPdebugMsg(scip, " -> infeasible aggregation\n");
    605 *result = SCIP_CUTOFF;
    606 return SCIP_OKAY;
    607 }
    608
    609 if( aggregated )
    610 (*naggrvars)++;
    611 }
    612 }
    613
    614 /* set result pointer */
    615 if( (*naggrvars) > 0 )
    616 *result = SCIP_SUCCESS;
    617 }
    618
    619 SCIPfreeBufferArray(scip, &binvars);
    620 SCIPfreeBufferArray(scip, &aggtypes);
    621 }
    622
    623 SCIPmatrixFree(scip, &matrix);
    624
    625 return SCIP_OKAY;
    626}
    627
    628/*
    629 * presolver specific interface methods
    630 */
    631
    632/** creates the dualagg presolver and includes it in SCIP */
    634 SCIP* scip /**< SCIP data structure */
    635 )
    636{
    637 SCIP_PRESOL* presol;
    638
    639 /* include presolver */
    641 PRESOL_TIMING, presolExecDualagg, NULL) );
    642
    643 /* set non fundamental callbacks via setter functions */
    644 SCIP_CALL( SCIPsetPresolCopy(scip, presol, presolCopyDualagg) );
    645
    646 return SCIP_OKAY;
    647}
    #define NULL
    Definition: def.h:248
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_Bool SCIPisStopped(SCIP *scip)
    Definition: scip_general.c:759
    SCIP_STAGE SCIPgetStage(SCIP *scip)
    Definition: scip_general.c:444
    int SCIPgetNBinVars(SCIP *scip)
    Definition: scip_prob.c:2293
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    SCIP_RETCODE SCIPincludePresolDualagg(SCIP *scip)
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    SCIP_Bool SCIPisNLPEnabled(SCIP *scip)
    Definition: scip_nlp.c:74
    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_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23498
    SCIP_RETCODE SCIPaggregateVars(SCIP *scip, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_Real scalarx, SCIP_Real scalary, SCIP_Real rhs, SCIP_Bool *infeasible, SCIP_Bool *redundant, SCIP_Bool *aggregated)
    Definition: scip_var.c:10550
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23900
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23453
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24142
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24120
    SCIP_Bool SCIPallowStrongDualReds(SCIP *scip)
    Definition: scip_var.c:10984
    int * SCIPmatrixGetColIdxPtr(SCIP_MATRIX *matrix, int col)
    Definition: matrix.c:1873
    int SCIPmatrixGetRowNNonzs(SCIP_MATRIX *matrix, int row)
    Definition: matrix.c:2013
    int SCIPmatrixGetColNDownlocks(SCIP_MATRIX *matrix, int col)
    Definition: matrix.c:1941
    int SCIPmatrixGetColNNonzs(SCIP_MATRIX *matrix, int col)
    Definition: matrix.c:1885
    SCIP_Bool SCIPmatrixIsRowRhsInfinity(SCIP_MATRIX *matrix, int row)
    Definition: matrix.c:2095
    int SCIPmatrixGetColNUplocks(SCIP_MATRIX *matrix, int col)
    Definition: matrix.c:1929
    SCIP_Real SCIPmatrixGetRowMaxActivity(SCIP_MATRIX *matrix, int row)
    Definition: matrix.c:2129
    SCIP_Real SCIPmatrixGetColLb(SCIP_MATRIX *matrix, int col)
    Definition: matrix.c:1918
    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 * SCIPmatrixGetColValPtr(SCIP_MATRIX *matrix, int col)
    Definition: matrix.c:1861
    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_Real SCIPmatrixGetRowMinActivity(SCIP_MATRIX *matrix, int row)
    Definition: matrix.c:2117
    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
    SCIP_Real SCIPmatrixGetColUb(SCIP_MATRIX *matrix, int col)
    Definition: matrix.c:1907
    memory allocation routines
    #define BMSclearMemoryArray(ptr, num)
    Definition: memory.h:130
    #define PRESOL_NAME
    static void getBinVarIdxInDownlockRow(SCIP *scip, SCIP_MATRIX *matrix, int aggvaridx, int *binvaridx, AGGRTYPE *aggtype)
    static void getUplockRowIdx(SCIP_MATRIX *matrix, int aggvaridx, int *rowidx, SCIP_Real *coef)
    static SCIP_DECL_PRESOLCOPY(presolCopyDualagg)
    static void getDownlockRowIdx(SCIP_MATRIX *matrix, int aggvaridx, int *rowidx, SCIP_Real *coef)
    #define PRESOL_PRIORITY
    static SCIP_RETCODE findUplockAggregations(SCIP *scip, SCIP_MATRIX *matrix, int *nvaragg, AGGRTYPE *aggtypes, SCIP_VAR **binvars)
    AggrType
    @ BIN0UBOUND
    @ BIN0LBOUND
    @ NOAGG
    static void getBinVarIdxInUplockRow(SCIP *scip, SCIP_MATRIX *matrix, int aggvaridx, int *binvaridx, AGGRTYPE *aggtype)
    static SCIP_DECL_PRESOLEXEC(presolExecDualagg)
    #define PRESOL_MAXROUNDS
    #define PRESOL_TIMING
    static SCIP_RETCODE findDownlockAggregations(SCIP *scip, SCIP_MATRIX *matrix, int *nvaragg, AGGRTYPE *aggtypes, SCIP_VAR **binvars)
    enum AggrType AGGRTYPE
    #define PRESOL_DESC
    aggregate variables by dual arguments
    public methods for matrix
    public methods for message output
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    public methods for presolvers
    public methods for problem variables
    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 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 SCIP variables
    @ 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
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_STAGE_PRESOLVING
    Definition: type_set.h:49
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64