35#pragma GCC diagnostic ignored "-Wsign-compare"
36#pragma GCC diagnostic ignored "-Wpedantic"
37#pragma GCC diagnostic ignored "-Wignored-qualifiers"
38#pragma GCC diagnostic ignored "-Wshadow"
39#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
40#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
41#pragma GCC diagnostic ignored "-Woverflow"
43#include "ortools/base/version.h"
44#include "ortools/glop/lp_solver.h"
45#include "ortools/glop/revised_simplex.h"
46#include "ortools/lp_data/lp_print_utils.h"
47#include "ortools/lp_data/lp_data_utils.h"
48#include "ortools/lp_data/proto_utils.h"
49#include "ortools/util/file_util.h"
50#include "ortools/util/stats.h"
51#include "ortools/util/time_limit.h"
53#include "ortools/base/logging.h"
54#include "ortools/base/vlog_is_on.h"
62#pragma GCC diagnostic warning "-Wsign-compare"
63#pragma GCC diagnostic warning "-Wpedantic"
64#pragma GCC diagnostic warning "-Wignored-qualifiers"
65#pragma GCC diagnostic warning "-Wshadow"
66#pragma GCC diagnostic warning "-Wnon-virtual-dtor"
67#pragma GCC diagnostic warning "-Wctor-dtor-privacy"
68#pragma GCC diagnostic warning "-Woverflow"
71using operations_research::TimeLimit;
72using operations_research::glop::BasisState;
73using operations_research::glop::ColIndex;
74using operations_research::glop::ColIndexVector;
75using operations_research::glop::ConstraintStatus;
76using operations_research::glop::ConstraintStatusColumn;
77using operations_research::glop::DenseBooleanColumn;
78using operations_research::glop::DenseBooleanRow;
79using operations_research::glop::DenseColumn;
80using operations_research::glop::DenseRow;
81using operations_research::glop::SparseColumn;
82using operations_research::glop::ScatteredColumn;
83using operations_research::glop::ScatteredColumnIterator;
84using operations_research::glop::SparseMatrix;
85using operations_research::glop::Fractional;
86using operations_research::glop::GetProblemStatusString;
87using operations_research::glop::ProblemStatus;
88using operations_research::glop::RowIndex;
89using operations_research::glop::ScatteredRow;
90using operations_research::glop::ScatteredRowIterator;
91using operations_research::glop::VariableStatus;
92using operations_research::glop::VariableStatusRow;
93using operations_research::MPModelProto;
99 operations_research::glop::LinearProgram*
scaled_lp;
100 operations_research::glop::RevisedSimplex*
solver;
102 operations_research::glop::LpScalingHelper*
scaler;
133#define UNSCALEDFEAS_CHECK 0
135#define UNSCALEDFEAS_CHECK 2
150 (void) snprintf(
glopname, 100,
"Glop %d.%d", operations_research::OrToolsMajorVersion(), operations_research::OrToolsMinorVersion());
167 return "Glop Linear Solver, developed by Google, part of OR-Tools (developers.google.com/optimization)";
177 SCIPerrorMessage(
"SCIPlpiGetSolverPointer() has not been implemented yet.\n");
194 for (ColIndex col(0); col < ColIndex(ncols); ++col)
197 int info = intInfo[col.value()];
198 assert( info == 0 || info == 1 );
200 lpi->
linear_program->SetVariableType(col, operations_research::glop::LinearProgram::VariableType::CONTINUOUS);
202 lpi->
linear_program->SetVariableType(col, operations_research::glop::LinearProgram::VariableType::INTEGER);
253 (*lpi)->linear_program =
new operations_research::glop::LinearProgram();
254 (*lpi)->scaled_lp =
new operations_research::glop::LinearProgram();
255 (*lpi)->solver =
new operations_research::glop::RevisedSimplex();
256 (*lpi)->parameters =
new operations_research::glop::GlopParameters();
257 (*lpi)->scaler =
new operations_research::glop::LpScalingHelper();
260 (*lpi)->linear_program->SetName(std::string(name));
263 (*lpi)->from_scratch =
false;
264 (*lpi)->lp_info =
false;
266 (*lpi)->lp_modified_since_last_solve =
true;
267 (*lpi)->lp_time_limit_was_reached =
false;
268 (*lpi)->conditionlimit = -1.0;
269 (*lpi)->checkcondition =
false;
270 (*lpi)->niterations = 0LL;
272 (*lpi)->tmp_row =
new ScatteredRow();
273 (*lpi)->tmp_column =
new ScatteredColumn();
276 (*lpi)->parameters->set_use_scaling(
false);
289 delete (*lpi)->scaler;
290 delete (*lpi)->parameters;
291 delete (*lpi)->solver;
292 delete (*lpi)->scaled_lp;
293 delete (*lpi)->linear_program;
295 delete (*lpi)->tmp_row;
296 delete (*lpi)->tmp_column;
386 for (
int j = 0; j < nnonz; ++j)
388 assert( 0 <= ind[j] && ind[j] < num_rows.value() );
394 for (
int i = 0;
i < ncols; ++
i)
399 const int end = (
i == ncols - 1) ? nnonz : beg[
i + 1];
410 for (
int i = 0;
i < ncols; ++
i)
433 assert(lastcol < lpi->linear_program->num_variables());
434 assert(firstcol <= lastcol + 1);
439 if( firstcol > lastcol )
443 DenseBooleanRow columns_to_delete(num_cols,
false);
444 for(
int i = firstcol;
i <= lastcol; ++
i )
445 columns_to_delete[ColIndex(
i)] =
true;
466 DenseBooleanRow columns_to_delete(num_cols,
false);
468 int num_deleted_columns = 0;
469 for (ColIndex col(0); col < num_cols; ++col)
474 columns_to_delete[col] =
true;
476 ++num_deleted_columns;
479 dstat[
i] = new_index++;
481 SCIPdebugMessage(
"SCIPlpiDelColset: deleting %d columns.\n", num_deleted_columns);
521 for (
int j = 0; j < nnonz; ++j)
524 assert( 0 <= ind[j] && ind[j] < num_cols.value() );
529 for (
int i = 0;
i < nrows; ++
i)
533 const int end = (
i == nrows - 1) ? nnonz : beg[
i + 1];
536 lpi->
linear_program->SetCoefficient(row, ColIndex(ind[nz]), val[nz]);
544 for (
int i = 0;
i < nrows; ++
i)
560 const DenseBooleanColumn& rows_to_delete
568 if ( state.statuses.size() == num_cols.value() + num_rows.value() )
572 ColIndex new_size = num_cols;
573 for (
RowIndex row(0); row < num_rows; ++row)
575 if ( rows_to_delete[row] )
577 state.statuses[new_size++] = state.statuses[num_cols + RowToColIndex(row)];
579 state.statuses.resize(new_size);
580 lpi->
solver->LoadStateForNextSolve(state);
597 assert(lastrow < lpi->linear_program->num_constraints());
598 assert(firstrow <= lastrow + 1);
603 if( firstrow > lastrow )
607 DenseBooleanColumn rows_to_delete(num_rows,
false);
608 for(
int i = firstrow;
i <= lastrow; ++
i )
628 DenseBooleanColumn rows_to_delete(num_rows,
false);
630 int num_deleted_rows = 0;
631 for (
RowIndex row(0); row < num_rows; ++row)
636 rows_to_delete[row] =
true;
641 dstat[
i] = new_index++;
644 SCIPdebugMessage(
"SCIPlpiDelRowset: deleting %d rows.\n", num_deleted_rows);
683 for (
int i = 0;
i < ncols; ++
i)
689 SCIPerrorMessage(
"LP Error: fixing lower bound for variable %d to infinity.\n", ind[
i]);
694 SCIPerrorMessage(
"LP Error: fixing upper bound for variable %d to -infinity.\n", ind[
i]);
722 for (
int i = 0;
i < nrows; ++
i)
740 assert( 0 <= row && row < lpi->linear_program->num_constraints().value() );
741 assert( 0 <= col && col < lpi->linear_program->num_variables().value() );
793 for (
int i = 0;
i < ncols; ++
i)
830 for (
int j = 0; j < nnonz; ++j)
840 else if ( scaleval < 0.0 )
845 else if ( scaleval < 0.0 )
848 if ( scaleval > 0.0 )
894 for (
int j = 0; j < nnonz; ++j)
909 else if ( scaleval < 0.0 )
914 else if ( scaleval < 0.0 )
917 if ( scaleval > 0.0 )
1031 assert(lastcol < lpi->linear_program->num_variables());
1032 assert(firstcol <= lastcol + 1);
1034 const DenseRow& tmplb = lpi->
linear_program->variable_lower_bounds();
1035 const DenseRow& tmpub = lpi->
linear_program->variable_upper_bounds();
1045 for( ColIndex col(firstcol); col <= ColIndex(lastcol); ++col, ++index )
1048 lb[index] = tmplb[col];
1050 ub[index] = tmpub[col];
1052 beg[index] = *nnonz;
1053 const SparseColumn& column = lpi->
linear_program->GetSparseColumn(col);
1054 for(
const SparseColumn::Entry& entry : column )
1057 ind[*nnonz] = row.value();
1058 val[*nnonz] = entry.coefficient();
1066 for( ColIndex col(firstcol); col <= ColIndex(lastcol); ++col, ++index )
1069 lb[index] = tmplb[col];
1071 ub[index] = tmpub[col];
1099 assert(lastrow < lpi->linear_program->num_constraints());
1100 assert(firstrow <= lastrow + 1);
1102 const DenseColumn& tmplhs = lpi->
linear_program->constraint_lower_bounds();
1103 const DenseColumn& tmprhs = lpi->
linear_program->constraint_upper_bounds();
1111 const SparseMatrix& matrixtrans = lpi->
linear_program->GetTransposeSparseMatrix();
1118 lhs[index] = tmplhs[row];
1120 rhs[index] = tmprhs[row];
1122 beg[index] = *nnonz;
1123 const SparseColumn& column = matrixtrans.column(ColIndex(row.value()));
1124 for(
const SparseColumn::Entry& entry : column )
1126 const RowIndex rowidx = entry.row();
1127 ind[*nnonz] = rowidx.value();
1128 val[*nnonz] = entry.coefficient();
1139 lhs[index] = tmplhs[row];
1141 rhs[index] = tmprhs[row];
1155 int namestoragesize,
1161 assert(colnames !=
NULL || namestoragesize == 0);
1162 assert(namestorage !=
NULL || namestoragesize == 0);
1163 assert(namestoragesize >= 0);
1166 assert(lastcol < lpi->linear_program->num_variables());
1167 assert(firstcol <= lastcol + 1);
1181 int namestoragesize,
1187 assert(rownames !=
NULL || namestoragesize == 0);
1188 assert(namestorage !=
NULL || namestoragesize == 0);
1189 assert(namestoragesize >= 0);
1192 assert(lastrow < lpi->linear_program->num_constraints());
1193 assert(firstrow <= lastrow + 1);
1212 assert(lastcol < lpi->linear_program->num_variables());
1213 assert(firstcol <= lastcol + 1);
1215 SCIPdebugMessage(
"getting objective values %d to %d\n", firstcol, lastcol);
1218 for( ColIndex col(firstcol); col <= ColIndex(lastcol); ++col )
1220 vals[index] = lpi->
linear_program->objective_coefficients()[col];
1239 assert(lastcol < lpi->linear_program->num_variables());
1240 assert(firstcol <= lastcol + 1);
1245 for( ColIndex col(firstcol); col <= ColIndex(lastcol); ++col )
1271 assert(lastrow < lpi->linear_program->num_constraints());
1272 assert(firstrow <= lastrow + 1);
1280 lhss[index] = lpi->
linear_program->constraint_lower_bounds()[row];
1283 rhss[index] = lpi->
linear_program->constraint_upper_bounds()[row];
1304 const SparseMatrix& matrix = lpi->
linear_program->GetSparseMatrix();
1305 *val = matrix.LookUpValue(
RowIndex(row), ColIndex(col));
1332 lpi->
scaled_lp->AddSlackVariablesWhereNecessary(
false);
1352#if UNSCALEDFEAS_CHECK == 1
1355 DenseRow unscaledsol(num_cols);
1356 for (ColIndex col = ColIndex(0); col < num_cols; ++col)
1357 unscaledsol[col] = lpi->
scaler->UnscaleVariableValue(col, lpi->
solver->GetVariableValue(col));
1360 const double feastol = lpi->
parameters->primal_feasibility_tolerance();
1361 return lpi->
linear_program->SolutionIsLPFeasible(unscaledsol, feastol);
1363#elif UNSCALEDFEAS_CHECK == 2
1364 const double feastol = lpi->
parameters->primal_feasibility_tolerance();
1368 for (ColIndex col = ColIndex(0); col < num_cols; ++col)
1370 const Fractional val = lpi->
scaler->UnscaleVariableValue(col, lpi->
solver->GetVariableValue(col));
1371 const Fractional lb = lpi->
linear_program->variable_lower_bounds()[col];
1372 if ( val < lb - feastol )
1374 const Fractional ub = lpi->
linear_program->variable_upper_bounds()[col];
1375 if ( val > ub + feastol )
1381 for (
RowIndex row(0); row < num_rows; ++row)
1383 const Fractional val = lpi->
scaler->UnscaleConstraintActivity(row, lpi->
solver->GetConstraintActivity(row));
1384 const Fractional lhs = lpi->
linear_program->constraint_lower_bounds()[row];
1385 if ( val < lhs - feastol )
1387 const Fractional rhs = lpi->
linear_program->constraint_upper_bounds()[row];
1388 if ( val > rhs + feastol )
1401 std::unique_ptr<TimeLimit>& time_limit
1415 lpi->
solver->ClearStateForNextSolve();
1427 SCIPdebugMessage(
"status=%s obj=%f iter=%ld.\n", GetProblemStatusString(lpi->
solver->GetProblemStatus()).c_str(),
1428 lpi->
solver->GetObjectiveValue(), lpi->
solver->GetNumberOfIterations());
1430 const ProblemStatus status = lpi->
solver->GetProblemStatus();
1431 if ( (status == ProblemStatus::PRIMAL_FEASIBLE || status == ProblemStatus::OPTIMAL) && lpi->
parameters->use_scaling() )
1435 SCIPdebugMessage(
"Solution not feasible w.r.t. absolute tolerance %g -> reoptimize.\n", lpi->
parameters->primal_feasibility_tolerance());
1445 SCIPdebugMessage(
"Solution still not feasible after turning off scaling.\n");
1466 std::unique_ptr<TimeLimit> time_limit = TimeLimit::FromParameters(*lpi->
parameters);
1469 lpi->
parameters->set_use_dual_simplex(
false);
1484 std::unique_ptr<TimeLimit> time_limit = TimeLimit::FromParameters(*lpi->
parameters);
1538 ProblemStatus status
1541 return status == ProblemStatus::OPTIMAL || status == ProblemStatus::DUAL_FEASIBLE || status == ProblemStatus::DUAL_UNBOUNDED;
1567 SCIPdebugMessage(
"calling strongbranching on variable %d (%d iterations)\n", col_index, itlim);
1570 const ColIndex col(col_index);
1571 const Fractional lb = lpi->
scaled_lp->variable_lower_bounds()[col];
1572 const Fractional ub = lpi->
scaled_lp->variable_upper_bounds()[col];
1573 const double value = psol * lpi->
scaler->VariableScalingFactor(col);
1578 int num_iterations = 0;
1581 const Fractional
eps = lpi->
parameters->primal_feasibility_tolerance();
1583 std::unique_ptr<TimeLimit> time_limit = TimeLimit::FromParameters(*lpi->
parameters);
1586 const Fractional newub =
EPSCEIL(value - 1.0,
eps);
1587 if ( newub >= lb - 0.5 )
1589 lpi->
scaled_lp->SetVariableBounds(col, lb, newub);
1593 num_iterations += (int) lpi->
solver->GetNumberOfIterations();
1594 *down = lpi->
solver->GetObjectiveValue();
1597 SCIPdebugMessage(
"down: itlim=%d col=%d [%f,%f] obj=%f status=%d iter=%ld.\n", itlim, col_index, lb,
EPSCEIL(value - 1.0,
eps),
1598 lpi->
solver->GetObjectiveValue(), (
int) lpi->
solver->GetProblemStatus(), lpi->
solver->GetNumberOfIterations());
1610 *down = lpi->
parameters->objective_lower_limit();
1612 *down = lpi->
parameters->objective_upper_limit();
1617 const Fractional newlb =
EPSFLOOR(value + 1.0,
eps);
1618 if ( newlb <= ub + 0.5 )
1620 lpi->
scaled_lp->SetVariableBounds(col, newlb, ub);
1624 num_iterations += (int) lpi->
solver->GetNumberOfIterations();
1625 *up = lpi->
solver->GetObjectiveValue();
1629 lpi->
solver->GetObjectiveValue(), (
int) lpi->
solver->GetProblemStatus(), lpi->
solver->GetNumberOfIterations());
1641 *up = lpi->
parameters->objective_lower_limit();
1643 *up = lpi->
parameters->objective_upper_limit();
1648 lpi->
scaled_lp->SetVariableBounds(col, lb, ub);
1650 *iter = num_iterations;
1677 SCIPdebugMessage(
"calling strongbranching on fractional variable %d (%d iterations)\n", col, itlim);
1814 const ProblemStatus status = lpi->
solver->GetProblemStatus();
1815 *primalfeasible = (status == ProblemStatus::OPTIMAL || status == ProblemStatus::PRIMAL_FEASIBLE);
1816 *dualfeasible = (status == ProblemStatus::OPTIMAL || status == ProblemStatus::DUAL_FEASIBLE);
1818 SCIPdebugMessage(
"SCIPlpiGetSolFeasibility primal:%u dual:%u\n", *primalfeasible, *dualfeasible);
1833 return lpi->
solver->GetProblemStatus() == ProblemStatus::PRIMAL_UNBOUNDED;
1846 return lpi->
solver->GetProblemStatus() == ProblemStatus::PRIMAL_UNBOUNDED;
1857 return lpi->
solver->GetProblemStatus() == ProblemStatus::PRIMAL_UNBOUNDED;
1868 const ProblemStatus status = lpi->
solver->GetProblemStatus();
1870 return status == ProblemStatus::DUAL_UNBOUNDED || status == ProblemStatus::PRIMAL_INFEASIBLE;
1881 const ProblemStatus status = lpi->
solver->GetProblemStatus();
1883 return status == ProblemStatus::PRIMAL_FEASIBLE || status == ProblemStatus::OPTIMAL;
1896 const ProblemStatus status = lpi->
solver->GetProblemStatus();
1898 return status == ProblemStatus::DUAL_UNBOUNDED;
1911 const ProblemStatus status = lpi->
solver->GetProblemStatus();
1913 return status == ProblemStatus::DUAL_UNBOUNDED;
1924 const ProblemStatus status = lpi->
solver->GetProblemStatus();
1925 return status == ProblemStatus::DUAL_UNBOUNDED;
1936 const ProblemStatus status = lpi->
solver->GetProblemStatus();
1937 return status == ProblemStatus::PRIMAL_UNBOUNDED || status == ProblemStatus::DUAL_INFEASIBLE;
1948 const ProblemStatus status = lpi->
solver->GetProblemStatus();
1950 return status == ProblemStatus::DUAL_FEASIBLE || status == ProblemStatus::OPTIMAL;
1961 return lpi->
solver->GetProblemStatus() == ProblemStatus::OPTIMAL;
1981 const ProblemStatus status = lpi->
solver->GetProblemStatus();
1982 if ( (status == ProblemStatus::PRIMAL_FEASIBLE || status == ProblemStatus::DUAL_FEASIBLE) &&
1989 if ( status == ProblemStatus::ABNORMAL || status == ProblemStatus::INVALID_PROBLEM || status == ProblemStatus::IMPRECISE )
2019 return lpi->
solver->objective_limit_reached();
2031 int maxiter = (int) lpi->
parameters->max_number_of_iterations();
2032 return maxiter >= 0 && lpi->
niterations >= maxiter;
2054 return static_cast<int>(lpi->
solver->GetProblemStatus());
2109 for (ColIndex col(0); col < num_cols; ++col)
2111 int i = col.value();
2116 if ( redcost !=
NULL )
2117 redcost[
i] = lpi->
scaler->UnscaleReducedCost(col, lpi->
solver->GetReducedCost(col));
2121 for (
RowIndex row(0); row < num_rows; ++row)
2123 int j = row.value();
2125 if ( dualsol !=
NULL )
2126 dualsol[j] = lpi->
scaler->UnscaleDualValue(row, lpi->
solver->GetDualValue(row));
2128 if ( activity !=
NULL )
2129 activity[j] = lpi->
scaler->UnscaleConstraintActivity(row, lpi->
solver->GetConstraintActivity(row));
2148 const DenseRow& primal_ray = lpi->
solver->GetPrimalRay();
2149 for (ColIndex col(0); col < num_cols; ++col)
2150 ray[col.value()] = lpi->
scaler->UnscaleVariableValue(col, primal_ray[col]);
2168 const DenseColumn& dual_ray = lpi->
solver->GetDualRay();
2169 for (
RowIndex row(0); row < num_rows; ++row)
2170 dualfarkas[row.value()] = -lpi->
scaler->UnscaleDualValue(row, dual_ray[row]);
2205 SCIPdebugMessage(
"Requesting solution quality: quality %d\n", qualityindicator);
2207 switch ( qualityindicator )
2210 *quality = lpi->
solver->GetBasisFactorization().ComputeInfinityNormConditionNumber();
2214 *quality = lpi->
solver->GetBasisFactorization().ComputeInfinityNormConditionNumberUpperBound();
2240 VariableStatus status,
2246 case VariableStatus::BASIC:
2248 case VariableStatus::AT_UPPER_BOUND:
2250 case VariableStatus::AT_LOWER_BOUND:
2252 case VariableStatus::FREE:
2254 case VariableStatus::FIXED_VALUE:
2265 ConstraintStatus status,
2271 case ConstraintStatus::BASIC:
2273 case ConstraintStatus::AT_UPPER_BOUND:
2275 case ConstraintStatus::AT_LOWER_BOUND:
2277 case ConstraintStatus::FREE:
2279 case ConstraintStatus::FIXED_VALUE:
2296 return VariableStatus::BASIC;
2298 return VariableStatus::AT_UPPER_BOUND;
2300 return VariableStatus::AT_LOWER_BOUND;
2302 return VariableStatus::FREE;
2321 return VariableStatus::BASIC;
2323 return VariableStatus::AT_LOWER_BOUND;
2325 return VariableStatus::AT_UPPER_BOUND;
2327 return VariableStatus::FREE;
2343 assert( lpi->
solver->GetProblemStatus() == ProblemStatus::OPTIMAL );
2345 if ( cstat !=
NULL )
2348 for (ColIndex col(0); col < num_cols; ++col)
2350 int i = col.value();
2355 if ( rstat !=
NULL )
2358 for (
RowIndex row(0); row < num_rows; ++row)
2360 int i = row.value();
2388 state.statuses.reserve(ColIndex(num_cols.value() + num_rows.value()));
2390 for (ColIndex col(0); col < num_cols; ++col)
2393 for (
RowIndex row(0); row < num_rows; ++row)
2396 lpi->
solver->LoadStateForNextSolve(state);
2417 for (
RowIndex row(0); row < num_rows; ++row)
2419 const ColIndex col = lpi->
solver->GetBasis(row);
2421 bind[row.value()] = col.value();
2424 assert( col < num_cols.value() + num_rows.value() );
2425 bind[row.value()] = -1 - (col - num_cols).value();
2453 lpi->
solver->GetBasisFactorization().LeftSolveForUnitRow(ColIndex(
r), lpi->
tmp_row);
2456 const ColIndex size = lpi->
tmp_row->values.size();
2460 if ( ninds !=
NULL && inds !=
NULL )
2465 if ( ! lpi->
tmp_row->non_zeros.empty() )
2467 ScatteredRowIterator end = lpi->
tmp_row->end();
2468 for (ScatteredRowIterator iter = lpi->
tmp_row->begin(); iter != end; ++iter)
2470 int idx = (*iter).column().value();
2471 assert( 0 <= idx && idx < lpi->linear_program->num_constraints() );
2472 coef[idx] = (*iter).coefficient();
2473 inds[(*ninds)++] = idx;
2479 const Fractional
eps = lpi->
parameters->primal_feasibility_tolerance();
2480 for (ColIndex col(0); col < size; ++col)
2483 if ( fabs(val) >=
eps )
2485 coef[col.value()] = val;
2486 inds[(*ninds)++] = col.value();
2494 for (ColIndex col(0); col < size; ++col)
2495 coef[col.value()] = (*lpi->
tmp_row)[col];
2497 if ( ninds !=
NULL )
2529 const ColIndex col(
c);
2533 if ( ninds !=
NULL && inds !=
NULL )
2535 const Fractional
eps = lpi->
parameters->primal_feasibility_tolerance();
2538 for (
int row = 0; row < num_rows; ++row)
2540 lpi->
solver->GetBasisFactorization().LeftSolveForUnitRow(ColIndex(row), lpi->
tmp_row);
2544 if ( fabs(val) >=
eps )
2547 inds[(*ninds)++] = row;
2554 for (
int row = 0; row < num_rows; ++row)
2556 lpi->
solver->GetBasisFactorization().LeftSolveForUnitRow(ColIndex(row), lpi->
tmp_row);
2558 coef[row] = (*lpi->
tmp_row)[col];
2561 if ( ninds !=
NULL )
2590 lpi->
solver->GetBasisFactorization().LeftSolveForUnitRow(ColIndex(
r), lpi->
tmp_row);
2596 if ( ninds !=
NULL && inds !=
NULL )
2598 const Fractional
eps = lpi->
parameters->primal_feasibility_tolerance();
2601 for (ColIndex col(0); col < num_cols; ++col)
2604 if ( fabs(val) >=
eps )
2606 coef[col.value()] = val;
2607 inds[(*ninds)++] = col.value();
2614 for (ColIndex col(0); col < num_cols; ++col)
2615 coef[col.value()] = operations_research::glop::ScalarProduct(lpi->
tmp_row->values, lpi->
linear_program->GetSparseColumn(col));
2617 if ( ninds !=
NULL )
2644 lpi->
solver->GetBasisFactorization().RightSolveForProblemColumn(ColIndex(
c), lpi->
tmp_column);
2650 if ( ninds !=
NULL && inds !=
NULL )
2657 ScatteredColumnIterator end = lpi->
tmp_column->end();
2658 for (ScatteredColumnIterator iter = lpi->
tmp_column->begin(); iter != end; ++iter)
2660 int idx = (*iter).row().value();
2661 assert( 0 <= idx && idx < num_rows );
2662 coef[idx] = (*iter).coefficient();
2663 inds[(*ninds)++] = idx;
2669 const Fractional
eps = lpi->
parameters->primal_feasibility_tolerance();
2670 for (
RowIndex row(0); row < num_rows; ++row)
2673 if ( fabs(val) >
eps )
2675 coef[row.value()] = val;
2676 inds[(*ninds)++] = row.value();
2684 for (
RowIndex row(0); row < num_rows; ++row)
2687 if ( ninds !=
NULL )
2741 lpi->
solver->LoadStateForNextSolve(*lpistate);
2754 lpi->
solver->ClearStateForNextSolve();
2785 return lpistate !=
NULL;
2909 SCIPdebugMessage(
"SCIPlpiGetIntpar: SCIP_LPPAR_FROMSCRATCH = %d.\n", *ival);
2916 *ival = (int) lpi->
parameters->max_number_of_iterations();
2920 *ival = lpi->
parameters->use_preprocessing();
2921 SCIPdebugMessage(
"SCIPlpiGetIntpar: SCIP_LPPAR_PRESOLVING = %d.\n", *ival);
2942 *ival = (int) lpi->
parameters->random_seed();
2943 SCIPdebugMessage(
"SCIPlpiGetIntpar: SCIP_LPPAR_RANDOMSEED = %d.\n", *ival);
2965 SCIPdebugMessage(
"SCIPlpiSetIntpar: SCIP_LPPAR_FROMSCRATCH -> %d.\n", ival);
2972 (void) google::SetVLOGLevel(
"*", google::GLOG_INFO);
2977 (void) google::SetVLOGLevel(
"*", google::GLOG_ERROR);
2983 lpi->
parameters->set_max_number_of_iterations(ival);
2986 SCIPdebugMessage(
"SCIPlpiSetIntpar: SCIP_LPPAR_PRESOLVING -> %d.\n", ival);
2987 lpi->
parameters->set_use_preprocessing(ival);
2999 lpi->
parameters->set_feasibility_rule(operations_research::glop::GlopParameters_PricingRule_STEEPEST_EDGE);
3003 lpi->
parameters->set_feasibility_rule(operations_research::glop::GlopParameters_PricingRule_DANTZIG);
3006 lpi->
parameters->set_feasibility_rule(operations_research::glop::GlopParameters_PricingRule_DEVEX);
3029 assert( 0 <= ival && ival <= 2 );
3032 absl::SetFlag(&FLAGS_time_limit_use_usertime,
true);
3034 absl::SetFlag(&FLAGS_time_limit_use_usertime,
false);
3037 SCIPdebugMessage(
"SCIPlpiSetIntpar: SCIP_LPPAR_RANDOMSEED -> %d.\n", ival);
3062 *dval = lpi->
parameters->primal_feasibility_tolerance();
3066 *dval = lpi->
parameters->dual_feasibility_tolerance();
3067 SCIPdebugMessage(
"SCIPlpiGetRealpar: SCIP_LPPAR_DUALFEASTOL = %g.\n", *dval);
3071 *dval = lpi->
parameters->objective_lower_limit();
3073 *dval = lpi->
parameters->objective_upper_limit();
3077 if ( absl::GetFlag(FLAGS_time_limit_use_usertime) )
3078 *dval = lpi->
parameters->max_time_in_seconds();
3080 *dval = lpi->
parameters->max_deterministic_time();
3086#ifdef SCIP_DISABLED_CODE
3089 *dval = lpi->
parameters->markowitz_singularity_threshold();
3090 SCIPdebugMessage(
"SCIPlpiGetRealpar: SCIP_LPPAR_MARKOWITZ = %f.\n", *dval);
3114 lpi->
parameters->set_primal_feasibility_tolerance(dval);
3117 SCIPdebugMessage(
"SCIPlpiSetRealpar: SCIP_LPPAR_DUALFEASTOL -> %g.\n", dval);
3118 lpi->
parameters->set_dual_feasibility_tolerance(dval);
3123 lpi->
parameters->set_objective_lower_limit(dval);
3125 lpi->
parameters->set_objective_upper_limit(dval);
3129 if ( absl::GetFlag(FLAGS_time_limit_use_usertime) )
3130 lpi->
parameters->set_max_time_in_seconds(dval);
3132 lpi->
parameters->set_max_deterministic_time(dval);
3138#ifdef SCIP_DISABLED_CODE
3141 SCIPdebugMessage(
"SCIPlpiSetRealpar: SCIP_LPPAR_MARKOWITZ -> %f.\n", dval);
3142 lpi->
parameters->set_markowitz_singularity_threshold(dval);
3182 return std::numeric_limits<SCIP_Real>::infinity();
3193 return val == std::numeric_limits<SCIP_Real>::infinity();
3218 const std::string filespec(fname);
3220 if ( ! ReadFileToProto(filespec, &proto) )
3243 const std::string filespec(fname);
3244 if ( ! WriteProtoToFile(filespec, proto, operations_research::ProtoWriteFormat::kProtoText,
true) )
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiChgObjsen(SCIP_LPI *lpi, SCIP_OBJSEN objsen)
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiClearState(SCIP_LPI *lpi)
SCIP_Bool SCIPlpiExistsDualRay(SCIP_LPI *lpi)
SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
SCIP_RETCODE SCIPlpiReadState(SCIP_LPI *lpi, const char *fname)
SCIP_RETCODE SCIPlpiAddRows(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, char **rownames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
SCIP_Bool SCIPlpiIsDualInfeasible(SCIP_LPI *lpi)
static void deleteRowsAndUpdateCurrentBasis(SCIP_LPI *lpi, const DenseBooleanColumn &rows_to_delete)
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
SCIP_RETCODE SCIPlpiStrongbranchFrac(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
SCIP_RETCODE SCIPlpiGetNNonz(SCIP_LPI *lpi, int *nnonz)
SCIP_Bool SCIPlpiHasPrimalSolve(void)
SCIP_RETCODE SCIPlpiStrongbranchInt(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
SCIP_Bool SCIPlpiHasBarrierSolve(void)
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
SCIP_RETCODE SCIPlpiScaleCol(SCIP_LPI *lpi, int col, SCIP_Real scaleval)
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
SCIP_RETCODE SCIPlpiWriteState(SCIP_LPI *lpi, const char *fname)
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
SCIP_RETCODE SCIPlpiStrongbranchesFrac(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
SCIP_RETCODE SCIPlpiGetCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real *val)
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiReadLP(SCIP_LPI *lpi, const char *fname)
SCIP_RETCODE SCIPlpiGetRealSolQuality(SCIP_LPI *lpi, SCIP_LPSOLQUALITY qualityindicator, SCIP_Real *quality)
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
const char * SCIPlpiGetSolverName(void)
SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, const int *cstat, const int *rstat)
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
SCIP_RETCODE SCIPlpiGetCols(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lb, SCIP_Real *ub, int *nnonz, int *beg, int *ind, SCIP_Real *val)
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
SCIP_RETCODE SCIPlpiGetColNames(SCIP_LPI *lpi, int firstcol, int lastcol, char **colnames, char *namestorage, int namestoragesize, int *storageleft)
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
SCIP_RETCODE SCIPlpiGetRows(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhs, SCIP_Real *rhs, int *nnonz, int *beg, int *ind, SCIP_Real *val)
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
const char * SCIPlpiGetSolverDesc(void)
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiGetRowNames(SCIP_LPI *lpi, int firstrow, int lastrow, char **rownames, char *namestorage, int namestoragesize, int *storageleft)
SCIP_Bool SCIPlpiHasDualSolve(void)
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
SCIP_RETCODE SCIPlpiStrongbranchesInt(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiAddCols(SCIP_LPI *lpi, int ncols, const SCIP_Real *obj, const SCIP_Real *lb, const SCIP_Real *ub, char **colnames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiLoadColLP(SCIP_LPI *lpi, SCIP_OBJSEN objsen, int ncols, const SCIP_Real *obj, const SCIP_Real *lb, const SCIP_Real *ub, char **colnames, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, char **rownames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
SCIP_Bool SCIPlpiIsDualUnbounded(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
void * SCIPlpiGetSolverPointer(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
SCIP_RETCODE SCIPlpiGetObjsen(SCIP_LPI *lpi, SCIP_OBJSEN *objsen)
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
SCIP_RETCODE SCIPlpiInterrupt(SCIP_LPI *lpi, SCIP_Bool interrupt)
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
SCIP_RETCODE SCIPlpiScaleRow(SCIP_LPI *lpi, int row, SCIP_Real scaleval)
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
SCIP_RETCODE SCIPlpiChgCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real newval)
assert(minobj< SCIPgetCutoffbound(scip))
interface methods for specific LP solvers
static SCIP_BASESTAT ConvertGlopConstraintStatus(ConstraintStatus status, Fractional dual)
static SCIP_BASESTAT ConvertGlopVariableStatus(VariableStatus status, Fractional rc)
static VariableStatus ConvertSCIPConstraintStatusToSlackStatus(int status)
static bool IsDualBoundValid(ProblemStatus status)
static SCIP_RETCODE strongbranch(SCIP_LPI *lpi, int col_index, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
static SCIP_RETCODE SolveInternal(SCIP_LPI *lpi, bool recursive, std::unique_ptr< TimeLimit > &time_limit)
static void updateScaledLP(SCIP_LPI *lpi)
static bool checkUnscaledPrimalFeasibility(SCIP_LPI *lpi)
static VariableStatus ConvertSCIPVariableStatus(int status)
#define BMSfreeMemory(ptr)
#define BMSallocMemoryArray(ptr, num)
#define BMSfreeMemoryArray(ptr)
struct BMS_BlkMem BMS_BLKMEM
#define BMSallocMemory(ptr)
public methods for message output
ScatteredColumn * tmp_column
operations_research::glop::LinearProgram * linear_program
operations_research::glop::LinearProgram * scaled_lp
operations_research::glop::GlopParameters * parameters
bool lp_time_limit_was_reached
bool lp_modified_since_last_solve
operations_research::glop::LpScalingHelper * scaler
operations_research::glop::RevisedSimplex * solver
@ SCIP_PRICING_STEEPQSTART
@ SCIP_PRICING_LPIDEFAULT
enum SCIP_Pricing SCIP_PRICING
enum SCIP_LPParam SCIP_LPPARAM
@ SCIP_LPSOLQUALITY_EXACTCONDITION
@ SCIP_LPSOLQUALITY_ESTIMCONDITION
struct SCIP_LPiState SCIP_LPISTATE
struct SCIP_LPiNorms SCIP_LPINORMS
@ SCIP_LPPAR_CONDITIONLIMIT
enum SCIP_LPSolQuality SCIP_LPSOLQUALITY
enum SCIP_ObjSen SCIP_OBJSEN
enum SCIP_BaseStat SCIP_BASESTAT
struct SCIP_Messagehdlr SCIP_MESSAGEHDLR
enum SCIP_Retcode SCIP_RETCODE