43#ifndef SCIP_WITH_PAPILO
58#pragma GCC diagnostic ignored "-Wshadow"
59#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
60#pragma GCC diagnostic ignored "-Wredundant-decls"
63#if __GNUC__ == 12 && __GNUC__MINOR__ <= 2
64#pragma GCC diagnostic ignored "-Wstringop-overflow"
88#if defined(SCIP_WITH_EXACTSOLVE)
92#include "papilo/core/Presolve.hpp"
93#include "papilo/core/ProblemBuilder.hpp"
94#include "papilo/Config.hpp"
97#if !defined(PAPILO_API_VERSION)
98#define PAPILO_APIVERSION 0
99#elif !(PAPILO_API_VERSION + 0)
100#define PAPILO_APIVERSION 1
102#define PAPILO_APIVERSION PAPILO_API_VERSION
105#if defined(SCIP_WITH_GMP) && defined(SCIP_WITH_EXACTSOLVE) && !defined(PAPILO_HAVE_GMP)
106#warning SCIP built with GMP and exact solving, but PaPILO without GMP disables exact presolving.
109#if defined(SCIP_WITH_GMP) && defined(SCIP_WITH_EXACTSOLVE) && defined(PAPILO_HAVE_GMP)
110#define PAPILO_WITH_EXACTPRESOLVE
113#define PRESOL_NAME "milp"
114#define PRESOL_DESC "MILP specific presolving methods"
115#define PRESOL_PRIORITY 9999999
116#define PRESOL_MAXROUNDS (-1)
117#define PRESOL_TIMING SCIP_PRESOLTIMING_MEDIUM
120#define DEFAULT_THREADS 1
121#define DEFAULT_ABORTFAC_EXHAUSTIVE 0.0008
122#define DEFAULT_ABORTFAC_MEDIUM 0.0008
123#define DEFAULT_ABORTFAC_FAST 0.0008
124#define DEFAULT_DETECTLINDEP 0
125#define DEFAULT_INTERNAL_MAXROUNDS (-1)
126#define DEFAULT_MODIFYCONSFAC 0.8
128#define DEFAULT_RANDOMSEED 0
131#define DEFAULT_HUGEBOUND 1e8
134#define DEFAULT_ENABLEDOMCOL TRUE
135#define DEFAULT_ENABLEDUALINFER TRUE
136#define DEFAULT_ENABLEMULTIAGGR TRUE
137#define DEFAULT_ENABLEPARALLELROWS TRUE
138#define DEFAULT_ENABLEPROBING TRUE
139#define DEFAULT_ENABLESPARSIFY FALSE
140#define DEFAULT_ENABLECLIQUEMERGE FALSE
143#define DEFAULT_MAXBADGESIZE_SEQ 15000
144#define DEFAULT_MAXBADGESIZE_PAR (-1)
145#define DEFAULT_MARKOWITZTOLERANCE 0.01
146#define DEFAULT_MAXFILLINPERSUBST 3
147#define DEFAULT_MAXSHIFTPERROW 10
148#define DEFAULT_MAXEDGESPARALLEL 1000000
149#define DEFAULT_MAXEDGESSEQUENTIAL 100000
150#define DEFAULT_MAXCLIQUESIZE 100
151#define DEFAULT_MAXGREEDYCALLS 10000
154#define DEFAULT_FILENAME_PROBLEM "-"
155#define DEFAULT_VERBOSITY 0
163struct SCIP_PresolMilpData
168 int maxfillinpersubstitution;
171 int internalmaxrounds;
173 int detectlineardependency;
174#if PAPILO_APIVERSION >= 6
175 int maxedgesparallel;
176 int maxedgessequential;
189#if PAPILO_APIVERSION >= 6
200 char* filename =
NULL;
202typedef struct SCIP_PresolMilpData SCIP_PRESOLMILPDATA;
204using namespace papilo;
210#if defined(PAPILO_WITH_EXACTPRESOLVE)
216 papilo::Rational papiloval
222 res->
val = papilo::Rational(papiloval.backend().data());
232Problem<papilo::Rational> buildProblemRational(
237 ProblemBuilder<papilo::Rational> builder;
243 builder.reserve(nnz, nrows, ncols);
246 builder.setNumCols(ncols);
247 for(
int i = 0;
i != ncols; ++
i )
252 builder.setColLb(
i, lb->
val);
253 builder.setColUb(
i, ub->
val);
262 builder.setNumRows(nrows);
263 for(
int i = 0;
i != nrows; ++
i )
267 Vec<papilo::Rational> rowvals;
269 for(
int j = 0; j < rowlen; ++j )
270 rowvals.emplace_back(rowvalsscip[j]->val);
271 builder.addRowEntries(
i, rowlen, rowcols, rowvals.data());
275 builder.setRowLhs(
i, lhs->
val);
276 builder.setRowRhs(
i, rhs->
val);
281 builder.setObjOffset(0);
283 return builder.build();
289Problem<SCIP_Real> buildProblemReal(
294 ProblemBuilder<SCIP_Real> builder;
300 builder.reserve(nnz, nrows, ncols);
303 builder.setNumCols(ncols);
304 for(
int i = 0;
i != ncols; ++
i )
309 builder.setColLb(
i, lb);
310 builder.setColUb(
i, ub);
314#if PAPILO_VERSION_MAJOR > 2 || (PAPILO_VERSION_MAJOR == 2 && PAPILO_VERSION_MINOR >= 1)
321 builder.setNumRows(nrows);
322 for(
int i = 0;
i != nrows; ++
i )
327 builder.addRowEntries(
i, rowlen, rowcols, rowvals);
331 builder.setRowLhs(
i, lhs);
332 builder.setRowRhs(
i, rhs);
338 builder.setObjOffset(0);
340#ifdef SCIP_PRESOLLIB_ENABLE_OUTPUT
345 return builder.build();
354 SCIP_PRESOLMILPDATA* data,
362 presolve.getPresolveOptions().substitutebinarieswithints =
false;
367 presolve.getPresolveOptions().removeslackvars =
false;
370 presolve.getPresolveOptions().maxfillinpersubstitution = data->maxfillinpersubstitution;
371 presolve.getPresolveOptions().markowitz_tolerance = data->markowitztolerance;
372 presolve.getPresolveOptions().maxshiftperrow = data->maxshiftperrow;
373 presolve.getPresolveOptions().hugeval = data->hugebound;
376 presolve.getPresolveOptions().detectlindep = allowconsmodification ? data->detectlineardependency : 0;
382 presolve.getPresolveOptions().threads = data->threads;
384#if PAPILO_VERSION_MAJOR > 2 || (PAPILO_VERSION_MAJOR == 2 && PAPILO_VERSION_MINOR >= 3)
385 presolve.getPresolveOptions().maxrounds = data->internalmaxrounds;
390 presolve.getPresolveOptions().dualreds = 2;
392 presolve.getPresolveOptions().dualreds = 1;
394 presolve.getPresolveOptions().dualreds = 0;
397 using uptr = std::unique_ptr<PresolveMethod<T>>;
400 presolve.addPresolveMethod( uptr(
new SingletonCols<T>() ) );
401 presolve.addPresolveMethod( uptr(
new CoefficientStrengthening<T>() ) );
402 presolve.addPresolveMethod( uptr(
new ConstraintPropagation<T>() ) );
405 presolve.addPresolveMethod( uptr(
new SimpleProbing<T>() ) );
406 if( data->enableparallelrows )
407 presolve.addPresolveMethod( uptr(
new ParallelRowDetection<T>() ) );
410 presolve.addPresolveMethod( uptr(
new SingletonStuffing<T>() ) );
411#if PAPILO_VERSION_MAJOR > 2 || (PAPILO_VERSION_MAJOR == 2 && PAPILO_VERSION_MINOR >= 1)
412 DualFix<T> *dualfix =
new DualFix<T>();
413 dualfix->set_fix_to_infinity_allowed(
false);
414 presolve.addPresolveMethod( uptr( dualfix ) );
416 presolve.addPresolveMethod( uptr(
new DualFix<SCIP_Real>() ) );
418 presolve.addPresolveMethod( uptr(
new FixContinuous<T>() ) );
419 presolve.addPresolveMethod( uptr(
new SimplifyInequalities<T>() ) );
420 presolve.addPresolveMethod( uptr(
new SimpleSubstitution<T>() ) );
421#if PAPILO_APIVERSION >= 6
422 if( data->enablecliquemerging )
424 CliqueMerging<T>* cliquemerging =
new CliqueMerging<T>();
425 cliquemerging->setParameters( data->maxedgesparallel, data->maxedgessequential,
426 data->maxcliquesize, data->maxgreedycalls );
427 presolve.addPresolveMethod( uptr( cliquemerging ) );
432 presolve.addPresolveMethod( uptr(
new ImplIntDetection<T>() ) );
433 if( data->enabledualinfer )
434 presolve.addPresolveMethod( uptr(
new DualInfer<T>() ) );
435 if( data->enableprobing )
437#if PAPILO_VERSION_MAJOR > 2 || (PAPILO_VERSION_MAJOR == 2 && PAPILO_VERSION_MINOR >= 1)
438 Probing<T> *probing =
new Probing<T>();
439 if(
presolve.getPresolveOptions().runs_sequential() )
441 probing->set_max_badge_size( data->maxbadgesizeseq );
445 probing->set_max_badge_size( data->maxbadgesizepar );
447 presolve.addPresolveMethod( uptr( probing ) );
449 presolve.addPresolveMethod( uptr(
new Probing<T>() ) );
450 if( data->maxbadgesizeseq != DEFAULT_MAXBADGESIZE_SEQ )
452 " The parameter 'presolving/milp/maxbadgesizeseq' can only be used with PaPILO 2.1.0 or later versions.\n");
454 if( data->maxbadgesizepar != DEFAULT_MAXBADGESIZE_PAR )
456 " The parameter 'presolving/milp/maxbadgesizepar' can only be used with PaPILO 2.1.0 or later versions.\n");
459 if( data->enabledomcol )
460 presolve.addPresolveMethod( uptr(
new DominatedCols<T>() ) );
461 if( data->enablemultiaggr )
462 presolve.addPresolveMethod( uptr(
new Substitution<T>() ) );
463 if( data->enablesparsify )
464 presolve.addPresolveMethod( uptr(
new Sparsify<T>() ) );
467#if PAPILO_APIVERSION >= 3
468 presolve.getPresolveOptions().useabsfeas =
false;
472 presolve.getPresolveOptions().epsilon = 0.0;
473 presolve.getPresolveOptions().feastol = 0.0;
481#ifndef SCIP_PRESOLLIB_ENABLE_OUTPUT
483 presolve.setVerbosityLevel((VerbosityLevel) data->verbosity);
486#if PAPILO_APIVERSION >= 2
487 presolve.getPresolveOptions().abortfac = data->abortfacexhaustive;
488 presolve.getPresolveOptions().abortfacmedium = data->abortfacmedium;
489 presolve.getPresolveOptions().abortfacfast = data->abortfacfast;
501#if defined(PAPILO_WITH_EXACTPRESOLVE)
507 SCIP_PRESOLMILPDATA* data,
530 int oldnaggrvars = *naggrvars;
531 int oldnfixedvars = *nfixedvars;
532 int oldnchgbds = *nchgbds;
534 Problem<papilo::Rational> problem = buildProblemRational(
scip, matrix);
535 Presolve<papilo::Rational>
presolve;
536 setupPresolve(
scip,
presolve, data, allowconsmodification);
541 presolve.getPresolveOptions().threads == 1 ?
"" :
" on multiple threads");
543 int oldnnz = problem.getConstraintMatrix().getNnz();
545#if (PAPILO_VERSION_MAJOR >= 2)
546 PresolveResult<papilo::Rational> res =
presolve.apply(problem,
false);
548 PresolveResult<papilo::Rational> res =
presolve.apply(problem);
550 data->lastncols = problem.getNCols();
551 data->lastnrows = problem.getNRows();
556 case PresolveStatus::kInfeasible:
559 " (%.1fs) MILP presolver detected infeasibility\n",
563 case PresolveStatus::kUnbndOrInfeas:
564 case PresolveStatus::kUnbounded:
567 " (%.1fs) MILP presolver detected unboundedness\n",
571 case PresolveStatus::kUnchanged:
573 data->lastncols =
nvars;
574 data->lastnrows = nconss;
576 " (%.1fs) MILP presolver found nothing\n",
580 case PresolveStatus::kReduced:
581 data->lastncols = problem.getNCols();
582 data->lastnrows = problem.getNRows();
587 Vec<SCIP_VAR*> tmpvars;
588 Vec<SCIP_Real> tmpvalsreal;
591 int newnnz = problem.getConstraintMatrix().getNnz();
592 bool constraintsReplaced =
false;
593 if( newnnz == 0 || (allowconsmodification &&
594 (problem.getNRows() <= data->modifyconsfac * data->lastnrows ||
595 newnnz <= data->modifyconsfac * oldnnz)) )
598 int newnrows = problem.getNRows();
600 constraintsReplaced =
true;
603 for(
int i = 0;
i < newnrows; ++
i )
610 *ndelconss += oldnrows;
611 *naddconss += newnrows;
613 for(
int i = 0;
i < oldnrows; ++
i )
621 const Vec<RowFlags>& rflags = problem.getRowFlags();
622 const auto& consmatrix = problem.getConstraintMatrix();
623 for(
int i = 0;
i < newnrows; ++
i )
625 auto rowvec = consmatrix.getRowCoefficients(
i);
626 const int* rowcols = rowvec.getIndices();
628 papilo::Rational* rowvals =
const_cast<papilo::Rational*
>(rowvec.getValues());
629 int rowlen = rowvec.getLength();
632 papilo::Rational lhs = rflags[
i].test(RowFlag::kLhsInf) ? -
SCIPinfinity(
scip) : consmatrix.getLeftHandSides()[
i];
633 papilo::Rational rhs = rflags[
i].test(RowFlag::kRhsInf) ?
SCIPinfinity(
scip) : consmatrix.getRightHandSides()[
i];
637 tmpvars.reserve(rowlen);
638 for(
int j = 0; j < rowlen; ++j )
639 tmpvars.push_back(
SCIPmatrixGetVar(matrix, res.postsolve.origcol_mapping[rowcols[j]]));
652 for(
int j = 0; j < rowlen; j++ )
653 setRational(
scip, tmpvals[j], rowvals[j]);
655 setRational(
scip, tmprhs, rhs);
656 setRational(
scip, tmplhs, lhs);
657 if( rflags[
i].test(RowFlag::kLhsInf) )
659 if( rflags[
i].test(RowFlag::kRhsInf) )
676 for( std::size_t
i = 0;
i != res.postsolve.types.size(); ++
i )
679 res.postsolve.types[
i];
680 int first = res.postsolve.start[
i];
681 int last = res.postsolve.start[
i + 1];
685 case ReductionType::kFixedCol:
690 int col = res.postsolve.indices[first];
694 papilo::Rational value = res.postsolve.values[first];
697 setRational(
scip, tmpval, value);
746#if (PAPILO_VERSION_MAJOR >= 2)
747 case ReductionType::kSubstitutedColWithDual:
749 case ReductionType::kSubstitutedCol:
752 papilo::Rational side = 0;
755 int startRowCoefficients = 0;
756 int lastRowCoefficients = 0;
758 if( type == ReductionType::kSubstitutedCol )
760 rowlen = last - first - 1;
761 col = res.postsolve.indices[first];
762 side = res.postsolve.values[first];
764 startRowCoefficients = first + 1;
765 lastRowCoefficients = last;
767#if (PAPILO_VERSION_MAJOR >= 2)
768 if( type == ReductionType::kSubstitutedColWithDual )
770 rowlen = (int) res.postsolve.values[first];
771 col = res.postsolve.indices[first + 3 + rowlen];
772 side = res.postsolve.values[first + 1];
774 startRowCoefficients = first + 3;
775 lastRowCoefficients = first + 3 + rowlen;
777 assert(side == res.postsolve.values[first + 2]);
778 assert(res.postsolve.indices[first + 1] == 0);
779 assert(res.postsolve.indices[first + 2] == 0);
781 assert( type == ReductionType::kSubstitutedCol || type == ReductionType::kSubstitutedColWithDual );
783 assert( type == ReductionType::kSubstitutedCol );
793 papilo::Rational scalarx = res.postsolve.values[startRowCoefficients];
794 papilo::Rational scalary = res.postsolve.values[startRowCoefficients + 1];
804 setRational(
scip, tmpscalarx, scalarx);
805 setRational(
scip, tmpscalary, scalary);
813 setRational(
scip, tmpside, side);
817 tmpscalarx, tmpscalary, constant);
838 for(
int j = startRowCoefficients; j < lastRowCoefficients; ++j )
840 if( res.postsolve.indices[j] == col )
842 setRational(
scip, colCoef, res.postsolve.values[j]);
848 tmpvars.reserve(rowlen);
856 for(
int j = startRowCoefficients; j < lastRowCoefficients; ++j )
858 if( res.postsolve.indices[j] == col )
862 setRational(
scip, tmpvals[
c], -res.postsolve.values[j] / colCoef->
val);
865 setRational(
scip, updatedSide, side);
872 tmpvars.data(), tmpvals, updatedSide, &infeas, &aggregated) );
882 else if( constraintsReplaced && !redundant )
891 setRational(
scip, tmpside, side);
894 for(
int j = startRowCoefficients; j < lastRowCoefficients; ++j )
896 int idx = j - startRowCoefficients;
898 setRational(
scip, tmpvals[idx], res.postsolve.values[j]);
904 tmpvars.size(), tmpvars.data(), tmpvals, tmpside, tmpside ) );
924 case ReductionType::kParallelCol:
926#if (PAPILO_VERSION_MAJOR <= 1 && PAPILO_VERSION_MINOR==0)
928 case ReductionType::kFixedInfCol: {
929 if(!constraintsReplaced)
938 int column = res.postsolve.indices[first];
939 bool is_negative_infinity = res.postsolve.values[first] < 0;
942 if( is_negative_infinity )
958#if (PAPILO_VERSION_MAJOR >= 2)
959 case ReductionType::kVarBoundChange :
960 case ReductionType::kRedundantRow :
961 case ReductionType::kRowBoundChange :
962 case ReductionType::kReasonForRowBoundChangeForcedByRow :
963 case ReductionType::kRowBoundChangeForcedByRow :
964 case ReductionType::kSaveRow :
965 case ReductionType::kReducedBoundsCost :
966 case ReductionType::kColumnDualValue :
967 case ReductionType::kRowDualValue :
968 case ReductionType::kCoefficientChange :
970 SCIPerrorMessage(
"PaPILO: PaPILO should not return dual postsolving reductions in SCIP!!\n");
983 VariableDomains<papilo::Rational>& varDomains = problem.getVariableDomains();
988 for(
int i = 0;
i != problem.getNCols(); ++
i )
991 if( !varDomains.flags[
i].test(ColFlag::kLbInf) )
996 setRational(
scip, varbound, varDomains.lower_bounds[
i]);
1013 if( !varDomains.flags[
i].test(ColFlag::kUbInf) )
1017 setRational(
scip, varbound, varDomains.upper_bounds[
i]);
1040 " (%.1fs) MILP presolver (%d rounds): %d aggregations, %d fixings, %d bound changes\n",
1042 *nfixedvars - oldnfixedvars, *nchgbds - oldnchgbds);
1057 SCIP_PRESOLMILPDATA* data,
1081 int oldnaggrvars = *naggrvars;
1082 int oldnfixedvars = *nfixedvars;
1083 int oldnchgbds = *nchgbds;
1086 Problem<SCIP_Real> problem = buildProblemReal(
scip, matrix);
1087 int oldnnz = problem.getConstraintMatrix().getNnz();
1089 setupPresolve(
scip,
presolve, data, allowconsmodification);
1094 presolve.getPresolveOptions().threads == 1 ?
"" :
" on multiple threads");
1097#if (PAPILO_VERSION_MAJOR >= 2)
1098 PresolveResult<SCIP_Real> res =
presolve.apply(problem,
false);
1100 PresolveResult<SCIP_Real> res =
presolve.apply(problem);
1102 data->lastncols = problem.getNCols();
1103 data->lastnrows = problem.getNRows();
1106 switch( res.status )
1108 case PresolveStatus::kInfeasible:
1111 " (%.1fs) MILP presolver detected infeasibility\n",
1115 case PresolveStatus::kUnbndOrInfeas:
1116 case PresolveStatus::kUnbounded:
1119 " (%.1fs) MILP presolver detected unboundedness\n",
1123 case PresolveStatus::kUnchanged:
1125 data->lastncols =
nvars;
1126 data->lastnrows = nconss;
1128 " (%.1fs) MILP presolver found nothing\n",
1132 case PresolveStatus::kReduced:
1133 data->lastncols = problem.getNCols();
1134 data->lastnrows = problem.getNRows();
1141 VariableDomains<SCIP_Real>& varDomains = problem.getVariableDomains();
1142 for(
int i = 0;
i != problem.getNCols(); ++
i )
1144 assert( ! varDomains.flags[
i].test(ColFlag::kInactive) );
1146 if( !varDomains.flags[
i].test(ColFlag::kLbInf) )
1162 if( !varDomains.flags[
i].test(ColFlag::kUbInf) )
1182 " (%.1fs) MILP presolver detected infeasibility\n",
1189 Vec<SCIP_VAR*> tmpvars;
1190 Vec<SCIP_Real> tmpvals;
1193 int newnnz = problem.getConstraintMatrix().getNnz();
1194 bool constraintsReplaced =
false;
1195 if( newnnz == 0 || (allowconsmodification &&
1198 newnnz <= data->modifyconsfac * oldnnz)) )
1201 int newnrows = problem.getNRows();
1203 constraintsReplaced =
true;
1206 for(
int i = 0;
i < newnrows; ++
i )
1213 *ndelconss += oldnrows;
1214 *naddconss += newnrows;
1216 for(
int i = 0;
i < oldnrows; ++
i )
1223 const Vec<RowFlags>& rflags = problem.getRowFlags();
1224 const auto& consmatrix = problem.getConstraintMatrix();
1225 for(
int i = 0;
i < newnrows; ++
i )
1227 auto rowvec = consmatrix.getRowCoefficients(
i);
1228 const int* rowcols = rowvec.getIndices();
1231 int rowlen = rowvec.getLength();
1239 tmpvars.reserve(rowlen);
1240 for(
int j = 0; j < rowlen; ++j )
1241 tmpvars.push_back(
SCIPmatrixGetVar(matrix, res.postsolve.origcol_mapping[rowcols[j]]));
1263 bool checkmultaggr =
1264#if PAPILO_APIVERSION >= 1
1265 presolve.getStatistics().single_matrix_coefficient_changes > 0
1267 presolve.getStatistics().ncoefchgs > 0
1269 && !constraintsReplaced;
1272 for( std::size_t
i = 0;
i != res.postsolve.types.size(); ++
i )
1274 ReductionType type = res.postsolve.types[
i];
1275 int first = res.postsolve.start[
i];
1276 int last = res.postsolve.start[
i + 1];
1280 case ReductionType::kFixedCol:
1284 int col = res.postsolve.indices[first];
1288 SCIP_Real value = res.postsolve.values[first];
1307#if (PAPILO_VERSION_MAJOR >= 2)
1308 case ReductionType::kSubstitutedColWithDual:
1310 case ReductionType::kSubstitutedCol:
1316 int startRowCoefficients = 0;
1317 int lastRowCoefficients = 0;
1319 if( type == ReductionType::kSubstitutedCol )
1321 rowlen = last - first - 1;
1322 col = res.postsolve.indices[first];
1323 side = res.postsolve.values[first];
1325 startRowCoefficients = first + 1;
1326 lastRowCoefficients = last;
1328#if (PAPILO_VERSION_MAJOR >= 2)
1329 if( type == ReductionType::kSubstitutedColWithDual )
1331 rowlen = (int) res.postsolve.values[first];
1332 col = res.postsolve.indices[first + 3 + rowlen];
1333 side = res.postsolve.values[first + 1];
1335 startRowCoefficients = first + 3;
1336 lastRowCoefficients = first + 3 + rowlen;
1338 assert(side == res.postsolve.values[first + 2]);
1339 assert(res.postsolve.indices[first + 1] == 0);
1340 assert(res.postsolve.indices[first + 2] == 0);
1342 assert( type == ReductionType::kSubstitutedCol || type == ReductionType::kSubstitutedColWithDual );
1344 assert( type == ReductionType::kSubstitutedCol );
1355 SCIP_Real scalarx = res.postsolve.values[startRowCoefficients];
1356 SCIP_Real scalary = res.postsolve.values[startRowCoefficients + 1];
1370 SCIPdebugMsg(
scip,
"Aggregation of <%s> and <%s> rejected because they are already fixed.\n",
1376 updatedSide = side - constant;
1390 for( j = startRowCoefficients; j < lastRowCoefficients; ++j )
1392 if( res.postsolve.indices[j] == col )
1394 colCoef = res.postsolve.values[j];
1401 tmpvars.reserve(rowlen);
1402 tmpvals.reserve(rowlen);
1416 SCIPdebugMsg(
scip,
"Multi-aggregation of <%s> rejected because it is already fixed.\n",
1422 updatedSide = side - constant;
1430 impliedlb = impliedub = updatedSide / colCoef;
1432 for( j = startRowCoefficients; j < lastRowCoefficients; ++j )
1437 if( res.postsolve.indices[j] == col )
1440 coef = - res.postsolve.values[j] / colCoef;
1443 if( checklbimplied )
1462 if( checkubimplied )
1480 tmpvals.push_back(coef);
1481 tmpvars.push_back(
var);
1485 if( j < lastRowCoefficients )
1495 tmpvars.data(), tmpvals.data(), updatedSide / colCoef, &infeas, &aggregated) );
1500 else if( constraintsReplaced && !redundant )
1505 for(
int j = startRowCoefficients; j < lastRowCoefficients; ++j )
1508 tmpvals.push_back(res.postsolve.values[j]);
1514 tmpvars.size(), tmpvars.data(), tmpvals.data(), side, side ) );
1528 case ReductionType::kParallelCol:
1530#if PAPILO_VERSION_MAJOR > 1 || (PAPILO_VERSION_MAJOR == 1 && PAPILO_VERSION_MINOR >= 1)
1531 case ReductionType::kFixedInfCol: {
1534 if(!constraintsReplaced)
1540 int column = res.postsolve.indices[first];
1541 bool is_negative_infinity = res.postsolve.values[first] < 0;
1544 if( is_negative_infinity )
1557#if (PAPILO_VERSION_MAJOR >= 2)
1558 case ReductionType::kVarBoundChange :
1559 case ReductionType::kRedundantRow :
1560 case ReductionType::kRowBoundChange :
1561 case ReductionType::kReasonForRowBoundChangeForcedByRow :
1562 case ReductionType::kRowBoundChangeForcedByRow :
1563 case ReductionType::kSaveRow :
1564 case ReductionType::kReducedBoundsCost :
1565 case ReductionType::kColumnDualValue :
1566 case ReductionType::kRowDualValue :
1567 case ReductionType::kCoefficientChange :
1569 SCIPerrorMessage(
"PaPILO: PaPILO should not return dual postsolving reductions in SCIP!!\n");
1581 " (%.1fs) MILP presolver (%d rounds): %d aggregations, %d fixings, %d bound changes\n",
1583 *nfixedvars - oldnfixedvars, *nchgbds - oldnchgbds);
1625 data->lastncols = -1;
1626 data->lastnrows = -1;
1637 SCIP_PRESOLMILPDATA* data;
1650 if( data->lastncols != -1 && data->lastnrows != -1 &&
1651 nvars > data->lastncols * 0.85 &&
1652 nconss > data->lastnrows * 0.85 )
1656 naddconss, ndelconss, nchgcoefs, nchgbds, nfixedvars) );
1669 if( !initialized || !complete )
1671 data->lastncols = 0;
1672 data->lastnrows = 0;
1680 if( 0 != strncmp(data->filename, DEFAULT_FILENAME_PROBLEM, strlen(DEFAULT_FILENAME_PROBLEM)) )
1683 " writing transformed problem to %s (only enforced constraints)\n", data->filename);
1688 return performRealPresolving(
scip, matrix, data, initialized, nfixedvars, naggrvars, nchgvartypes, nchgbds,
1689 naddholes, ndelconss, naddconss, nupgdconss, nchgcoefs, nchgsides,
result);
1690#if defined(PAPILO_WITH_EXACTPRESOLVE)
1692 return performRationalPresolving(
scip, matrix, data, initialized, nfixedvars, naggrvars, nchgvartypes, nchgbds,
1693 naddholes, ndelconss, naddconss, nupgdconss, nchgcoefs, nchgsides,
result);
1709 SCIP_PRESOLMILPDATA* presoldata;
1712#if defined(PAPILO_VERSION_TWEAK) && PAPILO_VERSION_TWEAK != 0
1713 String name = fmt::format(
"PaPILO {}.{}.{}.{}", PAPILO_VERSION_MAJOR, PAPILO_VERSION_MINOR, PAPILO_VERSION_PATCH, PAPILO_VERSION_TWEAK);
1715 String name = fmt::format(
"PaPILO {}.{}.{}", PAPILO_VERSION_MAJOR, PAPILO_VERSION_MINOR, PAPILO_VERSION_PATCH);
1718#if defined(PAPILO_GITHASH_AVAILABLE) && defined(PAPILO_TBB)
1719 String desc = fmt::format(
"parallel presolve for integer and linear optimization (github.com/scipopt/papilo) (built with TBB) [GitHash: {}]", PAPILO_GITHASH);
1720#elif !defined(PAPILO_GITHASH_AVAILABLE) && !defined(PAPILO_TBB)
1721 String desc(
"parallel presolve for integer and linear optimization (github.com/scipopt/papilo)");
1722#elif defined(PAPILO_GITHASH_AVAILABLE) && !defined(PAPILO_TBB)
1723 String desc = fmt::format(
"parallel presolve for integer and linear optimization (github.com/scipopt/papilo) [GitHash: {}]", PAPILO_GITHASH);
1724#elif !defined(PAPILO_GITHASH_AVAILABLE) && defined(PAPILO_TBB)
1725 String desc = fmt::format(
"parallel presolve for integer and linear optimization (github.com/scipopt/papilo) (built with TBB)");
1750#if defined(PAPILO_WITH_EXACTPRESOLVE)
1759 "maximum number of threads presolving may use (0: automatic)",
1760 &presoldata->threads,
FALSE, DEFAULT_THREADS, 0, INT_MAX,
NULL,
NULL) );
1762 presoldata->threads = 1;
1766 "presolving/" PRESOL_NAME "/maxfillinpersubstitution",
1767 "maximal possible fillin for substitutions to be considered",
1768 &presoldata->maxfillinpersubstitution,
FALSE, DEFAULT_MAXFILLINPERSUBST, INT_MIN, INT_MAX,
NULL,
NULL) );
1772 "maximal amount of nonzeros allowed to be shifted to make space for substitutions",
1773 &presoldata->maxshiftperrow,
TRUE, DEFAULT_MAXSHIFTPERROW, 0, INT_MAX,
NULL,
NULL) );
1777 "the random seed used for randomization of tie breaking",
1780 if( DependentRows<double>::Enabled )
1783 "presolving/" PRESOL_NAME "/detectlineardependency",
1784 "should linear dependent equations and free columns be removed? (0: never, 1: for LPs, 2: always)",
1785 &presoldata->detectlineardependency,
TRUE, DEFAULT_DETECTLINDEP, 0, 2,
NULL,
NULL) );
1788 presoldata->detectlineardependency = DEFAULT_DETECTLINDEP;
1792 "modify SCIP constraints when the number of nonzeros or rows is at most this factor "
1793 "times the number of nonzeros or rows before presolving",
1794 &presoldata->modifyconsfac,
FALSE, DEFAULT_MODIFYCONSFAC, 0.0, 1.0,
NULL,
NULL) );
1798 "the markowitz tolerance used for substitutions",
1799 &presoldata->markowitztolerance,
FALSE, DEFAULT_MARKOWITZTOLERANCE, 0.0, 1.0,
NULL,
NULL) );
1803 "absolute bound value that is considered too huge for activity based calculations",
1806#if PAPILO_APIVERSION >= 2
1808 "abort threshold for exhaustive presolving in PAPILO",
1809 &presoldata->abortfacexhaustive,
TRUE, DEFAULT_ABORTFAC_EXHAUSTIVE, 0.0, 1.0,
NULL,
NULL) );
1811 "abort threshold for medium presolving in PAPILO",
1812 &presoldata->abortfacmedium,
TRUE, DEFAULT_ABORTFAC_MEDIUM, 0.0, 1.0,
NULL,
NULL) );
1814 "abort threshold for fast presolving in PAPILO",
1815 &presoldata->abortfacfast,
TRUE, DEFAULT_ABORTFAC_FAST, 0.0, 1.0,
NULL,
NULL) );
1817 presoldata->abortfacexhaustive = DEFAULT_ABORTFAC_EXHAUSTIVE;
1818 presoldata->abortfacmedium = DEFAULT_ABORTFAC_MEDIUM;
1819 presoldata->abortfacfast = DEFAULT_ABORTFAC_FAST;
1822#if PAPILO_VERSION_MAJOR > 2 || (PAPILO_VERSION_MAJOR == 2 && PAPILO_VERSION_MINOR >= 1)
1824 "maximal badge size in Probing in PaPILO if PaPILO is executed in sequential mode",
1825 &presoldata->maxbadgesizeseq,
FALSE, DEFAULT_MAXBADGESIZE_SEQ, -1, INT_MAX,
NULL,
NULL) );
1828 "maximal badge size in Probing in PaPILO if PaPILO is executed in parallel mode",
1829 &presoldata->maxbadgesizepar,
FALSE, DEFAULT_MAXBADGESIZE_PAR, -1, INT_MAX,
NULL,
NULL) );
1831 presoldata->maxbadgesizeseq = DEFAULT_MAXBADGESIZE_SEQ;
1832 presoldata->maxbadgesizepar = DEFAULT_MAXBADGESIZE_PAR;
1835#if PAPILO_VERSION_MAJOR > 2 || (PAPILO_VERSION_MAJOR == 2 && PAPILO_VERSION_MINOR >= 3)
1837 "internal maxrounds for each milp presolving (-1: no limit, 0: model cleanup)",
1838 &presoldata->internalmaxrounds,
TRUE, DEFAULT_INTERNAL_MAXROUNDS, -1, INT_MAX,
NULL,
NULL) );
1840 presoldata->internalmaxrounds = DEFAULT_INTERNAL_MAXROUNDS;
1845 "should the parallel rows presolver be enabled within the presolve library?",
1846 &presoldata->enableparallelrows,
TRUE, DEFAULT_ENABLEPARALLELROWS,
NULL,
NULL) );
1850 "should the dominated column presolver be enabled within the presolve library?",
1851 &presoldata->enabledomcol,
TRUE, DEFAULT_ENABLEDOMCOL,
NULL,
NULL) );
1855 "should the dualinfer presolver be enabled within the presolve library?",
1856 &presoldata->enabledualinfer,
TRUE, DEFAULT_ENABLEDUALINFER,
NULL,
NULL) );
1860 "should the multi-aggregation presolver be enabled within the presolve library?",
1861 &presoldata->enablemultiaggr,
TRUE, DEFAULT_ENABLEMULTIAGGR,
NULL,
NULL) );
1865 "should the probing presolver be enabled within the presolve library?",
1866 &presoldata->enableprobing,
TRUE, DEFAULT_ENABLEPROBING,
NULL,
NULL) );
1870 "should the sparsify presolver be enabled within the presolve library?",
1871 &presoldata->enablesparsify,
TRUE, DEFAULT_ENABLESPARSIFY,
NULL,
NULL) );
1874 "filename to store the problem before MILP presolving starts (only enforced constraints)",
1875 &presoldata->filename,
TRUE, DEFAULT_FILENAME_PROBLEM,
NULL,
NULL) );
1878 "verbosity level of PaPILO (0: quiet, 1: errors, 2: warnings, 3: normal, 4: detailed)",
1879 &presoldata->verbosity,
FALSE, DEFAULT_VERBOSITY, 0, 4,
NULL,
NULL) );
1880#if PAPILO_APIVERSION >= 6
1883 "should the clique merging presolver be enabled within the presolve library?",
1884 &presoldata->enablecliquemerging,
TRUE, DEFAULT_ENABLESPARSIFY,
NULL,
NULL) );
1887 "maximal amount of edges in the parallel clique merging graph",
1888 &presoldata->maxedgesparallel,
FALSE, DEFAULT_MAXEDGESPARALLEL, -1, INT_MAX,
NULL,
NULL) );
1891 "maximal amount of edges in the sequential clique merging graph",
1892 &presoldata->maxedgessequential,
FALSE, DEFAULT_MAXEDGESSEQUENTIAL, -1, INT_MAX,
NULL,
NULL) );
1895 "maximal size of clique considered for clique merging",
1896 &presoldata->maxcliquesize,
FALSE, DEFAULT_MAXCLIQUESIZE, -1, INT_MAX,
NULL,
NULL) );
1899 "maximal number of greedy max clique calls in a single thread",
1900 &presoldata->maxgreedycalls,
FALSE, DEFAULT_MAXGREEDYCALLS, -1, INT_MAX,
NULL,
NULL) );
Constraint handler for linear constraints in their most general form, .
Constraint handler for linear constraints in their most general form, .
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)
SCIP_RETCODE SCIPcreateConsBasicExactLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_RATIONAL **vals, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs)
const char * SCIPgetProbName(SCIP *scip)
int SCIPgetNVars(SCIP *scip)
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNConss(SCIP *scip)
SCIP_RETCODE SCIPwriteTransProblem(SCIP *scip, const char *filename, const char *extension, SCIP_Bool genericnames)
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
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)
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)
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)
SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
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)
SCIP_RETCODE SCIPincludePresolMILP(SCIP *scip)
int SCIPconshdlrGetNCheckConss(SCIP_CONSHDLR *conshdlr)
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
const char * SCIPconsGetName(SCIP_CONS *cons)
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
SCIP_RETCODE SCIPcaptureCons(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisExact(SCIP *scip)
SCIP_RETCODE SCIPincludeExternalCodeInformation(SCIP *scip, const char *name, const char *description)
BMS_BUFMEM * SCIPbuffer(SCIP *scip)
#define SCIPfreeBlockMemory(scip, ptr)
#define SCIPallocBlockMemory(scip, ptr)
SCIP_RETCODE SCIPsetPresolFree(SCIP *scip, SCIP_PRESOL *presol,)
void SCIPpresolMarkExact(SCIP_PRESOL *presol)
void SCIPpresolSetData(SCIP_PRESOL *presol, SCIP_PRESOLDATA *presoldata)
SCIP_PRESOLDATA * SCIPpresolGetData(SCIP_PRESOL *presol)
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,)
void SCIPrationalSetInfinity(SCIP_RATIONAL *res)
SCIP_Real SCIPrationalGetReal(SCIP_RATIONAL *rational)
#define SCIPrationalDebugMessage
void SCIPrationalDiv(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
SCIP_Bool SCIPrationalIsAbsInfinity(SCIP_RATIONAL *rational)
void SCIPrationalFreeBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
void SCIPrationalDiff(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
SCIP_Bool SCIPrationalIsZero(SCIP_RATIONAL *rational)
void SCIPrationalSetNegInfinity(SCIP_RATIONAL *res)
SCIP_Bool SCIPrationalIsNegative(SCIP_RATIONAL *rational)
SCIP_Bool SCIPrationalIsInfinity(SCIP_RATIONAL *rational)
SCIP_RETCODE SCIPrationalCreateBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***rational, int size)
SCIP_Bool SCIPrationalIsNegInfinity(SCIP_RATIONAL *rational)
void SCIPrationalMultReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
void SCIPrationalFreeBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***ratbufarray, int size)
SCIP_Real SCIPgetSolvingTime(SCIP *scip)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfeastol(SCIP *scip)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPepsilon(SCIP *scip)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
SCIP_RETCODE SCIPtightenVarUbExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound, SCIP_Bool *infeasible, SCIP_Bool *tightened)
SCIP_RATIONAL * SCIPvarGetAggrScalarExact(SCIP_VAR *var)
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
SCIP_RETCODE SCIPaggregateVarsExact(SCIP *scip, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_RATIONAL *scalarx, SCIP_RATIONAL *scalary, SCIP_RATIONAL *rhs, SCIP_Bool *infeasible, SCIP_Bool *redundant, SCIP_Bool *aggregated)
SCIP_RATIONAL * SCIPvarGetAggrConstantExact(SCIP_VAR *var)
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)
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
SCIP_RETCODE SCIPgetProbvarSum(SCIP *scip, SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
SCIP_VARSTATUS SCIPvarGetStatusExact(SCIP_VAR *var)
const char * SCIPvarGetName(SCIP_VAR *var)
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)
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
SCIP_RATIONAL * SCIPvarGetLbGlobalExact(SCIP_VAR *var)
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
SCIP_RETCODE SCIPgetProbvarSumExact(SCIP *scip, SCIP_VAR **var, SCIP_RATIONAL *scalar, SCIP_RATIONAL *constant)
SCIP_RATIONAL * SCIPvarGetObjExact(SCIP_VAR *var)
SCIP_Bool SCIPallowWeakDualReds(SCIP *scip)
SCIP_RETCODE SCIPmultiaggregateVarExact(SCIP *scip, SCIP_VAR *var, int naggvars, SCIP_VAR **aggvars, SCIP_RATIONAL **scalars, SCIP_RATIONAL *constant, SCIP_Bool *infeasible, SCIP_Bool *aggregated)
SCIP_RETCODE SCIPtightenVarLbExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound, SCIP_Bool *infeasible, SCIP_Bool *tightened)
SCIP_Bool SCIPallowStrongDualReds(SCIP *scip)
SCIP_RATIONAL * SCIPvarGetUbGlobalExact(SCIP_VAR *var)
SCIP_RETCODE SCIPfixVarExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
SCIP_VAR * SCIPvarGetAggrVar(SCIP_VAR *var)
unsigned int SCIPinitializeRandomSeed(SCIP *scip, unsigned int initialseedvalue)
assert(minobj< SCIPgetCutoffbound(scip))
int SCIPmatrixGetNNonzs(SCIP_MATRIX *matrix)
SCIP_RATIONAL * SCIPmatrixGetRowLhsExact(SCIP_MATRIX *matrix, int row)
int SCIPmatrixGetRowNNonzs(SCIP_MATRIX *matrix, int row)
SCIP_Real SCIPmatrixGetRowLhs(SCIP_MATRIX *matrix, int row)
SCIP_Real * SCIPmatrixGetRowValPtr(SCIP_MATRIX *matrix, int row)
SCIP_RATIONAL ** SCIPmatrixGetRowValPtrExact(SCIP_MATRIX *matrix, int row)
SCIP_Real SCIPmatrixGetRowRhs(SCIP_MATRIX *matrix, int row)
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)
int SCIPmatrixGetNColumns(SCIP_MATRIX *matrix)
SCIP_CONS * SCIPmatrixGetCons(SCIP_MATRIX *matrix, int row)
void SCIPmatrixFree(SCIP *scip, SCIP_MATRIX **matrix)
SCIP_VAR * SCIPmatrixGetVar(SCIP_MATRIX *matrix, int col)
SCIP_RATIONAL * SCIPmatrixGetRowRhsExact(SCIP_MATRIX *matrix, int row)
int * SCIPmatrixGetRowIdxPtr(SCIP_MATRIX *matrix, int row)
int SCIPmatrixGetNRows(SCIP_MATRIX *matrix)
#define BMSclearMemory(ptr)
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
public methods for presolvers
public methods for problem variables
wrapper for rational number arithmetic
#define DEFAULT_RANDOMSEED
public methods for constraint handler plugins and constraints
public methods for exact solving
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
unsigned int isfprepresentable
definition of wrapper class for rational numbers
struct SCIP_Cons SCIP_CONS
struct SCIP_Conshdlr SCIP_CONSHDLR
struct SCIP_Matrix SCIP_MATRIX
#define SCIP_DECL_PRESOLCOPY(x)
struct SCIP_PresolData SCIP_PRESOLDATA
#define SCIP_DECL_PRESOLFREE(x)
struct SCIP_Presol SCIP_PRESOL
#define SCIP_DECL_PRESOLINIT(x)
#define SCIP_DECL_PRESOLEXEC(x)
struct SCIP_Rational SCIP_RATIONAL
@ SCIP_ISFPREPRESENTABLE_UNKNOWN
enum SCIP_Result SCIP_RESULT
enum SCIP_Retcode SCIP_RETCODE
@ SCIP_VARTYPE_CONTINUOUS
@ SCIP_VARSTATUS_MULTAGGR
@ SCIP_VARSTATUS_AGGREGATED