SCIP Doxygen Documentation
 
Loading...
Searching...
No Matches
presol_milp.cpp
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-2023 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_milp.cpp
26 * @brief MILP presolver
27 * @author Leona Gottwald
28 *
29 * Calls the presolve library and communicates (multi-)aggregations, fixings, and bound
30 * changes to SCIP by utilizing the postsolve information. Constraint changes can currently
31 * only be communicated by deleting all constraints and adding new ones.
32 *
33 * @todo add infrastructure to SCIP for handling parallel columns
34 * @todo better communication of constraint changes by adding more information to the postsolve structure
35 * @todo allow to pass additional external locks to the presolve library that are considered when doing reductions
36 *
37 */
38
39/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
40
41#include "scip/presol_milp.h"
42
43#ifndef SCIP_WITH_PAPILO
44
45/** creates the MILP presolver and includes it in SCIP */
47 SCIP* scip /**< SCIP data structure */
48 )
49{
50 assert(scip != NULL);
51 return SCIP_OKAY;
52}
53
54#else
55
56/* disable some warnings that come up in header files of PAPILOs dependencies */
57#ifdef __GNUC__
58#pragma GCC diagnostic ignored "-Wshadow"
59#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
60#pragma GCC diagnostic ignored "-Wredundant-decls"
61
62/* disable false warning, !3076, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106199 */
63#if __GNUC__ == 12 && __GNUC__MINOR__ <= 2
64#pragma GCC diagnostic ignored "-Wstringop-overflow"
65#endif
66#endif
67
68#include <assert.h>
69#include "scip/cons_linear.h"
70#include "scip/pub_matrix.h"
71#include "scip/pub_presol.h"
72#include "scip/pub_var.h"
73#include "scip/pub_cons.h"
74#include "scip/pub_message.h"
75#include "scip/scip_general.h"
76#include "scip/scip_presol.h"
77#include "scip/scip_var.h"
78#include "scip/scip_mem.h"
79#include "scip/scip_prob.h"
80#include "scip/scip_param.h"
81#include "scip/scip_cons.h"
82#include "scip/scip_numerics.h"
83#include "scip/scip_timing.h"
84#include "scip/scip_message.h"
86#include "papilo/core/Presolve.hpp"
87#include "papilo/core/ProblemBuilder.hpp"
88#include "papilo/Config.hpp"
89
90#define PRESOL_NAME "milp"
91#define PRESOL_DESC "MILP specific presolving methods"
92#define PRESOL_PRIORITY 9999999 /**< priority of the presolver (>= 0: before, < 0: after constraint handlers); combined with propagators */
93#define PRESOL_MAXROUNDS -1 /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */
94#define PRESOL_TIMING SCIP_PRESOLTIMING_MEDIUM /* timing of the presolver (fast, medium, or exhaustive) */
95
96/* default parameter values */
97#define DEFAULT_THREADS 1 /**< maximum number of threads presolving may use (0: automatic) */
98#define DEFAULT_MAXFILLINPERSUBST 3 /**< maximal possible fillin for substitutions to be considered */
99#define DEFAULT_MAXSHIFTPERROW 10 /**< maximal amount of nonzeros allowed to be shifted to make space for substitutions */
100#define DEFAULT_DETECTLINDEP 0 /**< should linear dependent equations and free columns be removed? (0: never, 1: for LPs, 2: always) */
101#define DEFAULT_MAXBADGESIZE_SEQ 15000 /**< the max badge size in Probing if PaPILO is executed in sequential mode*/
102#define DEFAULT_MAXBADGESIZE_PAR -1 /**< the max badge size in Probing if PaPILO is executed in parallel mode*/
103#define DEFAULT_RANDOMSEED 0 /**< the random seed used for randomization of tie breaking */
104#define DEFAULT_MODIFYCONSFAC 0.8 /**< modify SCIP constraints when the number of nonzeros or rows is at most this
105 * factor times the number of nonzeros or rows before presolving */
106#define DEFAULT_MARKOWITZTOLERANCE 0.01 /**< the markowitz tolerance used for substitutions */
107#define DEFAULT_HUGEBOUND 1e8 /**< absolute bound value that is considered too huge for activitity based calculations */
108#define DEFAULT_ENABLEPARALLELROWS TRUE /**< should the parallel rows presolver be enabled within the presolve library? */
109#define DEFAULT_ENABLEDOMCOL TRUE /**< should the dominated column presolver be enabled within the presolve library? */
110#define DEFAULT_ENABLEDUALINFER TRUE /**< should the dualinfer presolver be enabled within the presolve library? */
111#define DEFAULT_ENABLEMULTIAGGR TRUE /**< should the multi-aggregation presolver be enabled within the presolve library? */
112#define DEFAULT_ENABLEPROBING TRUE /**< should the probing presolver be enabled within the presolve library? */
113#define DEFAULT_ENABLESPARSIFY FALSE /**< should the sparsify presolver be enabled within the presolve library? */
114#define DEFAULT_FILENAME_PROBLEM "-" /**< default filename to store the instance before presolving */
115
116/*
117 * Data structures
118 */
119
120/** presolver data */
121struct SCIP_PresolData
122{
123 int lastncols; /**< the number of columns from the last call */
124 int lastnrows; /**< the number of rows from the last call */
125 int threads; /**< maximum number of threads presolving may use (0: automatic) */
126 int maxfillinpersubstitution; /**< maximal possible fillin for substitutions to be considered */
127 int maxbadgesizeseq; /**< the max badge size in Probing if PaPILO is called in sequential mode*/
128 int maxbadgesizepar; /**< the max badge size in Probing if PaPILO is called in parallel mode */
129 int maxshiftperrow; /**< maximal amount of nonzeros allowed to be shifted to make space for substitutions */
130 int detectlineardependency; /**< should linear dependent equations and free columns be removed? (0: never, 1: for LPs, 2: always) */
131 int randomseed; /**< the random seed used for randomization of tie breaking */
132 SCIP_Bool enablesparsify; /**< should the sparsify presolver be enabled within the presolve library? */
133 SCIP_Bool enabledomcol; /**< should the dominated column presolver be enabled within the presolve library? */
134 SCIP_Bool enableprobing; /**< should the probing presolver be enabled within the presolve library? */
135 SCIP_Bool enabledualinfer; /**< should the dualinfer presolver be enabled within the presolve library? */
136 SCIP_Bool enablemultiaggr; /**< should the multi-aggregation presolver be enabled within the presolve library? */
137 SCIP_Bool enableparallelrows; /**< should the parallel rows presolver be enabled within the presolve library? */
138 SCIP_Real modifyconsfac; /**< modify SCIP constraints when the number of nonzeros or rows is at most this
139 * factor times the number of nonzeros or rows before presolving */
140 SCIP_Real markowitztolerance; /**< the markowitz tolerance used for substitutions */
141 SCIP_Real hugebound; /**< absolute bound value that is considered too huge for activitity based calculations */
142
143 char* filename = NULL; /**< filename to store the instance before presolving */
144};
145
146using namespace papilo;
147
148/*
149 * Local methods
150 */
151
152/** builds the presolvelib problem datastructure from the matrix */
153static
154Problem<SCIP_Real> buildProblem(
155 SCIP* scip, /**< SCIP data structure */
156 SCIP_MATRIX* matrix /**< initialized SCIP_MATRIX data structure */
157 )
158{
160
161 /* build problem from matrix */
162 int nnz = SCIPmatrixGetNNonzs(matrix);
163 int ncols = SCIPmatrixGetNColumns(matrix);
164 int nrows = SCIPmatrixGetNRows(matrix);
165 builder.reserve(nnz, nrows, ncols);
166
167 /* set up columns */
168 builder.setNumCols(ncols);
169 for(int i = 0; i != ncols; ++i)
170 {
171 SCIP_VAR* var = SCIPmatrixGetVar(matrix, i);
172 SCIP_Real lb = SCIPvarGetLbGlobal(var);
173 SCIP_Real ub = SCIPvarGetUbGlobal(var);
174 builder.setColLb(i, lb);
175 builder.setColUb(i, ub);
176 builder.setColLbInf(i, SCIPisInfinity(scip, -lb));
177 builder.setColUbInf(i, SCIPisInfinity(scip, ub));
178#if PAPILO_VERSION_MAJOR > 2 || (PAPILO_VERSION_MAJOR == 2 && PAPILO_VERSION_MINOR >= 1)
180 builder.setColImplInt(i, TRUE);
181 else
182 builder.setColIntegral(i, SCIPvarIsIntegral(var));
183#else
184 builder.setColIntegral(i, SCIPvarIsIntegral(var));
185#endif
186 builder.setObj(i, SCIPvarGetObj(var));
187 }
188
189 /* set up rows */
190 builder.setNumRows(nrows);
191 for(int i = 0; i != nrows; ++i)
192 {
193 int* rowcols = SCIPmatrixGetRowIdxPtr(matrix, i);
194 SCIP_Real* rowvals = SCIPmatrixGetRowValPtr(matrix, i);
195 int rowlen = SCIPmatrixGetRowNNonzs(matrix, i);
196 builder.addRowEntries(i, rowlen, rowcols, rowvals);
197
198 SCIP_Real lhs = SCIPmatrixGetRowLhs(matrix, i);
199 SCIP_Real rhs = SCIPmatrixGetRowRhs(matrix, i);
200 builder.setRowLhs(i, lhs);
201 builder.setRowRhs(i, rhs);
202 builder.setRowLhsInf(i, SCIPisInfinity(scip, -lhs));
203 builder.setRowRhsInf(i, SCIPisInfinity(scip, rhs));
204 }
205
206 /* init objective offset - the value itself is irrelevant */
207 builder.setObjOffset(0);
208
209 return builder.build();
210}
211
212/*
213 * Callback methods of presolver
214 */
215
216/** copy method for constraint handler plugins (called when SCIP copies plugins) */
217static
219{ /*lint --e{715}*/
221
222 return SCIP_OKAY;
223}
224
225/** destructor of presolver to free user data (called when SCIP is exiting) */
226static
228{ /*lint --e{715}*/
230 assert(data != NULL);
231
234 return SCIP_OKAY;
235}
236
237/** initialization method of presolver (called after problem was transformed) */
238static
240{ /*lint --e{715}*/
242 assert(data != NULL);
243
244 data->lastncols = -1;
245 data->lastnrows = -1;
246
247 return SCIP_OKAY;
248}
249
250/** execution method of presolver */
251static
253{ /*lint --e{715}*/
254 SCIP_MATRIX* matrix;
255 SCIP_PRESOLDATA* data;
256 SCIP_Bool initialized;
257 SCIP_Bool complete;
258 SCIP_Bool infeasible;
259 SCIP_Real timelimit;
260
262
264
265 int nvars = SCIPgetNVars(scip);
266 int nconss = SCIPgetNConss(scip);
267
268 /* run only if the problem size reduced by some amount since the last call or if it is the first call */
269 if( data->lastncols != -1 && data->lastnrows != -1 &&
270 nvars > data->lastncols * 0.85 &&
271 nconss > data->lastnrows * 0.85 )
272 return SCIP_OKAY;
273
274 SCIP_CALL( SCIPmatrixCreate(scip, &matrix, TRUE, &initialized, &complete, &infeasible,
275 naddconss, ndelconss, nchgcoefs, nchgbds, nfixedvars) );
276
277 /* if infeasibility was detected during matrix creation, return here */
278 if( infeasible )
279 {
280 if( initialized )
281 SCIPmatrixFree(scip, &matrix);
282
284 return SCIP_OKAY;
285 }
286
287 /* we only work on pure MIPs, also disable to try building the matrix again if it failed once */
288 if( !initialized || !complete )
289 {
290 data->lastncols = 0;
291 data->lastnrows = 0;
292
293 if( initialized )
294 SCIPmatrixFree(scip, &matrix);
295
296 return SCIP_OKAY;
297 }
298
299 /* only allow communication of constraint modifications by deleting all constraints when they have not been upgraded yet */
303
304 Problem<SCIP_Real> problem = buildProblem(scip, matrix);
306
307 /* store current numbers of aggregations, fixings, and changed bounds for statistics */
308 int oldnaggrvars = *naggrvars;
309 int oldnfixedvars = *nfixedvars;
310 int oldnchgbds = *nchgbds;
311
312 /* important so that SCIP does not throw an error, e.g. when an integer variable is substituted
313 * into a knapsack constraint */
314 presolve.getPresolveOptions().substitutebinarieswithints = false;
315
316 /* currently these changes cannot be communicated to SCIP correctly since a constraint needs
317 * to be modified in the cases where slackvariables are removed from constraints but for the
318 * presolve library those look like normal substitution on the postsolve stack */
319 presolve.getPresolveOptions().removeslackvars = false;
320
321 /* communicate the SCIP parameters to the presolve libary */
322 presolve.getPresolveOptions().maxfillinpersubstitution = data->maxfillinpersubstitution;
323 presolve.getPresolveOptions().markowitz_tolerance = data->markowitztolerance;
324 presolve.getPresolveOptions().maxshiftperrow = data->maxshiftperrow;
325 presolve.getPresolveOptions().hugeval = data->hugebound;
326
327 /* removal of linear dependent equations has only an effect when constraint modifications are communicated */
328 presolve.getPresolveOptions().detectlindep = allowconsmodification ? data->detectlineardependency : 0;
329
330 /* communicate the random seed */
331 presolve.getPresolveOptions().randomseed = SCIPinitializeRandomSeed(scip, (unsigned int)data->randomseed);
332
333 /* set number of threads to be used for presolve */
334 presolve.getPresolveOptions().threads = data->threads;
335
336 /* disable dual reductions that are not permitted */
337 if( !complete )
338 presolve.getPresolveOptions().dualreds = 0;
339 else if( SCIPallowStrongDualReds(scip) )
340 presolve.getPresolveOptions().dualreds = 2;
341 else if( SCIPallowWeakDualReds(scip) )
342 presolve.getPresolveOptions().dualreds = 1;
343 else
344 presolve.getPresolveOptions().dualreds = 0;
345
346 /* set up the presolvers that shall participate */
347 using uptr = std::unique_ptr<PresolveMethod<SCIP_Real>>;
348
349 /* fast presolvers*/
350 presolve.addPresolveMethod( uptr( new SingletonCols<SCIP_Real>() ) );
351 presolve.addPresolveMethod( uptr( new CoefficientStrengthening<SCIP_Real>() ) );
352 presolve.addPresolveMethod( uptr( new ConstraintPropagation<SCIP_Real>() ) );
353
354 /* medium presolver */
355 presolve.addPresolveMethod( uptr( new SimpleProbing<SCIP_Real>() ) );
356 if( data->enableparallelrows )
357 presolve.addPresolveMethod( uptr( new ParallelRowDetection<SCIP_Real>() ) );
358 /* todo: parallel cols cannot be handled by SCIP currently
359 * addPresolveMethod( uptr( new ParallelColDetection<SCIP_Real>() ) ); */
360 presolve.addPresolveMethod( uptr( new SingletonStuffing<SCIP_Real>() ) );
361#if PAPILO_VERSION_MAJOR > 2 || (PAPILO_VERSION_MAJOR == 2 && PAPILO_VERSION_MINOR >= 1)
363 dualfix->set_fix_to_infinity_allowed(false);
364 presolve.addPresolveMethod( uptr( dualfix ) );
365#else
366 presolve.addPresolveMethod( uptr( new DualFix<SCIP_Real>() ) );
367#endif
368 presolve.addPresolveMethod( uptr( new FixContinuous<SCIP_Real>() ) );
369 presolve.addPresolveMethod( uptr( new SimplifyInequalities<SCIP_Real>() ) );
370 presolve.addPresolveMethod( uptr( new SimpleSubstitution<SCIP_Real>() ) );
371
372 /* exhaustive presolvers*/
373 presolve.addPresolveMethod( uptr( new ImplIntDetection<SCIP_Real>() ) );
374 if( data->enabledualinfer )
375 presolve.addPresolveMethod( uptr( new DualInfer<SCIP_Real>() ) );
376 if( data->enableprobing )
377 {
378#if PAPILO_VERSION_MAJOR > 2 || (PAPILO_VERSION_MAJOR == 2 && PAPILO_VERSION_MINOR >= 1)
379 Probing<SCIP_Real> *probing = new Probing<SCIP_Real>();
380 if( presolve.getPresolveOptions().runs_sequential() )
381 {
382 probing->set_max_badge_size( data->maxbadgesizeseq );
383 }
384 else
385 {
386 probing->set_max_badge_size( data->maxbadgesizepar );
387 }
388 presolve.addPresolveMethod( uptr( probing ) );
389
390#else
391 presolve.addPresolveMethod( uptr( new Probing<SCIP_Real>() ) );
392 if( data->maxbadgesizeseq != DEFAULT_MAXBADGESIZE_SEQ )
394 " The parameter 'presolving/milp/maxbadgesizeseq' can only be used with PaPILO 2.1.0 or later versions.\n");
395
396 if( data->maxbadgesizepar != DEFAULT_MAXBADGESIZE_PAR )
398 " The parameter 'presolving/milp/maxbadgesizepar' can only be used with PaPILO 2.1.0 or later versions.\n");
399
400#endif
401 }
402 if( data->enabledomcol )
403 presolve.addPresolveMethod( uptr( new DominatedCols<SCIP_Real>() ) );
404 if( data->enablemultiaggr )
405 presolve.addPresolveMethod( uptr( new Substitution<SCIP_Real>() ) );
406 if( data->enablesparsify )
407 presolve.addPresolveMethod( uptr( new Sparsify<SCIP_Real>() ) );
408
409 /* set tolerances */
410 presolve.getPresolveOptions().feastol = SCIPfeastol(scip);
411 presolve.getPresolveOptions().epsilon = SCIPepsilon(scip);
412
413 /* adjust output settings of presolve library */
414#ifdef SCIP_PRESOLLIB_ENABLE_OUTPUT
415 problem.setName(SCIPgetProbName(scip));
416#else
417 presolve.setVerbosityLevel(VerbosityLevel::kQuiet);
418#endif
419
420 /* communicate the time limit */
421 SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
422 if( !SCIPisInfinity(scip, timelimit) )
423 presolve.getPresolveOptions().tlim = timelimit - SCIPgetSolvingTime(scip);
424
426 {
427 SCIP_CALL(SCIPwriteTransProblem(scip, data->filename, NULL, FALSE));
428 }
429
430 /* call the presolving */
432 " (%.1fs) running MILP presolver\n", SCIPgetSolvingTime(scip));
433 int oldnnz = problem.getConstraintMatrix().getNnz();
434
435 /*call presolving without storing information for dual postsolve*/
436#if (PAPILO_VERSION_MAJOR >= 2)
437 PresolveResult<SCIP_Real> res = presolve.apply(problem, false);
438#else
439 PresolveResult<SCIP_Real> res = presolve.apply(problem);
440#endif
441 data->lastncols = problem.getNCols();
442 data->lastnrows = problem.getNRows();
443
444 /* evaluate the result */
445 switch(res.status)
446 {
447 case PresolveStatus::kInfeasible:
450 " (%.1fs) MILP presolver detected infeasibility\n",
452 SCIPmatrixFree(scip, &matrix);
453 return SCIP_OKAY;
454 case PresolveStatus::kUnbndOrInfeas:
455 case PresolveStatus::kUnbounded:
458 " (%.1fs) MILP presolver detected unboundedness\n",
460 SCIPmatrixFree(scip, &matrix);
461 return SCIP_OKAY;
462 case PresolveStatus::kUnchanged:
464 data->lastncols = nvars;
465 data->lastnrows = nconss;
467 " (%.1fs) MILP presolver found nothing\n",
469 SCIPmatrixFree(scip, &matrix);
470 return SCIP_OKAY;
471 case PresolveStatus::kReduced:
472 data->lastncols = problem.getNCols();
473 data->lastnrows = problem.getNRows();
475 }
476
477 /* result indicated success, now populate the changes into the SCIP structures */
478 std::vector<SCIP_VAR*> tmpvars;
479 std::vector<SCIP_Real> tmpvals;
480
481 /* if the number of nonzeros decreased by a sufficient factor, rather create all constraints from scratch */
482 int newnnz = problem.getConstraintMatrix().getNnz();
483 bool constraintsReplaced = false;
484 if( newnnz == 0 || (allowconsmodification &&
485 (problem.getNRows() <= data->modifyconsfac * data->lastnrows ||
487 {
488 int oldnrows = SCIPmatrixGetNRows(matrix);
489 int newnrows = problem.getNRows();
490
491 constraintsReplaced = true;
492
493 /* capture constraints that are still present in the problem after presolve */
494 for( int i = 0; i < newnrows; ++i )
495 {
496 SCIP_CONS* c = SCIPmatrixGetCons(matrix, res.postsolve.origrow_mapping[i]);
498 }
499
500 /* delete all constraints */
501 *ndelconss += oldnrows;
502 *naddconss += newnrows;
503
504 for( int i = 0; i < oldnrows; ++i )
505 {
507 }
508
509 /* now loop over rows of presolved problem and create them as new linear constraints,
510 * then release the old constraint after its name was passed to the new constraint */
511 const Vec<RowFlags>& rflags = problem.getRowFlags();
512 const auto& consmatrix = problem.getConstraintMatrix();
513 for( int i = 0; i < newnrows; ++i )
514 {
515 auto rowvec = consmatrix.getRowCoefficients(i);
516 const int* rowcols = rowvec.getIndices();
517 /* SCIPcreateConsBasicLinear() requires a non const pointer */
518 SCIP_Real* rowvals = const_cast<SCIP_Real*>(rowvec.getValues());
519 int rowlen = rowvec.getLength();
520
521 /* retrieve SCIP compatible left and right hand sides */
522 SCIP_Real lhs = rflags[i].test(RowFlag::kLhsInf) ? - SCIPinfinity(scip) : consmatrix.getLeftHandSides()[i];
523 SCIP_Real rhs = rflags[i].test(RowFlag::kRhsInf) ? SCIPinfinity(scip) : consmatrix.getRightHandSides()[i];
524
525 /* create variable array matching the value array */
526 tmpvars.clear();
527 tmpvars.reserve(rowlen);
528 for( int j = 0; j < rowlen; ++j )
529 tmpvars.push_back(SCIPmatrixGetVar(matrix, res.postsolve.origcol_mapping[rowcols[j]]));
530
531 /* create and add new constraint with name of old constraint */
532 SCIP_CONS* oldcons = SCIPmatrixGetCons(matrix, res.postsolve.origrow_mapping[i]);
533 SCIP_CONS* cons;
534 SCIP_CALL( SCIPcreateConsBasicLinear(scip, &cons, SCIPconsGetName(oldcons), rowlen, tmpvars.data(), rowvals, lhs, rhs) );
535 SCIP_CALL( SCIPaddCons(scip, cons) );
536
537 /* release old and new constraint */
539 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
540 }
541 }
542
543 /* loop over res.postsolve and add all fixed variables and aggregations to scip */
544 for( std::size_t i = 0; i != res.postsolve.types.size(); ++i )
545 {
546 ReductionType type = res.postsolve.types[i];
547 int first = res.postsolve.start[i];
548 int last = res.postsolve.start[i + 1];
549
550 switch( type )
551 {
552 case ReductionType::kFixedCol:
553 {
554 SCIP_Bool infeas;
555 SCIP_Bool fixed;
556 int col = res.postsolve.indices[first];
557
558 SCIP_VAR* var = SCIPmatrixGetVar(matrix, col);
559
560 SCIP_Real value = res.postsolve.values[first];
561
562 SCIP_CALL( SCIPfixVar(scip, var, value, &infeas, &fixed) );
563 *nfixedvars += 1;
564
565 assert(!infeas);
566 /* SCIP has different rules for aggregating variables than PaPILO: therefore the variable PaPILO
567 * tries to fix now may have been aggregated by SCIP before. Additionally, after aggregation SCIP
568 * sometimes performs bound tightening resulting in possible fixings. These cases need to be excluded. */
571 break;
572 }
573/*
574 * Dual-postsolving in PaPILO required introducing a postsolve-type for substitution with additional information.
575 * Further, the different Substitution-postsolving types store the required postsolving data differently (in different order) in the postsolving stack.
576 * Therefore, we need to distinguish how to parse the required data (rowLength, col, side, startRowCoefficients, lastRowCoefficients) from the postsolving stack.
577 * If these values are accessed, the procedure is the same for both.
578 */
579#if (PAPILO_VERSION_MAJOR >= 2)
580 case ReductionType::kSubstitutedColWithDual:
581#endif
582 case ReductionType::kSubstitutedCol:
583 {
584 int col = 0;
585 SCIP_Real side = 0;
586
587 int rowlen = 0;
588 int startRowCoefficients = 0;
589 int lastRowCoefficients = 0;
590
591 if( type == ReductionType::kSubstitutedCol )
592 {
593 rowlen = last - first - 1;
594 col = res.postsolve.indices[first];
595 side = res.postsolve.values[first];
596
597 startRowCoefficients = first + 1;
598 lastRowCoefficients = last;
599 }
600#if (PAPILO_VERSION_MAJOR >= 2)
601 if( type == ReductionType::kSubstitutedColWithDual )
602 {
603 rowlen = (int) res.postsolve.values[first];
604 col = res.postsolve.indices[first + 3 + rowlen];
605 side = res.postsolve.values[first + 1];
606
607 startRowCoefficients = first + 3;
608 lastRowCoefficients = first + 3 + rowlen;
609
610 assert(side == res.postsolve.values[first + 2]);
611 assert(res.postsolve.indices[first + 1] == 0);
612 assert(res.postsolve.indices[first + 2] == 0);
613 }
614 assert( type == ReductionType::kSubstitutedCol || type == ReductionType::kSubstitutedColWithDual );
615#else
616 assert( type == ReductionType::kSubstitutedCol );
617#endif
618 SCIP_Bool infeas;
619 SCIP_Bool aggregated;
620 SCIP_Bool redundant = FALSE;
621 SCIP_Real constant = 0.0;
622 if( rowlen == 2 )
623 {
624 SCIP_Real updatedSide;
625 SCIP_VAR* varx = SCIPmatrixGetVar(matrix, res.postsolve.indices[startRowCoefficients]);
626 SCIP_VAR* vary = SCIPmatrixGetVar(matrix, res.postsolve.indices[startRowCoefficients + 1]);
627 SCIP_Real scalarx = res.postsolve.values[startRowCoefficients];
628 SCIP_Real scalary = res.postsolve.values[startRowCoefficients + 1];
629
630 SCIP_CALL( SCIPgetProbvarSum(scip, &varx, &scalarx, &constant) );
632
633 SCIP_CALL( SCIPgetProbvarSum(scip, &vary, &scalary, &constant) );
635
636 updatedSide = side - constant;
637
639 }
640 else
641 {
642 SCIP_Real colCoef = 0.0;
643 SCIP_Real updatedSide;
644
645 for( int j = startRowCoefficients; j < lastRowCoefficients; ++j )
646 {
647 if( res.postsolve.indices[j] == col )
648 {
649 colCoef = res.postsolve.values[j];
650 break;
651 }
652 }
653
654 tmpvars.clear();
655 tmpvals.clear();
656 tmpvars.reserve(rowlen);
657 tmpvals.reserve(rowlen);
658
659 assert(colCoef != 0.0);
660 SCIP_VAR* aggrvar = SCIPmatrixGetVar(matrix, col);
661
664
665 updatedSide = side - constant;
666
667 for( int j = startRowCoefficients; j < lastRowCoefficients; ++j )
668 {
669 if( res.postsolve.indices[j] == col )
670 continue;
671
672 tmpvars.push_back(SCIPmatrixGetVar(matrix, res.postsolve.indices[j]));
673 tmpvals.push_back(- res.postsolve.values[j] / colCoef);
674 }
675
677 tmpvars.data(), tmpvals.data(), updatedSide / colCoef, &infeas, &aggregated) );
678 }
679
680 if( aggregated )
681 *naggrvars += 1;
682 else if( constraintsReplaced && !redundant )
683 {
684 /* if the constraints where replaced, we need to add the failed substitution as an equality to SCIP */
685 tmpvars.clear();
686 tmpvals.clear();
687 for( int j = startRowCoefficients; j < lastRowCoefficients; ++j )
688 {
689 tmpvars.push_back(SCIPmatrixGetVar(matrix, res.postsolve.indices[j]));
690 tmpvals.push_back(res.postsolve.values[j]);
691 }
692
693 SCIP_CONS* cons;
694 String name = fmt::format("{}_failed_aggregation_equality", SCIPvarGetName(SCIPmatrixGetVar(matrix, col)));
695 SCIP_CALL( SCIPcreateConsBasicLinear(scip, &cons, name.c_str(),
696 tmpvars.size(), tmpvars.data(), tmpvals.data(), side, side ) );
697 SCIP_CALL( SCIPaddCons(scip, cons) );
698 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
699 *naddconss += 1;
700 }
701
702 if( infeas )
703 {
705 break;
706 }
707
708 break;
709 }
710 case ReductionType::kParallelCol:
711 return SCIP_INVALIDRESULT;
712#if (PAPILO_VERSION_MAJOR <= 1 && PAPILO_VERSION_MINOR==0)
713#else
714 case ReductionType::kFixedInfCol: {
715 /* todo: currently SCIP can not handle this kind of reduction (see issue #3391) */
716 assert(false);
718 continue;
719 SCIP_Bool infeas;
720 SCIP_Bool fixed;
721 SCIP_Real value = SCIPinfinity(scip);
722
723 int column = res.postsolve.indices[first];
724 bool is_negative_infinity = res.postsolve.values[first] < 0;
726
728 {
729 value = -SCIPinfinity(scip);
730 }
731
733 *nfixedvars += 1;
734
735 assert(!infeas);
736 assert(fixed);
737 break;
738 }
739#endif
740#if (PAPILO_VERSION_MAJOR >= 2)
741 case ReductionType::kVarBoundChange :
742 case ReductionType::kRedundantRow :
743 case ReductionType::kRowBoundChange :
744 case ReductionType::kReasonForRowBoundChangeForcedByRow :
745 case ReductionType::kRowBoundChangeForcedByRow :
746 case ReductionType::kSaveRow :
747 case ReductionType::kReducedBoundsCost :
748 case ReductionType::kColumnDualValue :
749 case ReductionType::kRowDualValue :
750 case ReductionType::kCoefficientChange :
751 // dual ReductionTypes should be only calculated for dual reductions and should not appear for MIP
752 SCIPerrorMessage("PaPILO: PaPILO should not return dual postsolving reductions in SCIP!!\n");
753 SCIPABORT(); /*lint --e{527}*/
754 break;
755#endif
756 default:
757 SCIPdebugMsg(scip, "PaPILO returned unknown data type: \n" );
758 continue;
759 }
760 }
761
762 /* tighten bounds of variables that are still present after presolving */
763 if( *result != SCIP_CUTOFF )
764 {
765 VariableDomains<SCIP_Real>& varDomains = problem.getVariableDomains();
766 for( int i = 0; i != problem.getNCols(); ++i )
767 {
768 assert( ! varDomains.flags[i].test(ColFlag::kInactive) );
769 SCIP_VAR* var = SCIPmatrixGetVar(matrix, res.postsolve.origcol_mapping[i]);
770 if( !varDomains.flags[i].test(ColFlag::kLbInf) )
771 {
772 SCIP_Bool infeas;
773 SCIP_Bool tightened;
774 SCIP_CALL( SCIPtightenVarLb(scip, var, varDomains.lower_bounds[i], TRUE, &infeas, &tightened) );
775
776 if( tightened )
777 *nchgbds += 1;
778
779 if( infeas )
780 {
782 break;
783 }
784 }
785
786 if( !varDomains.flags[i].test(ColFlag::kUbInf) )
787 {
788 SCIP_Bool infeas;
789 SCIP_Bool tightened;
790 SCIP_CALL( SCIPtightenVarUb(scip, var, varDomains.upper_bounds[i], TRUE, &infeas, &tightened) );
791
792 if( tightened )
793 *nchgbds += 1;
794
795 if( infeas )
796 {
798 break;
799 }
800 }
801 }
802 }
803
804 /* finish with a final verb message and return */
806 " (%.1fs) MILP presolver (%d rounds): %d aggregations, %d fixings, %d bound changes\n",
807 SCIPgetSolvingTime(scip), presolve.getStatistics().nrounds, *naggrvars - oldnaggrvars,
808 *nfixedvars - oldnfixedvars, *nchgbds - oldnchgbds);
809
810 /* free the matrix */
811 assert(initialized);
812 SCIPmatrixFree(scip, &matrix);
813
814 return SCIP_OKAY;
815}
816
817
818/*
819 * presolver specific interface methods
820 */
821
822/** creates the xyz presolver and includes it in SCIP */
824 SCIP* scip /**< SCIP data structure */
825 )
826{
827 SCIP_PRESOLDATA* presoldata;
829
830#if defined(PAPILO_VERSION_TWEAK) && PAPILO_VERSION_TWEAK != 0
832#else
833 String name = fmt::format("PaPILO {}.{}.{}", PAPILO_VERSION_MAJOR, PAPILO_VERSION_MINOR, PAPILO_VERSION_PATCH);
834#endif
835
836#ifdef PAPILO_GITHASH_AVAILABLE
837 String desc = fmt::format("parallel presolve for integer and linear optimization (github.com/scipopt/papilo) [GitHash: {}]", PAPILO_GITHASH);
838#else
839 String desc("parallel presolve for integer and linear optimization (github.com/scipopt/papilo)");
840#endif
841
842 /* add external code info for the presolve library */
843 SCIP_CALL( SCIPincludeExternalCodeInformation(scip, name.c_str(), desc.c_str()) );
844
845 /* create MILP presolver data */
846 presoldata = NULL;
847 SCIP_CALL( SCIPallocBlockMemory(scip, &presoldata) );
848 BMSclearMemory(presoldata);
849
850 presol = NULL;
851
852 /* include presolver */
855 presoldata) );
856
857 assert(presol != NULL);
858
859 /* set non fundamental callbacks via setter functions */
863
864 /* add MILP presolver parameters */
866 "presolving/" PRESOL_NAME "/threads",
867 "maximum number of threads presolving may use (0: automatic)",
868 &presoldata->threads, FALSE, DEFAULT_THREADS, 0, INT_MAX, NULL, NULL) );
869
871 "presolving/" PRESOL_NAME "/maxfillinpersubstitution",
872 "maximal possible fillin for substitutions to be considered",
873 &presoldata->maxfillinpersubstitution, FALSE, DEFAULT_MAXFILLINPERSUBST, INT_MIN, INT_MAX, NULL, NULL) );
874
876 "presolving/" PRESOL_NAME "/maxshiftperrow",
877 "maximal amount of nonzeros allowed to be shifted to make space for substitutions",
878 &presoldata->maxshiftperrow, TRUE, DEFAULT_MAXSHIFTPERROW, 0, INT_MAX, NULL, NULL) );
879
881 "presolving/" PRESOL_NAME "/randomseed",
882 "the random seed used for randomization of tie breaking",
883 &presoldata->randomseed, FALSE, DEFAULT_RANDOMSEED, INT_MIN, INT_MAX, NULL, NULL) );
884
885 if( DependentRows<double>::Enabled )
886 {
888 "presolving/" PRESOL_NAME "/detectlineardependency",
889 "should linear dependent equations and free columns be removed? (0: never, 1: for LPs, 2: always)",
890 &presoldata->detectlineardependency, TRUE, DEFAULT_DETECTLINDEP, 0, 2, NULL, NULL) );
891 }
892 else
893 presoldata->detectlineardependency = 0;
894
896 "presolving/" PRESOL_NAME "/modifyconsfac",
897 "modify SCIP constraints when the number of nonzeros or rows is at most this factor "
898 "times the number of nonzeros or rows before presolving",
899 &presoldata->modifyconsfac, FALSE, DEFAULT_MODIFYCONSFAC, 0.0, 1.0, NULL, NULL) );
900
902 "presolving/" PRESOL_NAME "/markowitztolerance",
903 "the markowitz tolerance used for substitutions",
904 &presoldata->markowitztolerance, FALSE, DEFAULT_MARKOWITZTOLERANCE, 0.0, 1.0, NULL, NULL) );
905
907 "presolving/" PRESOL_NAME "/hugebound",
908 "absolute bound value that is considered too huge for activitity based calculations",
909 &presoldata->hugebound, FALSE, DEFAULT_HUGEBOUND, 0.0, SCIP_REAL_MAX, NULL, NULL) );
910
911#if PAPILO_VERSION_MAJOR > 2 || (PAPILO_VERSION_MAJOR == 2 && PAPILO_VERSION_MINOR >= 1)
912 SCIP_CALL(SCIPaddIntParam(scip, "presolving/" PRESOL_NAME "/maxbadgesizeseq",
913 "maximal badge size in Probing in PaPILO if PaPILO is executed in sequential mode",
914 &presoldata->maxbadgesizeseq, FALSE, DEFAULT_MAXBADGESIZE_SEQ, -1, INT_MAX, NULL, NULL));
915
916 SCIP_CALL(SCIPaddIntParam(scip, "presolving/" PRESOL_NAME "/maxbadgesizepar",
917 "maximal badge size in Probing in PaPILO if PaPILO is executed in parallel mode",
918 &presoldata->maxbadgesizepar, FALSE, DEFAULT_MAXBADGESIZE_PAR, -1, INT_MAX, NULL, NULL));
919#else
920 presoldata->maxbadgesizeseq = DEFAULT_MAXBADGESIZE_SEQ;
921 presoldata->maxbadgesizepar = DEFAULT_MAXBADGESIZE_PAR;
922#endif
923
925 "presolving/" PRESOL_NAME "/enableparallelrows",
926 "should the parallel rows presolver be enabled within the presolve library?",
927 &presoldata->enableparallelrows, TRUE, DEFAULT_ENABLEPARALLELROWS, NULL, NULL) );
928
930 "presolving/" PRESOL_NAME "/enabledomcol",
931 "should the dominated column presolver be enabled within the presolve library?",
932 &presoldata->enabledomcol, TRUE, DEFAULT_ENABLEDOMCOL, NULL, NULL) );
933
935 "presolving/" PRESOL_NAME "/enabledualinfer",
936 "should the dualinfer presolver be enabled within the presolve library?",
937 &presoldata->enabledualinfer, TRUE, DEFAULT_ENABLEDUALINFER, NULL, NULL) );
938
940 "presolving/" PRESOL_NAME "/enablemultiaggr",
941 "should the multi-aggregation presolver be enabled within the presolve library?",
942 &presoldata->enablemultiaggr, TRUE, DEFAULT_ENABLEMULTIAGGR, NULL, NULL) );
943
945 "presolving/" PRESOL_NAME "/enableprobing",
946 "should the probing presolver be enabled within the presolve library?",
947 &presoldata->enableprobing, TRUE, DEFAULT_ENABLEPROBING, NULL, NULL) );
948
950 "presolving/" PRESOL_NAME "/enablesparsify",
951 "should the sparsify presolver be enabled within the presolve library?",
952 &presoldata->enablesparsify, TRUE, DEFAULT_ENABLESPARSIFY, NULL, NULL) );
953
954 SCIP_CALL( SCIPaddStringParam(scip, "presolving/" PRESOL_NAME "/probfilename",
955 "filename to store the problem before MILP presolving starts",
956 &presoldata->filename, TRUE, DEFAULT_FILENAME_PROBLEM, NULL, NULL) );
957
958 return SCIP_OKAY;
959}
960
961#endif
Constraint handler for linear constraints in their most general form, .
#define SCIP_REAL_MAX
Definition def.h:187
#define TRUE
Definition def.h:95
#define FALSE
Definition def.h:96
#define SCIPABORT()
Definition def.h:360
#define SCIP_CALL(x)
Definition def.h:388
SCIP_RETCODE SCIPcreateConsBasicLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs)
const char * SCIPgetProbName(SCIP *scip)
Definition scip_prob.c:1067
int SCIPgetNVars(SCIP *scip)
Definition scip_prob.c:1992
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition scip_prob.c:2770
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition scip_prob.c:2843
int SCIPgetNConss(SCIP *scip)
Definition scip_prob.c:3042
SCIP_RETCODE SCIPwriteTransProblem(SCIP *scip, const char *filename, const char *extension, SCIP_Bool genericnames)
Definition scip_prob.c:648
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
#define SCIPdebugMsg
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 SCIPaddStringParam(SCIP *scip, const char *name, const char *desc, char **valueptr, SCIP_Bool isadvanced, const char *defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:194
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 SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
Definition scip_param.c:307
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
SCIP_RETCODE SCIPincludePresolMILP(SCIP *scip)
int SCIPconshdlrGetNCheckConss(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4615
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition scip_cons.c:886
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition cons.c:8088
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition scip_cons.c:1119
SCIP_RETCODE SCIPcaptureCons(SCIP *scip, SCIP_CONS *cons)
Definition scip_cons.c:1084
SCIP_RETCODE SCIPincludeExternalCodeInformation(SCIP *scip, const char *name, const char *description)
#define SCIPfreeBlockMemory(scip, ptr)
Definition scip_mem.h:108
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
SCIP_RETCODE SCIPsetPresolFree(SCIP *scip, SCIP_PRESOL *presol,)
void SCIPpresolSetData(SCIP_PRESOL *presol, SCIP_PRESOLDATA *presoldata)
Definition presol.c:522
SCIP_PRESOLDATA * SCIPpresolGetData(SCIP_PRESOL *presol)
Definition presol.c:512
SCIP_RETCODE SCIPsetPresolCopy(SCIP *scip, SCIP_PRESOL *presol,)
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)
SCIP_RETCODE SCIPsetPresolInit(SCIP *scip, SCIP_PRESOL *presol,)
SCIP_Real SCIPgetSolvingTime(SCIP *scip)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfeastol(SCIP *scip)
SCIP_Real SCIPepsilon(SCIP *scip)
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition scip_var.c:5203
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition var.c:17360
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:8401
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition var.c:17748
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition scip_var.c:5320
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition var.c:17406
SCIP_RETCODE SCIPgetProbvarSum(SCIP *scip, SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition scip_var.c:1794
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition var.c:17910
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:17241
SCIP_RETCODE SCIPmultiaggregateVar(SCIP *scip, SCIP_VAR *var, int naggvars, SCIP_VAR **aggvars, SCIP_Real *scalars, SCIP_Real constant, SCIP_Bool *infeasible, SCIP_Bool *aggregated)
Definition scip_var.c:8535
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition var.c:17432
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition var.c:17900
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition scip_var.c:8276
SCIP_Bool SCIPallowWeakDualReds(SCIP *scip)
Definition scip_var.c:8656
SCIP_Bool SCIPallowStrongDualReds(SCIP *scip)
Definition scip_var.c:8629
unsigned int SCIPinitializeRandomSeed(SCIP *scip, unsigned int initialseedvalue)
return SCIP_OKAY
int c
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
SCIP_VAR * var
#define NULL
Definition lpi_spx1.cpp:161
int SCIPmatrixGetNNonzs(SCIP_MATRIX *matrix)
Definition matrix.c:1747
int SCIPmatrixGetRowNNonzs(SCIP_MATRIX *matrix, int row)
Definition matrix.c:1677
SCIP_Real SCIPmatrixGetRowLhs(SCIP_MATRIX *matrix, int row)
Definition matrix.c:1711
SCIP_Real * SCIPmatrixGetRowValPtr(SCIP_MATRIX *matrix, int row)
Definition matrix.c:1653
SCIP_Real SCIPmatrixGetRowRhs(SCIP_MATRIX *matrix, int row)
Definition matrix.c:1723
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:1573
SCIP_CONS * SCIPmatrixGetCons(SCIP_MATRIX *matrix, int row)
Definition matrix.c:1829
void SCIPmatrixFree(SCIP *scip, SCIP_MATRIX **matrix)
Definition matrix.c:1041
SCIP_VAR * SCIPmatrixGetVar(SCIP_MATRIX *matrix, int col)
Definition matrix.c:1629
int * SCIPmatrixGetRowIdxPtr(SCIP_MATRIX *matrix, int row)
Definition matrix.c:1665
int SCIPmatrixGetNRows(SCIP_MATRIX *matrix)
Definition matrix.c:1701
#define BMSclearMemory(ptr)
Definition memory.h:131
#define PRESOL_NAME
#define PRESOL_PRIORITY
#define PRESOL_MAXROUNDS
#define PRESOL_TIMING
#define PRESOL_DESC
MILP presolver that calls the presolve library on the constraint matrix.
public methods for managing constraints
public methods for matrix
public methods for message output
#define SCIPerrorMessage
Definition pub_message.h:64
public methods for presolvers
public methods for problem variables
#define DEFAULT_RANDOMSEED
public methods for constraint handler plugins and constraints
general public methods
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for presolving plugins
public methods for global and local (sub)problems
public methods for random numbers
static SCIP_RETCODE presolve(SCIP *scip, SCIP_Bool *unbounded, SCIP_Bool *infeasible, SCIP_Bool *vanished)
public methods for timing
public methods for SCIP variables
@ SCIP_VERBLEVEL_HIGH
#define SCIP_DECL_PRESOLCOPY(x)
Definition type_presol.h:60
struct SCIP_PresolData SCIP_PRESOLDATA
Definition type_presol.h:51
#define SCIP_DECL_PRESOLFREE(x)
Definition type_presol.h:68
#define SCIP_DECL_PRESOLINIT(x)
Definition type_presol.h:76
#define SCIP_DECL_PRESOLEXEC(x)
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ SCIP_CUTOFF
Definition type_result.h:48
@ SCIP_DIDNOTFIND
Definition type_result.h:44
@ SCIP_UNBOUNDED
Definition type_result.h:47
@ SCIP_SUCCESS
Definition type_result.h:58
@ SCIP_INVALIDRESULT
enum SCIP_Retcode SCIP_RETCODE
@ SCIP_VARTYPE_IMPLINT
Definition type_var.h:64
@ SCIP_VARSTATUS_FIXED
Definition type_var.h:52
@ SCIP_VARSTATUS_MULTAGGR
Definition type_var.h:54
@ SCIP_VARSTATUS_NEGATED
Definition type_var.h:55
@ SCIP_VARSTATUS_AGGREGATED
Definition type_var.h:53