2014-07-09 10:01:48 +00:00
|
|
|
// Copyright 2010-2014 Google
|
2011-03-31 08:39:26 +00:00
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
|
//
|
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
//
|
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
|
// limitations under the License.
|
2014-07-09 15:18:27 +00:00
|
|
|
|
2011-03-31 08:39:26 +00:00
|
|
|
//
|
|
|
|
|
// (Laurent Perron).
|
|
|
|
|
//
|
2011-11-03 10:27:53 +00:00
|
|
|
// A C++ wrapper that provides a simple and unified interface to
|
|
|
|
|
// several linear programming and mixed integer programming solvers:
|
|
|
|
|
// GLPK, CLP, CBC and SCIP. The wrapper can also be used in Java and
|
|
|
|
|
// Python via SWIG.
|
2011-05-20 14:01:28 +00:00
|
|
|
//
|
|
|
|
|
//
|
2011-03-31 08:39:26 +00:00
|
|
|
// -----------------------------------
|
2011-11-03 10:27:53 +00:00
|
|
|
// What is Linear Programming?
|
2011-03-31 08:39:26 +00:00
|
|
|
//
|
|
|
|
|
// In mathematics, linear programming (LP) is a technique for optimization of
|
|
|
|
|
// a linear objective function, subject to linear equality and linear
|
|
|
|
|
// inequality constraints. Informally, linear programming determines the way
|
|
|
|
|
// to achieve the best outcome (such as maximum profit or lowest cost) in a
|
|
|
|
|
// given mathematical model and given some list of requirements represented
|
2011-10-07 14:28:52 +00:00
|
|
|
// as linear equations.
|
|
|
|
|
//
|
|
|
|
|
// The most widely used technique for solving a linear program is the Simplex
|
|
|
|
|
// algorithm, devised by George Dantzig in 1947. It performs very well on
|
|
|
|
|
// most instances, for which its running time is polynomial. A lot of effort
|
|
|
|
|
// has been put into improving the algorithm and its implementation. As a
|
|
|
|
|
// byproduct, it has however been shown that one can always construct
|
|
|
|
|
// problems that take exponential time for the Simplex algorithm to solve.
|
|
|
|
|
// Research has thus focused on trying to find a polynomial algorithm for
|
|
|
|
|
// linear programming, or to prove that linear programming is indeed
|
|
|
|
|
// polynomial.
|
|
|
|
|
//
|
|
|
|
|
// Leonid Khachiyan first exhibited in 1979 a weakly polynomial algorithm for
|
|
|
|
|
// linear programming. "Weakly polynomial" means that the running time of the
|
|
|
|
|
// algorithm is in O(P(n) * 2^p) where P(n) is a polynomial of the size of the
|
|
|
|
|
// problem, and p is the precision of computations expressed in number of
|
|
|
|
|
// bits. With a fixed-precision, floating-point-based implementation, a weakly
|
|
|
|
|
// polynomial algorithm will thus run in polynomial time. No implementation
|
|
|
|
|
// of Khachiyan's algorithm has proved efficient, but a larger breakthrough in
|
|
|
|
|
// the field came in 1984 when Narendra Karmarkar introduced a new interior
|
|
|
|
|
// point method for solving linear programming problems. Interior point
|
|
|
|
|
// algorithms have proved efficient on very large linear programs.
|
2011-03-31 08:39:26 +00:00
|
|
|
//
|
2011-11-03 10:27:53 +00:00
|
|
|
// Check Wikipedia for more detail:
|
|
|
|
|
// http://en.wikipedia.org/wiki/Linear_programming
|
|
|
|
|
//
|
2011-03-31 08:39:26 +00:00
|
|
|
// -----------------------------------
|
2011-11-03 10:27:53 +00:00
|
|
|
// Example of a Linear Program
|
|
|
|
|
//
|
|
|
|
|
// maximize:
|
|
|
|
|
// 3x + y
|
|
|
|
|
// subject to:
|
|
|
|
|
// 1.5 x + 2 y <= 12
|
|
|
|
|
// 0 <= x <= 3
|
|
|
|
|
// 0 <= y <= 5
|
2011-03-31 08:39:26 +00:00
|
|
|
//
|
2011-11-03 10:27:53 +00:00
|
|
|
// A linear program has:
|
|
|
|
|
// 1) a linear objective function
|
|
|
|
|
// 2) linear constraints that can be equalities or inequalities
|
|
|
|
|
// 3) bounds on variables that can be positive, negative, finite or
|
|
|
|
|
// infinite.
|
2011-03-31 08:39:26 +00:00
|
|
|
//
|
|
|
|
|
// -----------------------------------
|
2011-11-03 10:27:53 +00:00
|
|
|
// What is Mixed Integer Programming?
|
2011-03-31 08:39:26 +00:00
|
|
|
//
|
2011-11-03 10:27:53 +00:00
|
|
|
// Here, the constraints and the objective are still linear but
|
|
|
|
|
// there are additional integrality requirements for variables. If
|
|
|
|
|
// all variables are required to take integer values, then the
|
|
|
|
|
// problem is called an integer program (IP). In most cases, only
|
|
|
|
|
// some variables are required to be integer and the rest of the
|
|
|
|
|
// variables are continuous: this is called a mixed integer program
|
|
|
|
|
// (MIP). IPs and MIPs are generally NP-hard.
|
|
|
|
|
//
|
|
|
|
|
// Integer variables can be used to model discrete decisions (build a
|
|
|
|
|
// datacenter in city A or city B), logical relationships (only
|
|
|
|
|
// place machines in datacenter A if we have decided to build
|
|
|
|
|
// datacenter A) and approximate non-linear functions with piecewise
|
|
|
|
|
// linear functions (for example, the cost of machines as a function
|
|
|
|
|
// of how many machines are bought, or the latency of a server as a
|
|
|
|
|
// function of its load).
|
2011-03-31 08:39:26 +00:00
|
|
|
//
|
|
|
|
|
// -----------------------------------
|
2011-11-03 10:27:53 +00:00
|
|
|
// How to use the wrapper?
|
2011-03-31 08:39:26 +00:00
|
|
|
//
|
2011-11-03 10:27:53 +00:00
|
|
|
// The user builds the model and solves it through the MPSolver class,
|
|
|
|
|
// then queries the solution through the MPSolver, MPVariable and
|
|
|
|
|
// MPConstraint classes. To be able to query a solution, you need the
|
|
|
|
|
// following:
|
|
|
|
|
// - A solution exists: MPSolver::Solve has been called and a solution
|
|
|
|
|
// has been found.
|
|
|
|
|
// - The model has not been modified since the last time
|
|
|
|
|
// MPSolver::Solve was called. Otherwise, the solution obtained
|
|
|
|
|
// before the model modification may not longer be feasible or
|
|
|
|
|
// optimal.
|
2011-03-31 08:39:26 +00:00
|
|
|
//
|
2011-11-03 10:27:53 +00:00
|
|
|
// @see ../examples/linear_programming.cc for a simple LP example
|
|
|
|
|
// @see ../examples/integer_programming.cc for a simple MIP example
|
2011-03-31 08:39:26 +00:00
|
|
|
//
|
2011-11-03 10:27:53 +00:00
|
|
|
// All methods cannot be called successfully in all cases. For
|
|
|
|
|
// example: you cannot query a solution when no solution exists, you
|
|
|
|
|
// cannot query a reduced cost value (which makes sense only on
|
|
|
|
|
// continuous problems) on a discrete problem. When a method is
|
|
|
|
|
// called in an unsuitable context, it aborts with a
|
|
|
|
|
// LOG(FATAL).
|
|
|
|
|
// TODO(user): handle failures gracefully.
|
2011-03-31 08:39:26 +00:00
|
|
|
//
|
|
|
|
|
// -----------------------------------
|
2011-11-03 10:27:53 +00:00
|
|
|
// For developers: How the does the wrapper work?
|
|
|
|
|
//
|
|
|
|
|
// MPSolver stores a representation of the model (variables,
|
|
|
|
|
// constraints and objective) in its own data structures and a
|
|
|
|
|
// pointer to a MPSolverInterface that wraps the underlying solver
|
|
|
|
|
// (CBC, CLP, GLPK or SCIP) that does the actual work. The
|
|
|
|
|
// underlying solver also keeps a representation of the model in its
|
|
|
|
|
// own data structures. The model representations in MPSolver and in
|
|
|
|
|
// the underlying solver are kept in sync by the 'extraction'
|
|
|
|
|
// mechanism: synchronously for some changes and asynchronously
|
|
|
|
|
// (when MPSolver::Solve is called) for others. Synchronicity
|
|
|
|
|
// depends on the modification applied and on the underlying solver.
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2011-05-11 16:05:15 +00:00
|
|
|
#ifndef OR_TOOLS_LINEAR_SOLVER_LINEAR_SOLVER_H_
|
|
|
|
|
#define OR_TOOLS_LINEAR_SOLVER_LINEAR_SOLVER_H_
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2015-02-04 12:04:59 +00:00
|
|
|
#include <functional>
|
2011-05-17 20:38:55 +00:00
|
|
|
#include "base/hash.h"
|
|
|
|
|
#include "base/hash.h"
|
2011-03-31 08:39:26 +00:00
|
|
|
#include <limits>
|
2013-01-10 17:00:09 +00:00
|
|
|
#include <map>
|
2015-08-13 16:00:54 +02:00
|
|
|
#include <memory>
|
2011-03-31 08:39:26 +00:00
|
|
|
#include <string>
|
2015-06-17 16:29:25 +02:00
|
|
|
#include <utility>
|
2011-03-31 08:39:26 +00:00
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
#include "base/integral_types.h"
|
|
|
|
|
#include "base/logging.h"
|
|
|
|
|
#include "base/timer.h"
|
2015-06-17 16:29:25 +02:00
|
|
|
#include "glop/parameters.pb.h"
|
|
|
|
|
#include "linear_solver/linear_solver.pb.h"
|
2011-05-17 20:38:55 +00:00
|
|
|
|
2013-01-10 17:00:09 +00:00
|
|
|
|
2011-03-31 08:39:26 +00:00
|
|
|
namespace operations_research {
|
|
|
|
|
|
2011-09-05 13:42:36 +00:00
|
|
|
class MPConstraint;
|
|
|
|
|
class MPObjective;
|
2011-03-31 08:39:26 +00:00
|
|
|
class MPSolverInterface;
|
|
|
|
|
class MPSolverParameters;
|
2011-09-05 13:42:36 +00:00
|
|
|
class MPVariable;
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// This mathematical programming (MP) solver class is the main class
|
|
|
|
|
// though which users build and solve problems.
|
2011-03-31 08:39:26 +00:00
|
|
|
class MPSolver {
|
|
|
|
|
public:
|
2011-11-03 10:27:53 +00:00
|
|
|
// The type of problems (LP or MIP) that will be solved and the
|
|
|
|
|
// underlying solver (GLPK, CLP, CBC or SCIP) that will solve them.
|
2013-01-10 17:00:09 +00:00
|
|
|
// This must remain consistent with MPModelRequest::OptimizationProblemType
|
|
|
|
|
// (take particular care of the open-source version).
|
2011-03-31 08:39:26 +00:00
|
|
|
enum OptimizationProblemType {
|
2013-01-10 17:00:09 +00:00
|
|
|
// Linear programming problems.
|
|
|
|
|
#ifdef USE_CLP
|
|
|
|
|
CLP_LINEAR_PROGRAMMING = 0, // Recommended default value.
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef USE_GLPK
|
|
|
|
|
GLPK_LINEAR_PROGRAMMING = 1,
|
|
|
|
|
#endif
|
2014-07-08 09:27:02 +00:00
|
|
|
#ifdef USE_GLOP
|
|
|
|
|
GLOP_LINEAR_PROGRAMMING = 2,
|
|
|
|
|
#endif
|
2013-01-10 17:00:09 +00:00
|
|
|
#if defined(USE_SLM)
|
|
|
|
|
SULUM_LINEAR_PROGRAMMING = 8,
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef USE_GUROBI
|
|
|
|
|
GUROBI_LINEAR_PROGRAMMING = 6,
|
|
|
|
|
#endif
|
2014-10-15 21:31:03 +00:00
|
|
|
#ifdef USE_CPLEX
|
|
|
|
|
CPLEX_LINEAR_PROGRAMMING = 10,
|
|
|
|
|
#endif
|
2013-01-10 17:00:09 +00:00
|
|
|
|
|
|
|
|
// Integer programming problems.
|
|
|
|
|
#ifdef USE_SCIP
|
|
|
|
|
SCIP_MIXED_INTEGER_PROGRAMMING = 3, // Recommended default value.
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef USE_GLPK
|
|
|
|
|
GLPK_MIXED_INTEGER_PROGRAMMING = 4,
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef USE_CBC
|
|
|
|
|
CBC_MIXED_INTEGER_PROGRAMMING = 5,
|
|
|
|
|
#endif
|
|
|
|
|
#if defined(USE_SLM)
|
|
|
|
|
SULUM_MIXED_INTEGER_PROGRAMMING = 9,
|
|
|
|
|
#endif
|
|
|
|
|
#if defined(USE_GUROBI)
|
|
|
|
|
GUROBI_MIXED_INTEGER_PROGRAMMING = 7,
|
|
|
|
|
#endif
|
2014-10-15 21:31:03 +00:00
|
|
|
#if defined(USE_CPLEX)
|
|
|
|
|
CPLEX_MIXED_INTEGER_PROGRAMMING = 11,
|
|
|
|
|
#endif
|
2015-08-13 16:00:54 +02:00
|
|
|
#if defined(USE_BOP)
|
2015-01-16 17:02:32 +00:00
|
|
|
BOP_INTEGER_PROGRAMMING = 12,
|
|
|
|
|
#endif
|
2011-03-31 08:39:26 +00:00
|
|
|
};
|
|
|
|
|
|
2013-12-16 10:24:42 +00:00
|
|
|
MPSolver(const std::string& name, OptimizationProblemType problem_type);
|
2011-03-31 08:39:26 +00:00
|
|
|
virtual ~MPSolver();
|
|
|
|
|
|
2014-07-08 09:27:02 +00:00
|
|
|
// Whether the given problem type is supported (this will depend on the
|
|
|
|
|
// targets that you linked).
|
|
|
|
|
static bool SupportsProblemType(OptimizationProblemType problem_type);
|
2013-10-10 15:23:20 +00:00
|
|
|
|
2013-12-16 10:24:42 +00:00
|
|
|
std::string Name() const {
|
2011-11-16 21:37:43 +00:00
|
|
|
return name_; // Set at construction.
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-10 17:00:09 +00:00
|
|
|
virtual OptimizationProblemType ProblemType() const {
|
|
|
|
|
return problem_type_; // Set at construction.
|
|
|
|
|
}
|
|
|
|
|
|
2011-12-16 21:02:01 +00:00
|
|
|
// Clears the objective (including the optimization direction), all
|
|
|
|
|
// variables and constraints. All the other properties of the MPSolver
|
|
|
|
|
// (like the time limit) are kept untouched.
|
|
|
|
|
void Clear();
|
|
|
|
|
|
2011-03-31 08:39:26 +00:00
|
|
|
// ----- Variables ------
|
|
|
|
|
// Returns the number of variables.
|
|
|
|
|
int NumVariables() const { return variables_.size(); }
|
2013-01-10 17:00:09 +00:00
|
|
|
// Returns the array of variables handled by the MPSolver.
|
|
|
|
|
// (They are listed in the order in which they were created.)
|
|
|
|
|
const std::vector<MPVariable*>& variables() const { return variables_; }
|
2011-12-16 21:02:01 +00:00
|
|
|
// Look up a variable by name, and return NULL if it does not exist.
|
2013-12-16 10:24:42 +00:00
|
|
|
MPVariable* LookupVariableOrNull(const std::string& var_name) const;
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Creates a variable with the given bounds, integrality requirement
|
|
|
|
|
// and name. Bounds can be finite or +/- MPSolver::infinity().
|
2011-12-16 21:02:01 +00:00
|
|
|
// The MPSolver owns the variable (i.e. the returned pointer is borrowed).
|
|
|
|
|
// Variable names must be unique (it may crash otherwise). Empty variable
|
|
|
|
|
// names are allowed, an automated variable name will then be assigned.
|
2013-12-16 10:24:42 +00:00
|
|
|
MPVariable* MakeVar(double lb, double ub, bool integer, const std::string& name);
|
2011-11-03 10:27:53 +00:00
|
|
|
// Creates a continuous variable.
|
2013-12-16 10:24:42 +00:00
|
|
|
MPVariable* MakeNumVar(double lb, double ub, const std::string& name);
|
2011-11-03 10:27:53 +00:00
|
|
|
// Creates an integer variable.
|
2013-12-16 10:24:42 +00:00
|
|
|
MPVariable* MakeIntVar(double lb, double ub, const std::string& name);
|
2011-11-03 10:27:53 +00:00
|
|
|
// Creates a boolean variable.
|
2013-12-16 10:24:42 +00:00
|
|
|
MPVariable* MakeBoolVar(const std::string& name);
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Creates an array of variables. All variables created have the
|
2013-01-10 17:00:09 +00:00
|
|
|
// same bounds and integrality requirement. If nb <= 0, no variables are
|
|
|
|
|
// created, the function crashes in non-opt mode.
|
2011-11-03 10:27:53 +00:00
|
|
|
// @param name the prefix of the variable names. Variables are named
|
|
|
|
|
// name0, name1, ...
|
2014-01-08 12:01:58 +00:00
|
|
|
void MakeVarArray(int nb, double lb, double ub, bool integer,
|
|
|
|
|
const std::string& name_prefix, std::vector<MPVariable*>* vars);
|
2011-11-03 10:27:53 +00:00
|
|
|
// Creates an array of continuous variables.
|
2014-01-08 12:01:58 +00:00
|
|
|
void MakeNumVarArray(int nb, double lb, double ub, const std::string& name,
|
2011-05-17 20:38:55 +00:00
|
|
|
std::vector<MPVariable*>* vars);
|
2011-11-03 10:27:53 +00:00
|
|
|
// Creates an array of integer variables.
|
2014-01-08 12:01:58 +00:00
|
|
|
void MakeIntVarArray(int nb, double lb, double ub, const std::string& name,
|
2011-05-17 20:38:55 +00:00
|
|
|
std::vector<MPVariable*>* vars);
|
2011-11-03 10:27:53 +00:00
|
|
|
// Creates an array of boolean variables.
|
2014-01-08 12:01:58 +00:00
|
|
|
void MakeBoolVarArray(int nb, const std::string& name, std::vector<MPVariable*>* vars);
|
2011-03-31 08:39:26 +00:00
|
|
|
|
|
|
|
|
// ----- Constraints -----
|
|
|
|
|
// Returns the number of constraints.
|
|
|
|
|
int NumConstraints() const { return constraints_.size(); }
|
2013-01-10 17:00:09 +00:00
|
|
|
// Returns the array of constraints handled by the MPSolver.
|
|
|
|
|
// (They are listed in the order in which they were created.)
|
|
|
|
|
const std::vector<MPConstraint*>& constraints() const { return constraints_; }
|
2011-12-16 21:02:01 +00:00
|
|
|
// Look up a constraint by name, and return NULL if it does not exist.
|
2013-12-16 10:24:42 +00:00
|
|
|
MPConstraint* LookupConstraintOrNull(const std::string& constraint_name) const;
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Creates a linear constraint with given bounds. Bounds can be
|
|
|
|
|
// finite or +/- MPSolver::infinity(). The MPSolver class assumes
|
|
|
|
|
// ownership of the constraint.
|
|
|
|
|
// @return a pointer to the newly created constraint.
|
2011-03-31 08:39:26 +00:00
|
|
|
MPConstraint* MakeRowConstraint(double lb, double ub);
|
2011-11-03 10:27:53 +00:00
|
|
|
// Creates a constraint with -infinity and +infinity bounds.
|
2011-03-31 08:39:26 +00:00
|
|
|
MPConstraint* MakeRowConstraint();
|
2011-11-03 10:27:53 +00:00
|
|
|
// Creates a named constraint with given bounds.
|
2013-12-16 10:24:42 +00:00
|
|
|
MPConstraint* MakeRowConstraint(double lb, double ub, const std::string& name);
|
2011-11-03 10:27:53 +00:00
|
|
|
// Creates a named constraint with -infinity and +infinity bounds.
|
2013-12-16 10:24:42 +00:00
|
|
|
MPConstraint* MakeRowConstraint(const std::string& name);
|
2011-03-31 08:39:26 +00:00
|
|
|
|
|
|
|
|
// ----- Objective -----
|
2011-12-16 21:02:01 +00:00
|
|
|
// Note that the objective is owned by the solver, and is initialized to
|
|
|
|
|
// its default value (see the MPObjective class below) at construction.
|
2015-04-29 19:01:13 +02:00
|
|
|
const MPObjective& Objective() const { return *objective_; }
|
2011-12-16 21:02:01 +00:00
|
|
|
MPObjective* MutableObjective() { return objective_.get(); }
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2011-12-16 21:02:01 +00:00
|
|
|
// ----- Solve -----
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2015-04-29 19:01:13 +02:00
|
|
|
// The status of solving the problem. The straightforward translation to
|
|
|
|
|
// homonymous enum values of MPSolutionResponse::Status
|
2015-06-16 10:08:44 +02:00
|
|
|
// (see ./linear_solver.proto) is guaranteed by ./enum_consistency_test.cc,
|
2013-01-10 17:00:09 +00:00
|
|
|
// you may rely on it.
|
2011-12-16 21:02:01 +00:00
|
|
|
// TODO(user): Figure out once and for all what the status of
|
|
|
|
|
// underlying solvers exactly mean, especially for feasible and
|
|
|
|
|
// infeasible.
|
|
|
|
|
enum ResultStatus {
|
2015-06-17 16:29:25 +02:00
|
|
|
OPTIMAL, // optimal.
|
|
|
|
|
FEASIBLE, // feasible, or stopped by limit.
|
|
|
|
|
INFEASIBLE, // proven infeasible.
|
|
|
|
|
UNBOUNDED, // proven unbounded.
|
|
|
|
|
ABNORMAL, // abnormal, i.e., error of some kind.
|
|
|
|
|
MODEL_INVALID, // the model is trivially invalid (NaN coefficients, etc).
|
|
|
|
|
NOT_SOLVED = 6 // not been solved yet.
|
2011-12-16 21:02:01 +00:00
|
|
|
};
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Solves the problem using default parameter values.
|
2011-03-31 08:39:26 +00:00
|
|
|
ResultStatus Solve();
|
2011-11-03 10:27:53 +00:00
|
|
|
// Solves the problem using the specified parameter values.
|
2011-03-31 08:39:26 +00:00
|
|
|
ResultStatus Solve(const MPSolverParameters& param);
|
|
|
|
|
|
2015-06-18 14:26:12 +02:00
|
|
|
// Advanced usage: compute the "activities" of all constraints, which are the
|
|
|
|
|
// sums of their linear terms. The activities are returned in the same order
|
|
|
|
|
// as constraints(), which is the order in which constraints were added; but
|
|
|
|
|
// you can also use MPConstraint::index() to get a constraint's index.
|
|
|
|
|
std::vector<double> ComputeConstraintActivities() const;
|
|
|
|
|
|
2012-09-11 17:23:15 +00:00
|
|
|
// Advanced usage:
|
2013-06-11 14:49:45 +00:00
|
|
|
// Verifies the *correctness* of the solution: all variables must be within
|
|
|
|
|
// their domains, all constraints must be satisfied, and the reported
|
2012-09-11 17:23:15 +00:00
|
|
|
// objective value must be accurate.
|
|
|
|
|
// Usage:
|
|
|
|
|
// - This can only be called after Solve() was called.
|
2013-06-11 14:49:45 +00:00
|
|
|
// - "tolerance" is interpreted as an absolute error threshold.
|
|
|
|
|
// - For the objective value only, if the absolute error is too large,
|
|
|
|
|
// the tolerance is interpreted as a relative error threshold instead.
|
2012-09-11 17:23:15 +00:00
|
|
|
// - If "log_errors" is true, every single violation will be logged.
|
2013-06-11 14:49:45 +00:00
|
|
|
// - If "tolerance" is negative, it will be set to infinity().
|
2012-09-11 17:23:15 +00:00
|
|
|
//
|
|
|
|
|
// Most users should just set the --verify_solution flag and not bother
|
|
|
|
|
// using this method directly.
|
2013-06-11 14:49:45 +00:00
|
|
|
bool VerifySolution(double tolerance, bool log_errors) const;
|
2012-09-11 17:23:15 +00:00
|
|
|
|
2013-06-11 14:49:45 +00:00
|
|
|
// Advanced usage: resets extracted model to solve from scratch. This won't
|
|
|
|
|
// reset the parameters that were set with
|
|
|
|
|
// SetSolverSpecificParametersAsString() or set_time_limit() or even clear the
|
|
|
|
|
// linear program. It will just make sure that next Solve() will be as if
|
|
|
|
|
// everything was reconstructed from scratch.
|
2011-03-31 08:39:26 +00:00
|
|
|
void Reset();
|
|
|
|
|
|
2014-12-16 11:35:09 +00:00
|
|
|
// Interrupts the Solve() execution to terminate processing early if possible.
|
|
|
|
|
// If the underlying interface supports interruption; it does that and returns
|
|
|
|
|
// true regardless of whether there's an ongoing Solve() or not. The Solve()
|
|
|
|
|
// call may still linger for a while depending on the conditions. If
|
|
|
|
|
// interruption is not supported; returns false and does nothing.
|
|
|
|
|
bool InterruptSolve();
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// ----- Methods using protocol buffers -----
|
|
|
|
|
|
2015-06-17 16:29:25 +02:00
|
|
|
// Loads model from protocol buffer. Returns MPSOLVER_MODEL_IS_VALID if the
|
|
|
|
|
// model is valid, and another status otherwise (currently only
|
|
|
|
|
// MPSOLVER_MODEL_INVALID and MPSOLVER_INFEASIBLE). If the model isn't
|
|
|
|
|
// valid, populate "error_message".
|
|
|
|
|
MPSolverResponseStatus LoadModelFromProto(const MPModelProto& input_model,
|
|
|
|
|
std::string* error_message);
|
2015-10-23 13:45:43 +02:00
|
|
|
// The same as above, except that the loading keeps original variable and
|
|
|
|
|
// constraint names. Caller should make sure that all variable names and
|
|
|
|
|
// constraint names are unique, respectively.
|
|
|
|
|
MPSolverResponseStatus LoadModelFromProtoWithUniqueNamesOrDie(
|
|
|
|
|
const MPModelProto& input_model, std::string* error_message);
|
2011-11-03 10:27:53 +00:00
|
|
|
|
|
|
|
|
// Encodes the current solution in a solution response protocol buffer.
|
|
|
|
|
// Only nonzero variable values are stored in order to reduce the
|
|
|
|
|
// size of the MPSolutionResponse protocol buffer.
|
2015-06-16 10:08:44 +02:00
|
|
|
void FillSolutionResponseProto(MPSolutionResponse* response) const;
|
2011-11-03 10:27:53 +00:00
|
|
|
|
|
|
|
|
// Solves the model encoded by a MPModelRequest protocol buffer and
|
|
|
|
|
// fills the solution encoded as a MPSolutionResponse.
|
2011-11-19 01:58:48 +00:00
|
|
|
// Note(user): This creates a temporary MPSolver and destroys it at the
|
|
|
|
|
// end. If you want to keep the MPSolver alive (for debugging, or for
|
|
|
|
|
// incremental solving), you should write another version of this function
|
|
|
|
|
// that creates the MPSolver object on the heap and returns it.
|
2015-06-16 10:08:44 +02:00
|
|
|
//
|
|
|
|
|
// TODO(user): populate an error message in the response.
|
|
|
|
|
static void SolveWithProto(const MPModelRequest& model_request,
|
|
|
|
|
MPSolutionResponse* response);
|
2013-06-11 14:49:45 +00:00
|
|
|
|
2013-01-10 17:00:09 +00:00
|
|
|
// Exports model to protocol buffer.
|
2015-06-16 10:08:44 +02:00
|
|
|
void ExportModelToProto(MPModelProto* output_model) const;
|
2013-10-10 15:23:20 +00:00
|
|
|
|
2013-12-10 15:50:16 +00:00
|
|
|
// Load a solution encoded in a protocol buffer onto this solver for easy
|
|
|
|
|
// access via the MPSolver interface.
|
2013-01-10 17:00:09 +00:00
|
|
|
//
|
|
|
|
|
// IMPORTANT: This may only be used in conjunction with ExportModel(),
|
|
|
|
|
// following this example:
|
|
|
|
|
// MPSolver my_solver;
|
|
|
|
|
// ... add variables and constraints ...
|
2015-06-16 10:08:44 +02:00
|
|
|
// MPModelProto model_proto;
|
|
|
|
|
// my_solver.ExportModelToProto(&model_proto);
|
|
|
|
|
// MPSolutionResponse solver_response;
|
2013-01-10 17:00:09 +00:00
|
|
|
// // This can be replaced by a stubby call to the linear solver server.
|
2013-12-10 15:50:16 +00:00
|
|
|
// MPSolver::SolveWithProto(model_proto, &solver_response);
|
2013-01-10 17:00:09 +00:00
|
|
|
// if (solver_response.result_status() == MPSolutionResponse::OPTIMAL) {
|
2015-06-16 10:08:44 +02:00
|
|
|
// CHECK(my_solver.LoadSolutionFromProto(solver_response));
|
2013-01-10 17:00:09 +00:00
|
|
|
// ... inspect the solution using the usual API: solution_value(), etc...
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// This allows users of the pythonic API to conveniently communicate with
|
|
|
|
|
// a linear solver stubby server, via the MPSolver object as a proxy.
|
|
|
|
|
// See /.linear_solver_server_integration_test.py.
|
|
|
|
|
//
|
|
|
|
|
// The response must be in OPTIMAL or FEASIBLE status.
|
|
|
|
|
// Returns false if a problem arised (typically, if it wasn't used like
|
|
|
|
|
// it should be):
|
|
|
|
|
// - loading a solution whose variables don't correspond to the solver's
|
|
|
|
|
// current variables
|
|
|
|
|
// - loading a solution with a status other than OPTIMAL / FEASIBLE.
|
|
|
|
|
// Note: the variable and objective values aren't checked. You can use
|
|
|
|
|
// VerifySolution() for that.
|
2015-06-16 10:08:44 +02:00
|
|
|
bool LoadSolutionFromProto(const MPSolutionResponse& response);
|
2013-01-10 17:00:09 +00:00
|
|
|
|
2013-06-11 14:49:45 +00:00
|
|
|
// ----- Export model to files or strings -----
|
2015-06-17 16:29:25 +02:00
|
|
|
#ifndef ANDROID_JNI
|
2013-06-11 14:49:45 +00:00
|
|
|
// Shortcuts to the homonymous MPModelProtoExporter methods, via
|
2015-06-16 10:08:44 +02:00
|
|
|
// exporting to a MPModelProto with ExportModelToProto() (see above).
|
2013-12-16 10:24:42 +00:00
|
|
|
bool ExportModelAsLpFormat(bool obfuscated, std::string* model_str);
|
2014-01-08 12:01:58 +00:00
|
|
|
bool ExportModelAsMpsFormat(bool fixed_format, bool obfuscated,
|
|
|
|
|
std::string* model_str);
|
2015-06-17 16:29:25 +02:00
|
|
|
#endif
|
2011-11-03 10:27:53 +00:00
|
|
|
// ----- Misc -----
|
|
|
|
|
|
2013-10-10 15:23:20 +00:00
|
|
|
// Advanced usage: pass solver specific parameters in text format. The format
|
|
|
|
|
// is solver-specific and is the same as the corresponding solver
|
|
|
|
|
// configuration file format. Returns true if the operation was successful.
|
|
|
|
|
//
|
|
|
|
|
// TODO(user): Currently SCIP will always return true even if the format is
|
|
|
|
|
// wrong (you can check the log if you suspect an issue there). This seems to
|
|
|
|
|
// be a bug in SCIP though.
|
2013-12-16 10:24:42 +00:00
|
|
|
bool SetSolverSpecificParametersAsString(const std::string& parameters);
|
2013-10-10 15:23:20 +00:00
|
|
|
|
2011-12-16 21:02:01 +00:00
|
|
|
// Advanced usage: possible basis status values for a variable and the
|
|
|
|
|
// slack variable of a linear constraint.
|
|
|
|
|
enum BasisStatus {
|
|
|
|
|
FREE = 0,
|
|
|
|
|
AT_LOWER_BOUND,
|
|
|
|
|
AT_UPPER_BOUND,
|
|
|
|
|
FIXED_VALUE,
|
|
|
|
|
BASIC
|
|
|
|
|
};
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Infinity. You can use -MPSolver::infinity() for negative infinity.
|
2014-01-08 12:01:58 +00:00
|
|
|
static double infinity() { return std::numeric_limits<double>::infinity(); }
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2015-06-17 16:29:25 +02:00
|
|
|
// Controls (or queries) the amount of output produced by the underlying
|
|
|
|
|
// solver. The output can surface to LOGs, or to stdout or stderr, depending
|
|
|
|
|
// on the implementation. The amount of output will greatly vary with each
|
|
|
|
|
// implementation and each problem.
|
|
|
|
|
//
|
|
|
|
|
// Output is suppressed by default.
|
|
|
|
|
bool OutputIsEnabled() const;
|
2011-05-30 14:25:30 +00:00
|
|
|
void EnableOutput();
|
2015-06-17 16:29:25 +02:00
|
|
|
void SuppressOutput();
|
2011-05-30 14:25:30 +00:00
|
|
|
|
2013-01-10 17:00:09 +00:00
|
|
|
void set_time_limit(int64 time_limit_milliseconds) {
|
|
|
|
|
DCHECK_GE(time_limit_milliseconds, 0);
|
|
|
|
|
time_limit_ = time_limit_milliseconds;
|
2011-03-31 08:39:26 +00:00
|
|
|
}
|
|
|
|
|
|
2013-01-10 17:00:09 +00:00
|
|
|
// In milliseconds.
|
2014-01-08 12:01:58 +00:00
|
|
|
int64 time_limit() const { return time_limit_; }
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2013-10-10 15:23:20 +00:00
|
|
|
// In seconds. Note that this returns a double.
|
|
|
|
|
double time_limit_in_secs() const {
|
|
|
|
|
// static_cast<double> avoids a warning with -Wreal-conversion. This
|
|
|
|
|
// helps catching bugs with unwanted conversions from double to ints.
|
|
|
|
|
return static_cast<double>(time_limit_) / 1000.0;
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Returns wall_time() in milliseconds since the creation of the solver.
|
2014-01-08 12:01:58 +00:00
|
|
|
int64 wall_time() const { return timer_.GetInMs(); }
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Returns the number of simplex iterations.
|
2011-03-31 08:39:26 +00:00
|
|
|
int64 iterations() const;
|
2011-11-03 10:27:53 +00:00
|
|
|
|
|
|
|
|
// Returns the number of branch-and-bound nodes. Only available for
|
|
|
|
|
// discrete problems.
|
2011-03-31 08:39:26 +00:00
|
|
|
int64 nodes() const;
|
|
|
|
|
|
2013-12-16 10:24:42 +00:00
|
|
|
// Returns a std::string describing the underlying solver and its version.
|
|
|
|
|
std::string SolverVersion() const;
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Advanced usage: returns the underlying solver so that the user
|
|
|
|
|
// can use solver-specific features or features that are not exposed
|
|
|
|
|
// in the simple API of MPSolver. This method is for advanced users,
|
|
|
|
|
// use at your own risk! In particular, if you modify the model or
|
|
|
|
|
// the solution by accessing the underlying solver directly, then
|
|
|
|
|
// the underlying solver will be out of sync with the information
|
|
|
|
|
// kept in the wrapper (MPSolver, MPVariable, MPConstraint,
|
2011-08-11 18:44:23 +00:00
|
|
|
// MPObjective). You need to cast the void* returned back to its
|
|
|
|
|
// original type that depends on the interface (CBC:
|
|
|
|
|
// OsiClpSolverInterface*, CLP: ClpSimplex*, GLPK: glp_prob*, SCIP:
|
|
|
|
|
// SCIP*).
|
|
|
|
|
void* underlying_solver();
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Advanced usage: computes the exact condition number of the
|
|
|
|
|
// current scaled basis: L1norm(B) * L1norm(inverse(B)), where B is
|
|
|
|
|
// the scaled basis.
|
2011-09-19 08:58:03 +00:00
|
|
|
// This method requires that a basis exists: it should be called
|
|
|
|
|
// after Solve. It is only available for continuous problems. It is
|
|
|
|
|
// implemented for GLPK but not CLP because CLP does not provide the
|
|
|
|
|
// API for doing it.
|
|
|
|
|
// The condition number measures how well the constraint matrix is
|
|
|
|
|
// conditioned and can be used to predict whether numerical issues
|
|
|
|
|
// will arise during the solve: the model is declared infeasible
|
|
|
|
|
// whereas it is feasible (or vice-versa), the solution obtained is
|
|
|
|
|
// not optimal or violates some constraints, the resolution is slow
|
|
|
|
|
// because of repeated singularities.
|
|
|
|
|
// The rule of thumb to interpret the condition number kappa is:
|
|
|
|
|
// o kappa <= 1e7: virtually no chance of numerical issues
|
|
|
|
|
// o 1e7 < kappa <= 1e10: small chance of numerical issues
|
|
|
|
|
// o 1e10 < kappa <= 1e13: medium chance of numerical issues
|
|
|
|
|
// o kappa > 1e13: high chance of numerical issues
|
|
|
|
|
// The computation of the condition number depends on the quality of
|
|
|
|
|
// the LU decomposition, so it is not very accurate when the matrix
|
|
|
|
|
// is ill conditioned.
|
|
|
|
|
double ComputeExactConditionNumber() const;
|
|
|
|
|
|
2011-03-31 08:39:26 +00:00
|
|
|
friend class GLPKInterface;
|
|
|
|
|
friend class CLPInterface;
|
|
|
|
|
friend class CBCInterface;
|
2011-06-22 08:38:43 +00:00
|
|
|
friend class SCIPInterface;
|
2013-01-10 17:00:09 +00:00
|
|
|
friend class GurobiInterface;
|
2014-10-15 21:31:03 +00:00
|
|
|
friend class CplexInterface;
|
2013-04-18 13:53:08 +00:00
|
|
|
friend class SLMInterface;
|
2011-03-31 08:39:26 +00:00
|
|
|
friend class MPSolverInterface;
|
2014-07-08 09:27:02 +00:00
|
|
|
friend class GLOPInterface;
|
2015-01-16 17:02:32 +00:00
|
|
|
friend class BopInterface;
|
2015-08-13 16:00:54 +02:00
|
|
|
friend class KnapsackInterface;
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2012-09-11 17:23:15 +00:00
|
|
|
// Debugging: verify that the given MPVariable* belongs to this solver.
|
|
|
|
|
bool OwnsVariable(const MPVariable* var) const;
|
|
|
|
|
|
2011-03-31 08:39:26 +00:00
|
|
|
private:
|
2011-11-03 10:27:53 +00:00
|
|
|
// Computes the size of the constraint with the largest number of
|
2011-03-31 08:39:26 +00:00
|
|
|
// coefficients with index in [min_constraint_index,
|
|
|
|
|
// max_constraint_index)
|
|
|
|
|
int ComputeMaxConstraintSize(int min_constraint_index,
|
|
|
|
|
int max_constraint_index) const;
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Returns true if the model has constraints with lower bound > upper bound.
|
2011-06-10 20:00:52 +00:00
|
|
|
bool HasInfeasibleConstraints() const;
|
|
|
|
|
|
2011-03-31 08:39:26 +00:00
|
|
|
// The name of the linear programming problem.
|
2013-12-16 10:24:42 +00:00
|
|
|
const std::string name_;
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2013-01-10 17:00:09 +00:00
|
|
|
// The type of the linear programming problem.
|
|
|
|
|
const OptimizationProblemType problem_type_;
|
|
|
|
|
|
2011-03-31 08:39:26 +00:00
|
|
|
// The solver interface.
|
2013-12-05 09:24:58 +00:00
|
|
|
std::unique_ptr<MPSolverInterface> interface_;
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// The vector of variables in the problem.
|
2011-05-17 20:38:55 +00:00
|
|
|
std::vector<MPVariable*> variables_;
|
2011-12-16 21:02:01 +00:00
|
|
|
// A map from a variable's name to its index in variables_.
|
2013-12-16 10:24:42 +00:00
|
|
|
hash_map<std::string, int> variable_name_to_index_;
|
2015-06-18 14:08:50 +02:00
|
|
|
// Whether constraints have been extracted to the underlying interface.
|
|
|
|
|
std::vector<bool> variable_is_extracted_;
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// The vector of constraints in the problem.
|
2011-05-17 20:38:55 +00:00
|
|
|
std::vector<MPConstraint*> constraints_;
|
2011-12-16 21:02:01 +00:00
|
|
|
// A map from a constraint's name to its index in constraints_.
|
2013-12-16 10:24:42 +00:00
|
|
|
hash_map<std::string, int> constraint_name_to_index_;
|
2015-06-18 14:08:50 +02:00
|
|
|
// Whether constraints have been extracted to the underlying interface.
|
|
|
|
|
std::vector<bool> constraint_is_extracted_;
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// The linear objective function.
|
2013-12-05 09:24:58 +00:00
|
|
|
std::unique_ptr<MPObjective> objective_;
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2015-05-18 19:41:34 +02:00
|
|
|
// Initial values for all or some of the problem variables that can be
|
|
|
|
|
// exploited as a starting hint by a solver.
|
|
|
|
|
//
|
|
|
|
|
// Note(user): as of 05/05/2015, we can't use >> because of some SWIG errors.
|
|
|
|
|
std::vector<std::pair<MPVariable*, double> > solution_hint_;
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Time limit in milliseconds (0 = no limit).
|
2011-03-31 08:39:26 +00:00
|
|
|
int64 time_limit_;
|
|
|
|
|
|
|
|
|
|
WallTimer timer_;
|
|
|
|
|
|
2013-06-11 14:49:45 +00:00
|
|
|
// Permanent storage for SetSolverSpecificParametersAsString().
|
2013-12-16 10:24:42 +00:00
|
|
|
std::string solver_specific_parameter_string_;
|
2013-06-11 14:49:45 +00:00
|
|
|
|
|
|
|
|
|
2015-10-23 13:45:43 +02:00
|
|
|
MPSolverResponseStatus LoadModelFromProtoInternal(
|
|
|
|
|
const MPModelProto& input_model, bool clear_names, std::string* error_message);
|
|
|
|
|
|
2011-03-31 08:39:26 +00:00
|
|
|
DISALLOW_COPY_AND_ASSIGN(MPSolver);
|
|
|
|
|
};
|
|
|
|
|
|
2015-06-17 16:29:25 +02:00
|
|
|
#ifndef ANDROID_JNI
|
|
|
|
|
inline std::ostream& operator<<(std::ostream& os,
|
|
|
|
|
MPSolver::ResultStatus status) {
|
|
|
|
|
return os << MPSolverResponseStatus_Name(
|
|
|
|
|
static_cast<MPSolverResponseStatus>(status));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2013-06-11 14:49:45 +00:00
|
|
|
// The data structure used to store the coefficients of the contraints and of
|
|
|
|
|
// the objective. Also define a type to facilitate iteration over them with:
|
|
|
|
|
// for (CoeffEntry entry : coefficients_) { ... }
|
2013-10-17 08:58:26 +00:00
|
|
|
class CoeffMap : public hash_map<const MPVariable*, double> {
|
|
|
|
|
public:
|
|
|
|
|
explicit CoeffMap(int num_buckets)
|
2014-01-08 12:01:58 +00:00
|
|
|
#if !defined(_MSC_VER) // Visual C++ doesn't support this constructor
|
|
|
|
|
: hash_map<const MPVariable*, double>(num_buckets)
|
|
|
|
|
#endif // _MSC_VER
|
|
|
|
|
{
|
|
|
|
|
}
|
2013-10-17 08:58:26 +00:00
|
|
|
};
|
|
|
|
|
|
2013-06-11 14:49:45 +00:00
|
|
|
typedef std::pair<const MPVariable*, double> CoeffEntry;
|
|
|
|
|
|
2011-12-16 21:02:01 +00:00
|
|
|
// A class to express a linear objective.
|
|
|
|
|
class MPObjective {
|
|
|
|
|
public:
|
|
|
|
|
// Clears the offset, all variables and coefficients, and the optimization
|
|
|
|
|
// direction.
|
|
|
|
|
void Clear();
|
|
|
|
|
|
2013-01-10 17:00:09 +00:00
|
|
|
// Sets the coefficient of the variable in the objective. If the variable
|
|
|
|
|
// does not belong to the solver, the function just returns, or crashes in
|
|
|
|
|
// non-opt mode.
|
2011-12-16 21:02:01 +00:00
|
|
|
void SetCoefficient(const MPVariable* const var, double coeff);
|
|
|
|
|
// Gets the coefficient of a given variable in the objective (which
|
|
|
|
|
// is 0 if the variable does not appear in the objective).
|
|
|
|
|
double GetCoefficient(const MPVariable* const var) const;
|
|
|
|
|
|
|
|
|
|
// Sets the constant term in the objective.
|
|
|
|
|
void SetOffset(double value);
|
|
|
|
|
// Gets the constant term in the objective.
|
|
|
|
|
double offset() const { return offset_; }
|
|
|
|
|
|
|
|
|
|
// Adds a constant term to the objective.
|
2013-01-10 17:00:09 +00:00
|
|
|
// Note: please use the less ambiguous SetOffset() if possible!
|
2011-12-16 21:02:01 +00:00
|
|
|
// TODO(user): remove this.
|
|
|
|
|
void AddOffset(double value) { SetOffset(offset() + value); }
|
|
|
|
|
|
|
|
|
|
// Sets the optimization direction (maximize: true or minimize: false).
|
|
|
|
|
void SetOptimizationDirection(bool maximize);
|
|
|
|
|
// Sets the optimization direction to minimize.
|
|
|
|
|
void SetMinimization() { SetOptimizationDirection(false); }
|
|
|
|
|
// Sets the optimization direction to maximize.
|
|
|
|
|
void SetMaximization() { SetOptimizationDirection(true); }
|
|
|
|
|
// Is the optimization direction set to maximize?
|
|
|
|
|
bool maximization() const;
|
|
|
|
|
// Is the optimization direction set to minimize?
|
|
|
|
|
bool minimization() const;
|
|
|
|
|
|
|
|
|
|
// Returns the objective value of the best solution found so far. It
|
|
|
|
|
// is the optimal objective value if the problem has been solved to
|
|
|
|
|
// optimality.
|
2013-10-10 15:23:20 +00:00
|
|
|
//
|
|
|
|
|
// Note: the objective value may be slightly different than what you
|
|
|
|
|
// could compute yourself using MPVariable::solution_value();
|
|
|
|
|
// please use the --verify_solution flag to gain confidence about the
|
|
|
|
|
// numerical stability of your solution.
|
2011-12-16 21:02:01 +00:00
|
|
|
double Value() const;
|
|
|
|
|
|
|
|
|
|
// Returns the best objective bound. In case of minimization, it is
|
|
|
|
|
// a lower bound on the objective value of the optimal integer
|
|
|
|
|
// solution. Only available for discrete problems.
|
|
|
|
|
double BestBound() const;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
friend class MPSolver;
|
|
|
|
|
friend class MPSolverInterface;
|
|
|
|
|
friend class CBCInterface;
|
|
|
|
|
friend class CLPInterface;
|
|
|
|
|
friend class GLPKInterface;
|
|
|
|
|
friend class SCIPInterface;
|
2013-04-18 13:53:08 +00:00
|
|
|
friend class SLMInterface;
|
2013-01-10 17:00:09 +00:00
|
|
|
friend class GurobiInterface;
|
2014-10-15 21:31:03 +00:00
|
|
|
friend class CplexInterface;
|
2014-07-08 09:27:02 +00:00
|
|
|
friend class GLOPInterface;
|
2015-01-16 17:02:32 +00:00
|
|
|
friend class BopInterface;
|
2015-08-13 16:00:54 +02:00
|
|
|
friend class KnapsackInterface;
|
2011-12-16 21:02:01 +00:00
|
|
|
|
|
|
|
|
// Constructor. An objective points to a single MPSolverInterface
|
|
|
|
|
// that is specified in the constructor. An objective cannot belong
|
|
|
|
|
// to several models.
|
|
|
|
|
// At construction, an MPObjective has no terms (which is equivalent
|
|
|
|
|
// on having a coefficient of 0 for all variables), and an offset of 0.
|
|
|
|
|
explicit MPObjective(MPSolverInterface* const interface)
|
2013-06-11 14:49:45 +00:00
|
|
|
: interface_(interface), coefficients_(1), offset_(0.0) {}
|
2011-12-16 21:02:01 +00:00
|
|
|
|
|
|
|
|
MPSolverInterface* const interface_;
|
|
|
|
|
|
|
|
|
|
// Mapping var -> coefficient.
|
2013-06-11 14:49:45 +00:00
|
|
|
CoeffMap coefficients_;
|
2011-12-16 21:02:01 +00:00
|
|
|
// Constant term.
|
|
|
|
|
double offset_;
|
|
|
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(MPObjective);
|
|
|
|
|
};
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// The class for variables of a Mathematical Programming (MP) model.
|
2011-09-05 13:42:36 +00:00
|
|
|
class MPVariable {
|
|
|
|
|
public:
|
2011-11-03 10:27:53 +00:00
|
|
|
// Returns the name of the variable.
|
2013-12-16 10:24:42 +00:00
|
|
|
const std::string& name() const { return name_; }
|
2011-09-05 13:42:36 +00:00
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Sets the integrality requirement of the variable.
|
2011-09-05 13:42:36 +00:00
|
|
|
void SetInteger(bool integer);
|
2011-11-03 10:27:53 +00:00
|
|
|
// Returns the integrality requirement of the variable.
|
2011-09-05 13:42:36 +00:00
|
|
|
bool integer() const { return integer_; }
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Returns the value of the variable in the current solution.
|
2013-10-10 15:23:20 +00:00
|
|
|
// If the variable is integer, then the value will always be an integer
|
|
|
|
|
// (the underlying solver handles floating-point values only, but this
|
|
|
|
|
// function automatically rounds it to the nearest integer; see: man 3 round).
|
2011-09-05 13:42:36 +00:00
|
|
|
double solution_value() const;
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Returns the index of the variable in the MPSolver::variables_.
|
2011-09-05 13:42:36 +00:00
|
|
|
int index() const { return index_; }
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Returns the lower bound.
|
2011-09-05 13:42:36 +00:00
|
|
|
double lb() const { return lb_; }
|
2011-11-03 10:27:53 +00:00
|
|
|
// Returns the upper bound.
|
2011-09-05 13:42:36 +00:00
|
|
|
double ub() const { return ub_; }
|
2011-11-03 10:27:53 +00:00
|
|
|
// Sets the lower bound.
|
2011-09-05 13:42:36 +00:00
|
|
|
void SetLB(double lb) { SetBounds(lb, ub_); }
|
2011-11-03 10:27:53 +00:00
|
|
|
// Sets the upper bound.
|
2011-09-05 13:42:36 +00:00
|
|
|
void SetUB(double ub) { SetBounds(lb_, ub); }
|
2011-11-03 10:27:53 +00:00
|
|
|
// Sets both the lower and upper bounds.
|
2011-09-05 13:42:36 +00:00
|
|
|
void SetBounds(double lb, double ub);
|
2011-10-07 14:28:52 +00:00
|
|
|
|
2013-10-10 15:23:20 +00:00
|
|
|
// Advanced usage: unrounded solution value, i.e. it won't be rounded to the
|
|
|
|
|
// nearest integer even if the variable is integer.
|
|
|
|
|
double unrounded_solution_value() const;
|
2011-11-03 10:27:53 +00:00
|
|
|
// Advanced usage: returns the reduced cost of the variable in the
|
|
|
|
|
// current solution (only available for continuous problems).
|
|
|
|
|
double reduced_cost() const;
|
|
|
|
|
// Advanced usage: returns the basis status of the variable in the
|
|
|
|
|
// current solution (only available for continuous problems).
|
|
|
|
|
// @see MPSolver::BasisStatus.
|
|
|
|
|
MPSolver::BasisStatus basis_status() const;
|
|
|
|
|
|
2011-09-05 13:42:36 +00:00
|
|
|
protected:
|
|
|
|
|
friend class MPSolver;
|
|
|
|
|
friend class MPSolverInterface;
|
|
|
|
|
friend class CBCInterface;
|
|
|
|
|
friend class CLPInterface;
|
|
|
|
|
friend class GLPKInterface;
|
|
|
|
|
friend class SCIPInterface;
|
2013-04-18 13:53:08 +00:00
|
|
|
friend class SLMInterface;
|
2013-01-10 17:00:09 +00:00
|
|
|
friend class GurobiInterface;
|
2014-10-15 21:31:03 +00:00
|
|
|
friend class CplexInterface;
|
2014-07-08 09:27:02 +00:00
|
|
|
friend class GLOPInterface;
|
2013-10-10 15:23:20 +00:00
|
|
|
friend class MPVariableSolutionValueTest;
|
2015-01-16 17:02:32 +00:00
|
|
|
friend class BopInterface;
|
2015-08-13 16:00:54 +02:00
|
|
|
friend class KnapsackInterface;
|
2011-09-05 13:42:36 +00:00
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Constructor. A variable points to a single MPSolverInterface that
|
|
|
|
|
// is specified in the constructor. A variable cannot belong to
|
|
|
|
|
// several models.
|
2015-06-18 14:08:50 +02:00
|
|
|
MPVariable(int index, double lb, double ub, bool integer, const std::string& name,
|
2011-09-05 13:42:36 +00:00
|
|
|
MPSolverInterface* const interface)
|
2015-06-18 14:08:50 +02:00
|
|
|
: index_(index),
|
|
|
|
|
lb_(lb),
|
2014-01-08 12:01:58 +00:00
|
|
|
ub_(ub),
|
|
|
|
|
integer_(integer),
|
|
|
|
|
name_(name),
|
|
|
|
|
solution_value_(0.0),
|
|
|
|
|
reduced_cost_(0.0),
|
|
|
|
|
interface_(interface) {}
|
2011-09-05 13:42:36 +00:00
|
|
|
|
|
|
|
|
void set_solution_value(double value) { solution_value_ = value; }
|
|
|
|
|
void set_reduced_cost(double reduced_cost) { reduced_cost_ = reduced_cost; }
|
|
|
|
|
|
|
|
|
|
private:
|
2015-06-18 14:08:50 +02:00
|
|
|
const int index_;
|
2011-09-05 13:42:36 +00:00
|
|
|
double lb_;
|
|
|
|
|
double ub_;
|
|
|
|
|
bool integer_;
|
2013-12-16 10:24:42 +00:00
|
|
|
const std::string name_;
|
2011-09-05 13:42:36 +00:00
|
|
|
double solution_value_;
|
|
|
|
|
double reduced_cost_;
|
|
|
|
|
MPSolverInterface* const interface_;
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(MPVariable);
|
|
|
|
|
};
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// The class for constraints of a Mathematical Programming (MP) model.
|
|
|
|
|
// A constraint is represented as a linear equation or inequality.
|
2011-09-05 13:42:36 +00:00
|
|
|
class MPConstraint {
|
|
|
|
|
public:
|
2011-11-03 10:27:53 +00:00
|
|
|
// Returns the name of the constraint.
|
2013-12-16 10:24:42 +00:00
|
|
|
const std::string& name() const { return name_; }
|
2011-09-05 13:42:36 +00:00
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Clears all variables and coefficients. Does not clear the bounds.
|
2011-09-05 13:42:36 +00:00
|
|
|
void Clear();
|
|
|
|
|
|
2013-01-10 17:00:09 +00:00
|
|
|
// Sets the coefficient of the variable on the constraint. If the variable
|
|
|
|
|
// does not belong to the solver, the function just returns, or crashes in
|
|
|
|
|
// non-opt mode.
|
2011-12-16 21:02:01 +00:00
|
|
|
void SetCoefficient(const MPVariable* const var, double coeff);
|
|
|
|
|
// Gets the coefficient of a given variable on the constraint (which
|
|
|
|
|
// is 0 if the variable does not appear in the constraint).
|
|
|
|
|
double GetCoefficient(const MPVariable* const var) const;
|
2011-09-05 13:42:36 +00:00
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Returns the lower bound.
|
2011-09-05 13:42:36 +00:00
|
|
|
double lb() const { return lb_; }
|
2011-11-03 10:27:53 +00:00
|
|
|
// Returns the upper bound.
|
2011-09-05 13:42:36 +00:00
|
|
|
double ub() const { return ub_; }
|
2011-11-03 10:27:53 +00:00
|
|
|
// Sets the lower bound.
|
2011-09-05 13:42:36 +00:00
|
|
|
void SetLB(double lb) { SetBounds(lb, ub_); }
|
2011-11-03 10:27:53 +00:00
|
|
|
// Sets the upper bound.
|
2011-09-05 13:42:36 +00:00
|
|
|
void SetUB(double ub) { SetBounds(lb_, ub); }
|
2011-11-03 10:27:53 +00:00
|
|
|
// Sets both the lower and upper bounds.
|
2011-09-05 13:42:36 +00:00
|
|
|
void SetBounds(double lb, double ub);
|
|
|
|
|
|
2013-06-11 14:49:45 +00:00
|
|
|
// Advanced usage: returns true if the constraint is "lazy" (see below).
|
|
|
|
|
bool is_lazy() const { return is_lazy_; }
|
|
|
|
|
// Advanced usage: sets the constraint "laziness".
|
|
|
|
|
// *** This is only supported for SCIP and has no effect on other solvers. ***
|
|
|
|
|
// When 'laziness' is true, the constraint is only considered by the Linear
|
|
|
|
|
// Programming solver if its current solution violates the constraint.
|
|
|
|
|
// In this case, the constraint is definitively added to the problem.
|
|
|
|
|
// This may be useful in some MIP problems, and may have a dramatic impact
|
|
|
|
|
// on performance.
|
|
|
|
|
// For more info see: http://tinyurl.com/lazy-constraints.
|
|
|
|
|
void set_is_lazy(bool laziness) { is_lazy_ = laziness; }
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Returns the index of the constraint in the MPSolver::constraints_.
|
|
|
|
|
int index() const { return index_; }
|
|
|
|
|
|
|
|
|
|
// Advanced usage: returns the dual value of the constraint in the
|
|
|
|
|
// current solution (only available for continuous problems).
|
2011-09-05 13:42:36 +00:00
|
|
|
double dual_value() const;
|
|
|
|
|
// Advanced usage: returns the basis status of the slack variable
|
2011-11-03 10:27:53 +00:00
|
|
|
// associated with the constraint (only available for continuous
|
|
|
|
|
// problems).
|
|
|
|
|
// @see MPSolver::BasisStatus.
|
2011-09-05 13:42:36 +00:00
|
|
|
MPSolver::BasisStatus basis_status() const;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
friend class MPSolver;
|
|
|
|
|
friend class MPSolverInterface;
|
|
|
|
|
friend class CBCInterface;
|
|
|
|
|
friend class CLPInterface;
|
|
|
|
|
friend class GLPKInterface;
|
|
|
|
|
friend class SCIPInterface;
|
2013-04-18 13:53:08 +00:00
|
|
|
friend class SLMInterface;
|
2013-01-10 17:00:09 +00:00
|
|
|
friend class GurobiInterface;
|
2014-10-15 21:31:03 +00:00
|
|
|
friend class CplexInterface;
|
2014-07-08 09:27:02 +00:00
|
|
|
friend class GLOPInterface;
|
2015-01-16 17:02:32 +00:00
|
|
|
friend class BopInterface;
|
2015-08-13 16:00:54 +02:00
|
|
|
friend class KnapsackInterface;
|
2011-09-05 13:42:36 +00:00
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Constructor. A constraint points to a single MPSolverInterface
|
|
|
|
|
// that is specified in the constructor. A constraint cannot belong
|
|
|
|
|
// to several models.
|
2015-06-18 14:08:50 +02:00
|
|
|
MPConstraint(int index, double lb, double ub, const std::string& name,
|
2011-09-05 13:42:36 +00:00
|
|
|
MPSolverInterface* const interface)
|
2014-01-08 12:01:58 +00:00
|
|
|
: coefficients_(1),
|
2015-06-18 14:08:50 +02:00
|
|
|
index_(index),
|
2014-01-08 12:01:58 +00:00
|
|
|
lb_(lb),
|
|
|
|
|
ub_(ub),
|
|
|
|
|
name_(name),
|
|
|
|
|
is_lazy_(false),
|
|
|
|
|
dual_value_(0.0),
|
|
|
|
|
interface_(interface) {}
|
2011-09-05 13:42:36 +00:00
|
|
|
|
|
|
|
|
void set_dual_value(double dual_value) { dual_value_ = dual_value; }
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
// Returns true if the constraint contains variables that have not
|
|
|
|
|
// been extracted yet.
|
|
|
|
|
bool ContainsNewVariables();
|
|
|
|
|
|
|
|
|
|
// Mapping var -> coefficient.
|
2013-06-11 14:49:45 +00:00
|
|
|
CoeffMap coefficients_;
|
2011-09-05 13:42:36 +00:00
|
|
|
|
2015-06-18 14:08:50 +02:00
|
|
|
const int index_; // See index().
|
|
|
|
|
|
2011-09-05 13:42:36 +00:00
|
|
|
// The lower bound for the linear constraint.
|
|
|
|
|
double lb_;
|
2013-06-11 14:49:45 +00:00
|
|
|
|
2011-09-05 13:42:36 +00:00
|
|
|
// The upper bound for the linear constraint.
|
|
|
|
|
double ub_;
|
2013-06-11 14:49:45 +00:00
|
|
|
|
2011-09-05 13:42:36 +00:00
|
|
|
// Name.
|
2013-12-16 10:24:42 +00:00
|
|
|
const std::string name_;
|
2013-06-11 14:49:45 +00:00
|
|
|
|
|
|
|
|
// True if the constraint is "lazy", i.e. the constraint is added to the
|
|
|
|
|
// underlying Linear Programming solver only if it is violated.
|
|
|
|
|
// By default this parameter is 'false'.
|
|
|
|
|
bool is_lazy_;
|
2011-09-05 13:42:36 +00:00
|
|
|
double dual_value_;
|
|
|
|
|
MPSolverInterface* const interface_;
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(MPConstraint);
|
|
|
|
|
};
|
|
|
|
|
|
2011-03-31 08:39:26 +00:00
|
|
|
// This class stores parameter settings for LP and MIP solvers.
|
2011-09-08 00:34:13 +00:00
|
|
|
// Some parameters are marked as advanced: do not change their values
|
|
|
|
|
// unless you know what you are doing!
|
2011-11-03 10:27:53 +00:00
|
|
|
//
|
|
|
|
|
// For developers: how to add a new parameter:
|
2011-03-31 08:39:26 +00:00
|
|
|
// - Add the new Foo parameter in the DoubleParam or IntegerParam enum.
|
|
|
|
|
// - If it is a categorical param, add a FooValues enum.
|
|
|
|
|
// - Decide if the wrapper should define a default value for it: yes
|
|
|
|
|
// if it controls the properties of the solution (example:
|
|
|
|
|
// tolerances) or if it consistently improves performance, no
|
|
|
|
|
// otherwise. If yes, define kDefaultFoo.
|
|
|
|
|
// - Add a foo_value_ member and, if no default value is defined, a
|
|
|
|
|
// foo_is_default_ member.
|
|
|
|
|
// - Add code to handle Foo in Set...Param, Reset...Param,
|
|
|
|
|
// Get...Param, Reset and the constructor.
|
2011-09-08 00:34:13 +00:00
|
|
|
// - In class MPSolverInterface, add a virtual method SetFoo, add it
|
|
|
|
|
// to SetCommonParameters or SetMIPParameters, and implement it for
|
|
|
|
|
// each solver. Sometimes, parameters need to be implemented
|
|
|
|
|
// differently, see for example the INCREMENTALITY implementation.
|
2011-03-31 08:39:26 +00:00
|
|
|
// - Add a test in linear_solver_test.cc.
|
2011-11-03 10:27:53 +00:00
|
|
|
//
|
|
|
|
|
// TODO(user): store the parameter values in a protocol buffer
|
|
|
|
|
// instead. We need to figure out how to deal with the subtleties of
|
|
|
|
|
// the default values.
|
2011-03-31 08:39:26 +00:00
|
|
|
class MPSolverParameters {
|
|
|
|
|
public:
|
|
|
|
|
// Enumeration of parameters that take continuous values.
|
|
|
|
|
enum DoubleParam {
|
2011-09-08 00:34:13 +00:00
|
|
|
// Limit for relative MIP gap.
|
|
|
|
|
RELATIVE_MIP_GAP = 0,
|
2011-11-03 10:27:53 +00:00
|
|
|
// Advanced usage: tolerance for primal feasibility of basic
|
|
|
|
|
// solutions. This does not control the integer feasibility
|
2011-09-08 00:34:13 +00:00
|
|
|
// tolerance of integer solutions for MIP or the tolerance used
|
|
|
|
|
// during presolve.
|
|
|
|
|
PRIMAL_TOLERANCE = 1,
|
2011-11-03 10:27:53 +00:00
|
|
|
// Advanced usage: tolerance for dual feasibility of basic solutions.
|
2011-09-08 00:34:13 +00:00
|
|
|
DUAL_TOLERANCE = 2
|
2011-03-31 08:39:26 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Enumeration of parameters that take integer or categorical values.
|
|
|
|
|
enum IntegerParam {
|
2011-11-03 10:27:53 +00:00
|
|
|
// Advanced usage: presolve mode.
|
2011-09-08 00:34:13 +00:00
|
|
|
PRESOLVE = 1000,
|
|
|
|
|
// Algorithm to solve linear programs.
|
|
|
|
|
LP_ALGORITHM = 1001,
|
2011-11-03 10:27:53 +00:00
|
|
|
// Advanced usage: incrementality from one solve to the next.
|
2012-09-11 17:23:15 +00:00
|
|
|
INCREMENTALITY = 1002,
|
|
|
|
|
// Advanced usage: enable or disable matrix scaling.
|
|
|
|
|
SCALING = 1003
|
2011-03-31 08:39:26 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// For each categorical parameter, enumeration of possible values.
|
|
|
|
|
enum PresolveValues {
|
|
|
|
|
PRESOLVE_OFF = 0, // Presolve is off.
|
|
|
|
|
PRESOLVE_ON = 1 // Presolve is on.
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum LpAlgorithmValues {
|
2014-01-08 12:01:58 +00:00
|
|
|
DUAL = 10, // Dual simplex.
|
|
|
|
|
PRIMAL = 11, // Primal simplex.
|
|
|
|
|
BARRIER = 12 // Barrier algorithm.
|
2011-03-31 08:39:26 +00:00
|
|
|
};
|
|
|
|
|
|
2011-09-08 00:34:13 +00:00
|
|
|
enum IncrementalityValues {
|
|
|
|
|
// Start solve from scratch.
|
|
|
|
|
INCREMENTALITY_OFF = 0,
|
|
|
|
|
// Reuse results from previous solve as much as the underlying
|
|
|
|
|
// solver allows.
|
|
|
|
|
INCREMENTALITY_ON = 1
|
|
|
|
|
};
|
|
|
|
|
|
2012-09-11 17:23:15 +00:00
|
|
|
enum ScalingValues {
|
|
|
|
|
SCALING_OFF = 0, // Scaling is off.
|
|
|
|
|
SCALING_ON = 1 // Scaling is on.
|
|
|
|
|
};
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// @{
|
|
|
|
|
// Placeholder value to indicate that a parameter is set to
|
|
|
|
|
// the default value defined in the wrapper.
|
2011-03-31 08:39:26 +00:00
|
|
|
static const double kDefaultDoubleParamValue;
|
|
|
|
|
static const int kDefaultIntegerParamValue;
|
2011-11-03 10:27:53 +00:00
|
|
|
// @}
|
|
|
|
|
|
|
|
|
|
// @{
|
|
|
|
|
// Placeholder value to indicate that a parameter is unknown.
|
2011-03-31 08:39:26 +00:00
|
|
|
static const double kUnknownDoubleParamValue;
|
|
|
|
|
static const int kUnknownIntegerParamValue;
|
2011-11-03 10:27:53 +00:00
|
|
|
// @}
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// @{
|
2011-03-31 08:39:26 +00:00
|
|
|
// Default values for parameters. Only parameters that define the
|
|
|
|
|
// properties of the solution returned need to have a default value
|
|
|
|
|
// (that is the same for all solvers). You can also define a default
|
|
|
|
|
// value for performance parameters when you are confident it is a
|
|
|
|
|
// good choice (example: always turn presolve on).
|
|
|
|
|
static const double kDefaultRelativeMipGap;
|
2011-09-08 00:34:13 +00:00
|
|
|
static const double kDefaultPrimalTolerance;
|
|
|
|
|
static const double kDefaultDualTolerance;
|
2011-03-31 08:39:26 +00:00
|
|
|
static const PresolveValues kDefaultPresolve;
|
2011-09-08 00:34:13 +00:00
|
|
|
static const IncrementalityValues kDefaultIncrementality;
|
2011-11-03 10:27:53 +00:00
|
|
|
// @}
|
2011-03-31 08:39:26 +00:00
|
|
|
|
|
|
|
|
// The constructor sets all parameters to their default value.
|
|
|
|
|
MPSolverParameters();
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// @{
|
|
|
|
|
// Sets a parameter to a specific value.
|
2011-03-31 08:39:26 +00:00
|
|
|
void SetDoubleParam(MPSolverParameters::DoubleParam param, double value);
|
|
|
|
|
void SetIntegerParam(MPSolverParameters::IntegerParam param, int value);
|
2011-11-03 10:27:53 +00:00
|
|
|
// @}
|
|
|
|
|
|
|
|
|
|
// @{
|
|
|
|
|
// Sets a parameter to its default value (default value defined
|
|
|
|
|
// in MPSolverParameters if it exists, otherwise the default value
|
|
|
|
|
// defined in the underlying solver).
|
2011-03-31 08:39:26 +00:00
|
|
|
void ResetDoubleParam(MPSolverParameters::DoubleParam param);
|
|
|
|
|
void ResetIntegerParam(MPSolverParameters::IntegerParam param);
|
2011-11-03 10:27:53 +00:00
|
|
|
// Sets all parameters to their default value.
|
2011-03-31 08:39:26 +00:00
|
|
|
void Reset();
|
2011-11-03 10:27:53 +00:00
|
|
|
// @}
|
|
|
|
|
|
|
|
|
|
// @{
|
|
|
|
|
// Returns the value of a parameter.
|
2011-03-31 08:39:26 +00:00
|
|
|
double GetDoubleParam(MPSolverParameters::DoubleParam param) const;
|
|
|
|
|
int GetIntegerParam(MPSolverParameters::IntegerParam param) const;
|
2014-07-08 09:27:02 +00:00
|
|
|
// @}
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2013-01-10 17:00:09 +00:00
|
|
|
|
2011-03-31 08:39:26 +00:00
|
|
|
private:
|
2011-11-03 10:27:53 +00:00
|
|
|
// @{
|
2011-03-31 08:39:26 +00:00
|
|
|
// Parameter value for each parameter.
|
2011-11-03 10:27:53 +00:00
|
|
|
// @see DoubleParam
|
|
|
|
|
// @see IntegerParam
|
2011-03-31 08:39:26 +00:00
|
|
|
double relative_mip_gap_value_;
|
2011-09-08 00:34:13 +00:00
|
|
|
double primal_tolerance_value_;
|
|
|
|
|
double dual_tolerance_value_;
|
2011-03-31 08:39:26 +00:00
|
|
|
int presolve_value_;
|
2012-09-11 17:23:15 +00:00
|
|
|
int scaling_value_;
|
2011-03-31 08:39:26 +00:00
|
|
|
int lp_algorithm_value_;
|
2011-09-08 00:34:13 +00:00
|
|
|
int incrementality_value_;
|
2011-11-03 10:27:53 +00:00
|
|
|
// @}
|
|
|
|
|
|
2011-03-31 08:39:26 +00:00
|
|
|
// Boolean value indicating whether each parameter is set to the
|
|
|
|
|
// solver's default value. Only parameters for which the wrapper
|
|
|
|
|
// does not define a default value need such an indicator.
|
|
|
|
|
bool lp_algorithm_is_default_;
|
|
|
|
|
|
2013-01-10 17:00:09 +00:00
|
|
|
|
2011-03-31 08:39:26 +00:00
|
|
|
DISALLOW_COPY_AND_ASSIGN(MPSolverParameters);
|
|
|
|
|
};
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// This class wraps the actual mathematical programming solvers. Each
|
|
|
|
|
// solver (CLP, CBC, GLPK, SCIP) has its own interface class that
|
|
|
|
|
// derives from this abstract class. This class is never directly
|
|
|
|
|
// accessed by the user.
|
|
|
|
|
// @see cbc_interface.cc
|
|
|
|
|
// @see clp_interface.cc
|
|
|
|
|
// @see glpk_interface.cc
|
|
|
|
|
// @see scip_interface.cc
|
2011-03-31 08:39:26 +00:00
|
|
|
class MPSolverInterface {
|
|
|
|
|
public:
|
|
|
|
|
enum SynchronizationStatus {
|
|
|
|
|
// The underlying solver (CLP, GLPK, ...) and MPSolver are not in
|
|
|
|
|
// sync for the model nor for the solution.
|
|
|
|
|
MUST_RELOAD,
|
|
|
|
|
// The underlying solver and MPSolver are in sync for the model
|
|
|
|
|
// but not for the solution: the model has changed since the
|
|
|
|
|
// solution was computed last.
|
|
|
|
|
MODEL_SYNCHRONIZED,
|
|
|
|
|
// The underlying solver and MPSolver are in sync for the model and
|
|
|
|
|
// the solution.
|
|
|
|
|
SOLUTION_SYNCHRONIZED
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// When the underlying solver does not provide the number of simplex
|
|
|
|
|
// iterations.
|
2011-11-03 10:27:53 +00:00
|
|
|
static const int64 kUnknownNumberOfIterations = -1;
|
|
|
|
|
// When the underlying solver does not provide the number of
|
|
|
|
|
// branch-and-bound nodes.
|
|
|
|
|
static const int64 kUnknownNumberOfNodes = -1;
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Constructor. The user will access the MPSolverInterface through the
|
|
|
|
|
// MPSolver passed as argument.
|
2011-03-31 08:39:26 +00:00
|
|
|
explicit MPSolverInterface(MPSolver* const solver);
|
|
|
|
|
virtual ~MPSolverInterface();
|
|
|
|
|
|
|
|
|
|
// ----- Solve -----
|
2011-06-10 20:00:52 +00:00
|
|
|
// Solves problem with specified parameter values. Returns true if the
|
2013-06-11 14:49:45 +00:00
|
|
|
// solution is optimal.
|
2011-03-31 08:39:26 +00:00
|
|
|
virtual MPSolver::ResultStatus Solve(const MPSolverParameters& param) = 0;
|
|
|
|
|
|
|
|
|
|
// ----- Model modifications and extraction -----
|
2011-11-03 10:27:53 +00:00
|
|
|
// Resets extracted model.
|
2011-03-31 08:39:26 +00:00
|
|
|
virtual void Reset() = 0;
|
|
|
|
|
|
|
|
|
|
// Sets the optimization direction (min/max).
|
2011-11-03 10:27:53 +00:00
|
|
|
virtual void SetOptimizationDirection(bool maximize) = 0;
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Modifies bounds of an extracted variable.
|
2011-03-31 08:39:26 +00:00
|
|
|
virtual void SetVariableBounds(int index, double lb, double ub) = 0;
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Modifies integrality of an extracted variable.
|
2011-03-31 08:39:26 +00:00
|
|
|
virtual void SetVariableInteger(int index, bool integer) = 0;
|
|
|
|
|
|
|
|
|
|
// Modify bounds of an extracted variable.
|
|
|
|
|
virtual void SetConstraintBounds(int index, double lb, double ub) = 0;
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Adds a linear constraint.
|
2011-03-31 08:39:26 +00:00
|
|
|
virtual void AddRowConstraint(MPConstraint* const ct) = 0;
|
|
|
|
|
|
|
|
|
|
// Add a variable.
|
|
|
|
|
virtual void AddVariable(MPVariable* const var) = 0;
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Changes a coefficient in a constraint.
|
2011-03-31 08:39:26 +00:00
|
|
|
virtual void SetCoefficient(MPConstraint* const constraint,
|
2011-12-16 21:02:01 +00:00
|
|
|
const MPVariable* const variable,
|
2014-01-08 12:01:58 +00:00
|
|
|
double new_value, double old_value) = 0;
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Clears a constraint from all its terms.
|
2011-03-31 08:39:26 +00:00
|
|
|
virtual void ClearConstraint(MPConstraint* const constraint) = 0;
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Changes a coefficient in the linear objective.
|
2011-12-16 21:02:01 +00:00
|
|
|
virtual void SetObjectiveCoefficient(const MPVariable* const variable,
|
2011-03-31 08:39:26 +00:00
|
|
|
double coefficient) = 0;
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Changes the constant term in the linear objective.
|
2011-03-31 08:39:26 +00:00
|
|
|
virtual void SetObjectiveOffset(double value) = 0;
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Clears the objective from all its terms.
|
2011-03-31 08:39:26 +00:00
|
|
|
virtual void ClearObjective() = 0;
|
|
|
|
|
|
|
|
|
|
// ------ Query statistics on the solution and the solve ------
|
2013-01-10 17:00:09 +00:00
|
|
|
// Returns the number of simplex iterations. The problem must be discrete,
|
|
|
|
|
// otherwise it crashes, or returns kUnknownNumberOfIterations in NDEBUG mode.
|
2011-03-31 08:39:26 +00:00
|
|
|
virtual int64 iterations() const = 0;
|
2013-01-10 17:00:09 +00:00
|
|
|
// Returns the number of branch-and-bound nodes. The problem must be discrete,
|
|
|
|
|
// otherwise it crashes, or returns kUnknownNumberOfNodes in NDEBUG mode.
|
2011-03-31 08:39:26 +00:00
|
|
|
virtual int64 nodes() const = 0;
|
2013-01-10 17:00:09 +00:00
|
|
|
// Returns the best objective bound. The problem must be discrete, otherwise
|
|
|
|
|
// it crashes, or returns trivial_worst_objective_bound() in NDEBUG mode.
|
2011-03-31 08:39:26 +00:00
|
|
|
virtual double best_objective_bound() const = 0;
|
2013-01-10 17:00:09 +00:00
|
|
|
// A trivial objective bound: the worst possible value of the objective,
|
|
|
|
|
// which will be +infinity if minimizing and -infinity if maximing.
|
|
|
|
|
double trivial_worst_objective_bound() const;
|
2011-11-03 10:27:53 +00:00
|
|
|
// Returns the objective value of the best solution found so far.
|
2011-03-31 08:39:26 +00:00
|
|
|
double objective_value() const;
|
|
|
|
|
|
2011-09-05 13:42:36 +00:00
|
|
|
// Returns the basis status of a row.
|
|
|
|
|
virtual MPSolver::BasisStatus row_status(int constraint_index) const = 0;
|
|
|
|
|
// Returns the basis status of a constraint.
|
|
|
|
|
virtual MPSolver::BasisStatus column_status(int variable_index) const = 0;
|
|
|
|
|
|
2013-01-10 17:00:09 +00:00
|
|
|
// Checks whether the solution is synchronized with the model, i.e. whether
|
|
|
|
|
// the model has changed since the solution was computed last.
|
|
|
|
|
// If it isn't, it crashes in NDEBUG, and returns false othwerwise.
|
|
|
|
|
bool CheckSolutionIsSynchronized() const;
|
|
|
|
|
// Checks whether a feasible solution exists. The behavior is similar to
|
|
|
|
|
// CheckSolutionIsSynchronized() above.
|
|
|
|
|
virtual bool CheckSolutionExists() const;
|
2011-12-16 21:02:01 +00:00
|
|
|
// Handy shortcut to do both checks above (it is often used).
|
2013-01-10 17:00:09 +00:00
|
|
|
bool CheckSolutionIsSynchronizedAndExists() const {
|
|
|
|
|
return CheckSolutionIsSynchronized() && CheckSolutionExists();
|
2011-12-16 21:02:01 +00:00
|
|
|
}
|
2013-01-10 17:00:09 +00:00
|
|
|
// Checks whether information on the best objective bound exists. The behavior
|
|
|
|
|
// is similar to CheckSolutionIsSynchronized() above.
|
|
|
|
|
virtual bool CheckBestObjectiveBoundExists() const;
|
2011-03-31 08:39:26 +00:00
|
|
|
|
|
|
|
|
// ----- Misc -----
|
2011-11-03 10:27:53 +00:00
|
|
|
// Queries problem type. For simplicity, the distinction between
|
2011-03-31 08:39:26 +00:00
|
|
|
// continuous and discrete is based on the declaration of the user
|
|
|
|
|
// when the solver is created (example: GLPK_LINEAR_PROGRAMMING
|
|
|
|
|
// vs. GLPK_MIXED_INTEGER_PROGRAMMING), not on the actual content of
|
|
|
|
|
// the model.
|
|
|
|
|
// Returns true if the problem is continuous.
|
|
|
|
|
virtual bool IsContinuous() const = 0;
|
|
|
|
|
// Returns true if the problem is continuous and linear.
|
|
|
|
|
virtual bool IsLP() const = 0;
|
|
|
|
|
// Returns true if the problem is discrete and linear.
|
|
|
|
|
virtual bool IsMIP() const = 0;
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Returns the index of the last variable extracted.
|
2014-01-08 12:01:58 +00:00
|
|
|
int last_variable_index() const { return last_variable_index_; }
|
2011-05-30 14:25:30 +00:00
|
|
|
|
2015-06-18 14:08:50 +02:00
|
|
|
bool variable_is_extracted(int var_index) const {
|
|
|
|
|
return solver_->variable_is_extracted_[var_index];
|
|
|
|
|
}
|
|
|
|
|
void set_variable_as_extracted(int var_index, bool extracted) {
|
|
|
|
|
solver_->variable_is_extracted_[var_index] = extracted;
|
|
|
|
|
}
|
|
|
|
|
bool constraint_is_extracted(int ct_index) const {
|
|
|
|
|
return solver_->constraint_is_extracted_[ct_index];
|
|
|
|
|
}
|
|
|
|
|
void set_constraint_as_extracted(int ct_index, bool extracted) {
|
|
|
|
|
solver_->constraint_is_extracted_[ct_index] = extracted;
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Returns the boolean indicating the verbosity of the solver output.
|
2014-01-08 12:01:58 +00:00
|
|
|
bool quiet() const { return quiet_; }
|
2011-11-03 10:27:53 +00:00
|
|
|
// Sets the boolean indicating the verbosity of the solver output.
|
2014-01-08 12:01:58 +00:00
|
|
|
void set_quiet(bool quiet_value) { quiet_ = quiet_value; }
|
2011-05-30 14:25:30 +00:00
|
|
|
|
2011-03-31 08:39:26 +00:00
|
|
|
// Returns the result status of the last solve.
|
|
|
|
|
MPSolver::ResultStatus result_status() const {
|
|
|
|
|
CheckSolutionIsSynchronized();
|
|
|
|
|
return result_status_;
|
|
|
|
|
}
|
2011-09-05 13:42:36 +00:00
|
|
|
|
2013-12-16 10:24:42 +00:00
|
|
|
// Returns a std::string describing the underlying solver and its version.
|
|
|
|
|
virtual std::string SolverVersion() const = 0;
|
2011-03-31 08:39:26 +00:00
|
|
|
|
2011-08-11 18:44:23 +00:00
|
|
|
// Returns the underlying solver.
|
|
|
|
|
virtual void* underlying_solver() = 0;
|
|
|
|
|
|
2011-09-19 08:58:03 +00:00
|
|
|
// Computes exact condition number. Only available for continuous
|
|
|
|
|
// problems and only implemented in GLPK.
|
2013-01-10 17:00:09 +00:00
|
|
|
virtual double ComputeExactConditionNumber() const;
|
2011-09-19 08:58:03 +00:00
|
|
|
|
2014-12-16 11:35:09 +00:00
|
|
|
virtual bool InterruptSolve() { return false; }
|
|
|
|
|
|
2011-03-31 08:39:26 +00:00
|
|
|
friend class MPSolver;
|
2011-12-16 21:02:01 +00:00
|
|
|
|
2012-09-11 17:23:15 +00:00
|
|
|
// To access the maximize_ bool and the MPSolver.
|
|
|
|
|
friend class MPConstraint;
|
2011-12-16 21:02:01 +00:00
|
|
|
friend class MPObjective;
|
|
|
|
|
|
2011-03-31 08:39:26 +00:00
|
|
|
protected:
|
|
|
|
|
MPSolver* const solver_;
|
|
|
|
|
// Indicates whether the model and the solution are synchronized.
|
|
|
|
|
SynchronizationStatus sync_status_;
|
|
|
|
|
// Indicates whether the solve has reached optimality,
|
|
|
|
|
// infeasibility, a limit, etc.
|
|
|
|
|
MPSolver::ResultStatus result_status_;
|
2011-11-03 10:27:53 +00:00
|
|
|
// Optimization direction.
|
2011-03-31 08:39:26 +00:00
|
|
|
bool maximize_;
|
|
|
|
|
|
2011-09-05 13:42:36 +00:00
|
|
|
// Index in MPSolver::variables_ of last constraint extracted.
|
2011-03-31 08:39:26 +00:00
|
|
|
int last_constraint_index_;
|
2011-09-05 13:42:36 +00:00
|
|
|
// Index in MPSolver::constraints_ of last variable extracted.
|
2011-03-31 08:39:26 +00:00
|
|
|
int last_variable_index_;
|
|
|
|
|
|
|
|
|
|
// The value of the objective function.
|
|
|
|
|
double objective_value_;
|
|
|
|
|
|
2011-05-30 14:25:30 +00:00
|
|
|
// Boolean indicator for the verbosity of the solver output.
|
|
|
|
|
bool quiet_;
|
|
|
|
|
|
2011-03-31 08:39:26 +00:00
|
|
|
// Index of dummy variable created for empty constraints or the
|
|
|
|
|
// objective offset.
|
|
|
|
|
static const int kDummyVariableIndex;
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Extracts model stored in MPSolver.
|
2011-03-31 08:39:26 +00:00
|
|
|
void ExtractModel();
|
2011-11-03 10:27:53 +00:00
|
|
|
// Extracts the variables that have not been extracted yet.
|
2011-03-31 08:39:26 +00:00
|
|
|
virtual void ExtractNewVariables() = 0;
|
2011-11-03 10:27:53 +00:00
|
|
|
// Extracts the constraints that have not been extracted yet.
|
2011-03-31 08:39:26 +00:00
|
|
|
virtual void ExtractNewConstraints() = 0;
|
2011-11-03 10:27:53 +00:00
|
|
|
// Extracts the objective.
|
2011-03-31 08:39:26 +00:00
|
|
|
virtual void ExtractObjective() = 0;
|
2011-11-03 10:27:53 +00:00
|
|
|
// Resets the extraction information.
|
2011-03-31 08:39:26 +00:00
|
|
|
void ResetExtractionInformation();
|
|
|
|
|
// Change synchronization status from SOLUTION_SYNCHRONIZED to
|
|
|
|
|
// MODEL_SYNCHRONIZED. To be used for model changes.
|
|
|
|
|
void InvalidateSolutionSynchronization();
|
|
|
|
|
|
2011-11-03 10:27:53 +00:00
|
|
|
// Sets parameters common to LP and MIP in the underlying solver.
|
2011-03-31 08:39:26 +00:00
|
|
|
void SetCommonParameters(const MPSolverParameters& param);
|
2011-11-03 10:27:53 +00:00
|
|
|
// Sets MIP specific parameters in the underlying solver.
|
2011-03-31 08:39:26 +00:00
|
|
|
void SetMIPParameters(const MPSolverParameters& param);
|
2011-11-03 10:27:53 +00:00
|
|
|
// Sets all parameters in the underlying solver.
|
2011-03-31 08:39:26 +00:00
|
|
|
virtual void SetParameters(const MPSolverParameters& param) = 0;
|
2011-11-03 10:27:53 +00:00
|
|
|
// Sets an unsupported double parameter.
|
2011-03-31 08:39:26 +00:00
|
|
|
void SetUnsupportedDoubleParam(MPSolverParameters::DoubleParam param) const;
|
2011-11-03 10:27:53 +00:00
|
|
|
// Sets an unsupported integer parameter.
|
2011-03-31 08:39:26 +00:00
|
|
|
void SetUnsupportedIntegerParam(MPSolverParameters::IntegerParam param) const;
|
2011-11-03 10:27:53 +00:00
|
|
|
// Sets a supported double parameter to an unsupported value.
|
2011-03-31 08:39:26 +00:00
|
|
|
void SetDoubleParamToUnsupportedValue(MPSolverParameters::DoubleParam param,
|
2013-10-10 15:23:20 +00:00
|
|
|
double value) const;
|
2011-11-03 10:27:53 +00:00
|
|
|
// Sets a supported integer parameter to an unsupported value.
|
2011-03-31 08:39:26 +00:00
|
|
|
void SetIntegerParamToUnsupportedValue(MPSolverParameters::IntegerParam param,
|
2013-10-10 15:23:20 +00:00
|
|
|
int value) const;
|
2011-11-03 10:27:53 +00:00
|
|
|
// Sets each parameter in the underlying solver.
|
2011-03-31 08:39:26 +00:00
|
|
|
virtual void SetRelativeMipGap(double value) = 0;
|
2011-09-08 00:34:13 +00:00
|
|
|
virtual void SetPrimalTolerance(double value) = 0;
|
|
|
|
|
virtual void SetDualTolerance(double value) = 0;
|
2011-03-31 08:39:26 +00:00
|
|
|
virtual void SetPresolveMode(int value) = 0;
|
2012-09-11 17:23:15 +00:00
|
|
|
|
2013-06-11 14:49:45 +00:00
|
|
|
// Reads a solver-specific file of parameters and set them.
|
|
|
|
|
// Returns true if there was no errors.
|
2013-12-16 10:24:42 +00:00
|
|
|
virtual bool ReadParameterFile(const std::string& filename);
|
2013-06-11 14:49:45 +00:00
|
|
|
|
|
|
|
|
// Returns a file extension like ".tmp", this is needed because some solvers
|
|
|
|
|
// require a given extension for the ReadParameterFile() filename and we need
|
|
|
|
|
// to know it to generate a temporary parameter file.
|
2013-12-16 10:24:42 +00:00
|
|
|
virtual std::string ValidFileExtensionForParameterFile() const;
|
2013-06-11 14:49:45 +00:00
|
|
|
|
2012-09-11 17:23:15 +00:00
|
|
|
// Sets the scaling mode.
|
|
|
|
|
virtual void SetScalingMode(int value) = 0;
|
2011-03-31 08:39:26 +00:00
|
|
|
virtual void SetLpAlgorithm(int value) = 0;
|
|
|
|
|
};
|
|
|
|
|
|
2013-01-10 17:00:09 +00:00
|
|
|
|
2011-03-31 08:39:26 +00:00
|
|
|
} // namespace operations_research
|
|
|
|
|
|
2011-05-11 16:05:15 +00:00
|
|
|
#endif // OR_TOOLS_LINEAR_SOLVER_LINEAR_SOLVER_H_
|