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 &&
237 SCIPmatrixGetColUb(matrix, *rowpnt) > 0.5 )
238 {
239 SCIP_Real bincoef;
240 bincoef = *valpnt;
241
242 if( bincoef < 0 )
243 {
244 /* binvar = 0 implies that the constraint is redundant */
245 if( SCIPisGE(scip, minact-bincoef, lhs) )
246 {
247 /* binvar = 1 implies that aggvar = lb */
248 SCIP_Real bnd;
249 bnd = (lhs - maxact + coef*lb - bincoef) / coef;
250 if( SCIPisGE(scip, lb, bnd) )
251 {
252 *binvaridx = *rowpnt;
253 *aggtype = BIN0UBOUND;
254 break;
255 }
256 }
257 }
258
259 if( bincoef > 0 )
260 {
261 /* binvar = 1 implies that the constraint is redundant */
262 if( SCIPisGE(scip, minact+bincoef, lhs) )
263 {
264 /* binvar = 0 implies that aggvar = lb */
265 SCIP_Real bnd;
266 bnd = (lhs - maxact + coef*lb + bincoef) / coef;
267 if( SCIPisGE(scip, lb, bnd) )
268 {
269 *binvaridx = *rowpnt;
270 *aggtype = BIN0LBOUND;
271 }
272 }
273 }
274 }
275 }
276}
277
278/** find fitting binary variable aggregation for downlock case */
279static
281 SCIP* scip, /**< SCIP main data structure */
282 SCIP_MATRIX* matrix, /**< constraint matrix */
283 int aggvaridx, /**< index of variable which should be aggregated */
284 int* binvaridx, /**< pointer to store index of binary variable */
285 AGGRTYPE* aggtype /**< pointer to store type of aggregation */
286 )
287{
288 int rowidx;
289 SCIP_Real coef;
290 int* rowpnt;
291 int* rowend;
292 SCIP_Real* valpnt;
293 SCIP_Real minact;
294 SCIP_Real maxact;
295 SCIP_Real lhs;
296 SCIP_Real ub;
297
298 assert(binvaridx != NULL);
299 assert(aggtype != NULL);
300
301 *binvaridx = -1;
302 *aggtype = NOAGG;
303
304 getDownlockRowIdx(matrix, aggvaridx, &rowidx, &coef);
305
306 if( rowidx < 0 )
307 return;
308
309 assert(coef > 0);
310 minact = SCIPmatrixGetRowMinActivity(matrix, rowidx);
311 maxact = SCIPmatrixGetRowMaxActivity(matrix, rowidx);
312
313 if( SCIPisInfinity(scip, -minact) || SCIPisInfinity(scip, maxact) )
314 return;
315
316 lhs = SCIPmatrixGetRowLhs(matrix, rowidx);
317 ub = SCIPmatrixGetColUb(matrix, aggvaridx);
318
319 /* search for appropriate binary variables */
320 rowpnt = SCIPmatrixGetRowIdxPtr(matrix, rowidx);
321 rowend = rowpnt + SCIPmatrixGetRowNNonzs(matrix, rowidx);
322 valpnt = SCIPmatrixGetRowValPtr(matrix, rowidx);
323 for( ; (rowpnt < rowend); rowpnt++, valpnt++ )
324 {
325 SCIP_VAR* var;
326
327 if( *rowpnt == aggvaridx )
328 continue;
329
330 var = SCIPmatrixGetVar(matrix, *rowpnt);
331
332 /* avoid cases where the binary variable has lb=ub=1 or lb=ub=0 */
334 SCIPmatrixGetColLb(matrix, *rowpnt) < 0.5 &&
335 SCIPmatrixGetColUb(matrix, *rowpnt) > 0.5 )
336 {
337 SCIP_Real bincoef;
338
339 bincoef = *valpnt;
340
341 if( bincoef < 0 )
342 {
343 /* binvar = 0 implies that the constraint is redundant */
344 if( SCIPisGE(scip, minact-bincoef, lhs) )
345 {
346 /* binvar = 1 implies that aggvar = ub */
347 SCIP_Real bnd;
348 bnd = (lhs - maxact + coef*ub - bincoef) / coef;
349 if( SCIPisGE(scip, bnd, ub) )
350 {
351 *binvaridx = *rowpnt;
352 *aggtype = BIN0LBOUND;
353 break;
354 }
355 }
356 }
357
358 if( bincoef > 0 )
359 {
360 /* binvar = 1 implies that the constraint is redundant */
361 if( SCIPisGE(scip, minact+bincoef, lhs) )
362 {
363 /* binvar = 0 implies that aggvar = ub */
364 SCIP_Real bnd;
365 bnd = (lhs - maxact + coef*ub + bincoef) / coef;
366 if( SCIPisGE(scip, bnd, ub) )
367 {
368 *binvaridx = *rowpnt;
369 *aggtype = BIN0UBOUND;
370 break;
371 }
372 }
373 }
374 }
375 }
376}
377
378/** find variable aggregations for uplock case */
379static
381 SCIP* scip, /**< SCIP main data structure */
382 SCIP_MATRIX* matrix, /**< constraint matrix */
383 int* nvaragg, /**< number of redundant variables */
384 AGGRTYPE* aggtypes, /**< type of aggregations (in same order as variables in matrix) */
385 SCIP_VAR** binvars /**< pointers to the binary variables (in same order as variables in matrix) */
386 )
387{
388 int nvars;
389 int i;
390
391 assert(scip != NULL);
392 assert(matrix != NULL);
393 assert(nvaragg != NULL);
394 assert(aggtypes != NULL);
395 assert(binvars != NULL);
396
397 nvars = SCIPmatrixGetNColumns(matrix);
398
399 for( i = 0; i < nvars; i++ )
400 {
401 /* column has only one uplock which keeps it from being fixed by duality fixing */
402 if( SCIPmatrixGetColNUplocks(matrix, i) == 1 &&
403 SCIPisLE(scip, SCIPvarGetObj(SCIPmatrixGetVar(matrix, i)), 0.0) )
404 {
405 SCIP_Real lb;
406 SCIP_Real ub;
407
408 lb = SCIPmatrixGetColLb(matrix, i);
409 ub = SCIPmatrixGetColUb(matrix, i);
410 assert(lb == SCIPvarGetLbGlobal(SCIPmatrixGetVar(matrix, i))); /*lint !e777*/
411 assert(ub == SCIPvarGetUbGlobal(SCIPmatrixGetVar(matrix, i))); /*lint !e777*/
412
413 /* the variable needs to have finite bounds to allow an agregation */
414 if( !SCIPisInfinity(scip, -lb) && !SCIPisInfinity(scip, ub) )
415 {
416 int binvaridx;
417 AGGRTYPE aggtype;
418
419 getBinVarIdxInUplockRow(scip, matrix, i, &binvaridx, &aggtype);
420
421 if( binvaridx >= 0 )
422 {
423 aggtypes[i] = aggtype;
424 binvars[i] = SCIPmatrixGetVar(matrix, binvaridx);
425 (*nvaragg)++;
426 }
427 }
428 }
429 }
430
431 return SCIP_OKAY;
432}
433
434/** find variable aggregations for downlock case */
435static
437 SCIP* scip, /**< SCIP main data structure */
438 SCIP_MATRIX* matrix, /**< constraint matrix */
439 int* nvaragg, /**< number of redundant variables */
440 AGGRTYPE* aggtypes, /**< type of aggregations (in same order as variables in matrix) */
441 SCIP_VAR** binvars /**< pointers to the binary variables (in same order as variables in matrix) */
442 )
443{
444 int nvars;
445 int i;
446
447 assert(scip != NULL);
448 assert(matrix != NULL);
449 assert(nvaragg != NULL);
450 assert(aggtypes != NULL);
451 assert(binvars != NULL);
452
453 nvars = SCIPmatrixGetNColumns(matrix);
454
455 for( i = 0; i < nvars; i++ )
456 {
457 /* column has only one downlock which keeps it from being fixed by duality fixing;
458 * only handle variable if it was not yet aggregated due to a single uplock
459 */
460 if( SCIPmatrixGetColNDownlocks(matrix, i) == 1 &&
461 SCIPisGE(scip, SCIPvarGetObj(SCIPmatrixGetVar(matrix, i)), 0.0) &&
462 aggtypes[i] == NOAGG )
463 {
464 SCIP_Real lb;
465 SCIP_Real ub;
466
467 lb = SCIPmatrixGetColLb(matrix, i);
468 ub = SCIPmatrixGetColUb(matrix, i);
469 assert(lb == SCIPvarGetLbGlobal(SCIPmatrixGetVar(matrix, i))); /*lint !e777*/
470 assert(ub == SCIPvarGetUbGlobal(SCIPmatrixGetVar(matrix, i))); /*lint !e777*/
471
472 /* the variable needs to have finite bounds to allow an agregation */
473 if( !SCIPisInfinity(scip, -lb) && !SCIPisInfinity(scip, ub) )
474 {
475 int binvaridx;
476 AGGRTYPE aggtype;
477 getBinVarIdxInDownlockRow(scip, matrix, i, &binvaridx, &aggtype);
478
479 if( binvaridx >= 0 )
480 {
481 aggtypes[i] = aggtype;
482 binvars[i] = SCIPmatrixGetVar(matrix, binvaridx);
483 (*nvaragg)++;
484 }
485 }
486 }
487 }
488
489 return SCIP_OKAY;
490}
491
492/*
493 * Callback methods of presolver
494 */
495
496/** copy method for presolver plugins (called when SCIP copies plugins) */
497static
498SCIP_DECL_PRESOLCOPY(presolCopyDualagg)
499{ /*lint --e{715}*/
500 assert(scip != NULL);
501 assert(presol != NULL);
502 assert(strcmp(SCIPpresolGetName(presol), PRESOL_NAME) == 0);
503
504 /* call inclusion method of presolver */
506
507 return SCIP_OKAY;
508}
509
510/** execution method of presolver */
511static
512SCIP_DECL_PRESOLEXEC(presolExecDualagg)
513{ /*lint --e{715}*/
514 SCIP_MATRIX* matrix;
515 SCIP_Bool initialized;
516 SCIP_Bool complete;
517 SCIP_Bool infeasible;
518
519 assert(result != NULL);
520 *result = SCIP_DIDNOTRUN;
521
523 return SCIP_OKAY;
524
526 return SCIP_OKAY;
527
528 if( SCIPgetNBinVars(scip) == 0 )
529 return SCIP_OKAY;
530
532 return SCIP_OKAY;
533
534 *result = SCIP_DIDNOTFIND;
535
536 matrix = NULL;
537
538 SCIP_CALL( SCIPmatrixCreate(scip, &matrix, TRUE, &initialized, &complete, &infeasible,
539 naddconss, ndelconss, nchgcoefs, nchgbds, nfixedvars) );
540
541 /* if infeasibility was detected during matrix creation, return here */
542 if( infeasible )
543 {
544 if( initialized )
545 SCIPmatrixFree(scip, &matrix);
546
547 *result = SCIP_CUTOFF;
548 return SCIP_OKAY;
549 }
550
551 /* we only work on pure MIPs currently */
552 if( initialized && complete )
553 {
554 AGGRTYPE* aggtypes;
555 SCIP_VAR** binvars;
556 int nvaragg;
557 int ncols;
558
559 ncols = SCIPmatrixGetNColumns(matrix);
560 nvaragg = 0;
561
562 SCIP_CALL( SCIPallocBufferArray(scip, &aggtypes, ncols) );
563 BMSclearMemoryArray(aggtypes, ncols);
564
565 SCIP_CALL( SCIPallocBufferArray(scip, &binvars, ncols) );
566 SCIPdebug( BMSclearMemoryArray(binvars, ncols) );
567
568 /* search for aggregations */
569 SCIP_CALL( findUplockAggregations(scip, matrix, &nvaragg, aggtypes, binvars) );
570 SCIP_CALL( findDownlockAggregations(scip, matrix, &nvaragg, aggtypes, binvars) );
571
572 /* apply aggregations, if we found any */
573 if( nvaragg > 0 )
574 {
575 int v;
576
577 for( v = 0; v < ncols; v++ )
578 {
579 if( aggtypes[v] != NOAGG )
580 {
581 SCIP_Bool redundant;
582 SCIP_Bool aggregated;
583 SCIP_Real ub;
584 SCIP_Real lb;
585
586 ub = SCIPmatrixGetColUb(matrix, v);
587 lb = SCIPmatrixGetColLb(matrix, v);
588
589 /* aggregate variable */
590 assert(binvars[v] != NULL);
591 if( aggtypes[v] == BIN0UBOUND )
592 {
593 SCIP_CALL( SCIPaggregateVars(scip, SCIPmatrixGetVar(matrix, v), binvars[v], 1.0, ub-lb,
594 ub, &infeasible, &redundant, &aggregated) );
595 }
596 else
597 {
598 assert(aggtypes[v] == BIN0LBOUND);
599 SCIP_CALL( SCIPaggregateVars(scip, SCIPmatrixGetVar(matrix, v), binvars[v], 1.0, lb-ub,
600 lb, &infeasible, &redundant, &aggregated) );
601 }
602
603 /* infeasible aggregation */
604 if( infeasible )
605 {
606 SCIPdebugMsg(scip, " -> infeasible aggregation\n");
607 *result = SCIP_CUTOFF;
608 return SCIP_OKAY;
609 }
610
611 if( aggregated )
612 (*naggrvars)++;
613 }
614 }
615
616 /* set result pointer */
617 if( (*naggrvars) > 0 )
618 *result = SCIP_SUCCESS;
619 }
620
621 SCIPfreeBufferArray(scip, &binvars);
622 SCIPfreeBufferArray(scip, &aggtypes);
623 }
624
625 SCIPmatrixFree(scip, &matrix);
626
627 return SCIP_OKAY;
628}
629
630/*
631 * presolver specific interface methods
632 */
633
634/** creates the dualagg presolver and includes it in SCIP */
636 SCIP* scip /**< SCIP data structure */
637 )
638{
639 SCIP_PRESOL* presol;
640
641 /* include presolver */
643 PRESOL_TIMING, presolExecDualagg, NULL) );
644
645 /* set non fundamental callbacks via setter functions */
646 SCIP_CALL( SCIPsetPresolCopy(scip, presol, presolCopyDualagg) );
647
648 return SCIP_OKAY;
649}
#define NULL
Definition: def.h:266
#define SCIP_Bool
Definition: def.h:91
#define SCIP_Real
Definition: def.h:172
#define TRUE
Definition: def.h:93
#define SCIP_CALL(x)
Definition: def.h:373
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip_general.c:734
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:390
int SCIPgetNBinVars(SCIP *scip)
Definition: scip_prob.c:2037
#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:140
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:105
const char * SCIPpresolGetName(SCIP_PRESOL *presol)
Definition: presol.c:599
int SCIPgetNActivePricers(SCIP *scip)
Definition: scip_pricer.c:348
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip_probing.c:97
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_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:8524
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17946
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17604
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:18108
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:18098
SCIP_Bool SCIPallowStrongDualReds(SCIP *scip)
Definition: scip_var.c:8752
int * SCIPmatrixGetColIdxPtr(SCIP_MATRIX *matrix, int col)
Definition: matrix.c:1580
int SCIPmatrixGetRowNNonzs(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1708
int SCIPmatrixGetColNDownlocks(SCIP_MATRIX *matrix, int col)
Definition: matrix.c:1648
int SCIPmatrixGetColNNonzs(SCIP_MATRIX *matrix, int col)
Definition: matrix.c:1592
SCIP_Bool SCIPmatrixIsRowRhsInfinity(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1766
int SCIPmatrixGetColNUplocks(SCIP_MATRIX *matrix, int col)
Definition: matrix.c:1636
SCIP_Real SCIPmatrixGetRowMaxActivity(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1800
SCIP_Real SCIPmatrixGetColLb(SCIP_MATRIX *matrix, int col)
Definition: matrix.c:1625
SCIP_Real SCIPmatrixGetRowLhs(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1742
SCIP_Real * SCIPmatrixGetRowValPtr(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1684
SCIP_Real * SCIPmatrixGetColValPtr(SCIP_MATRIX *matrix, int col)
Definition: matrix.c:1568
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:454
int SCIPmatrixGetNColumns(SCIP_MATRIX *matrix)
Definition: matrix.c:1604
SCIP_Real SCIPmatrixGetRowMinActivity(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1788
void SCIPmatrixFree(SCIP *scip, SCIP_MATRIX **matrix)
Definition: matrix.c:1072
SCIP_VAR * SCIPmatrixGetVar(SCIP_MATRIX *matrix, int col)
Definition: matrix.c:1660
int * SCIPmatrixGetRowIdxPtr(SCIP_MATRIX *matrix, int row)
Definition: matrix.c:1696
SCIP_Real SCIPmatrixGetColUb(SCIP_MATRIX *matrix, int col)
Definition: matrix.c:1614
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:62