linear_solver.h
Go to the documentation of this file.
1 // Copyright 2010-2018 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
134 #ifndef OR_TOOLS_LINEAR_SOLVER_LINEAR_SOLVER_H_
135 #define OR_TOOLS_LINEAR_SOLVER_LINEAR_SOLVER_H_
136 
137 #include <functional>
138 #include <limits>
139 #include <map>
140 #include <memory>
141 #include <string>
142 #include <utility>
143 #include <vector>
144 
145 #include "absl/container/flat_hash_map.h"
146 #include "absl/strings/match.h"
147 #include "absl/strings/str_format.h"
148 #include "absl/types/optional.h"
149 #include "ortools/base/commandlineflags.h"
150 #include "ortools/base/integral_types.h"
151 #include "ortools/base/logging.h"
152 #include "ortools/base/macros.h"
153 #include "ortools/base/status.h"
154 #include "ortools/base/timer.h"
155 #include "ortools/glop/parameters.pb.h"
158 #include "ortools/port/proto_utils.h"
159 
160 namespace operations_research {
161 
162 constexpr double kDefaultPrimalTolerance = 1e-07;
163 
164 class MPConstraint;
165 class MPObjective;
166 class MPSolverInterface;
167 class MPSolverParameters;
168 class MPVariable;
169 
174 class MPSolver {
175  public:
183 #ifdef USE_CLP
186 #endif
187 #ifdef USE_GLPK
188  GLPK_LINEAR_PROGRAMMING = 1,
190 #endif
191 #ifdef USE_GLOP
194 #endif
195 #ifdef USE_GUROBI
196  GUROBI_LINEAR_PROGRAMMING = 6,
198 #endif
199 #ifdef USE_CPLEX
200  CPLEX_LINEAR_PROGRAMMING = 10,
202 #endif
203 
204 // Integer programming problems.
205 #ifdef USE_SCIP
206  SCIP_MIXED_INTEGER_PROGRAMMING = 3, // Recommended default value.
208 #endif
209 #ifdef USE_GLPK
210  GLPK_MIXED_INTEGER_PROGRAMMING = 4,
212 #endif
213 #ifdef USE_CBC
216 #endif
217 #if defined(USE_GUROBI)
218  GUROBI_MIXED_INTEGER_PROGRAMMING = 7,
220 #endif
221 #if defined(USE_CPLEX)
222  CPLEX_MIXED_INTEGER_PROGRAMMING = 11,
224 #endif
225 #if defined(USE_BOP)
228 #endif
229  };
230 
232  MPSolver(const std::string& name, OptimizationProblemType problem_type);
233  virtual ~MPSolver();
234 
239  static bool SupportsProblemType(OptimizationProblemType problem_type);
240 
245  static bool ParseSolverType(absl::string_view solver,
247 
248  bool IsMIP() const;
249 
251  const std::string& Name() const {
252  return name_; // Set at construction.
253  }
254 
257  return problem_type_; // Set at construction.
258  }
259 
265  void Clear();
266 
268  int NumVariables() const { return variables_.size(); }
269 
274  const std::vector<MPVariable*>& variables() const { return variables_; }
275 
281  MPVariable* LookupVariableOrNull(const std::string& var_name) const;
282 
290  MPVariable* MakeVar(double lb, double ub, bool integer,
291  const std::string& name);
292 
294  MPVariable* MakeNumVar(double lb, double ub, const std::string& name);
295 
297  MPVariable* MakeIntVar(double lb, double ub, const std::string& name);
298 
300  MPVariable* MakeBoolVar(const std::string& name);
301 
316  void MakeVarArray(int nb, double lb, double ub, bool integer,
317  const std::string& name_prefix,
318  std::vector<MPVariable*>* vars);
319 
321  void MakeNumVarArray(int nb, double lb, double ub, const std::string& name,
322  std::vector<MPVariable*>* vars);
323 
325  void MakeIntVarArray(int nb, double lb, double ub, const std::string& name,
326  std::vector<MPVariable*>* vars);
327 
329  void MakeBoolVarArray(int nb, const std::string& name,
330  std::vector<MPVariable*>* vars);
331 
333  int NumConstraints() const { return constraints_.size(); }
334 
340  const std::vector<MPConstraint*>& constraints() const { return constraints_; }
341 
350  const std::string& constraint_name) const;
351 
360  MPConstraint* MakeRowConstraint(double lb, double ub);
361 
364 
366  MPConstraint* MakeRowConstraint(double lb, double ub,
367  const std::string& name);
368 
370  MPConstraint* MakeRowConstraint(const std::string& name);
371 
377 
380  const std::string& name);
381 
388  const MPObjective& Objective() const { return *objective_; }
389 
391  MPObjective* MutableObjective() { return objective_.get(); }
392 
414  };
415 
418 
420  ResultStatus Solve(const MPSolverParameters& param);
421 
426  void Write(const std::string& file_name);
427 
434  std::vector<double> ComputeConstraintActivities() const;
435 
454  bool VerifySolution(double tolerance, bool log_errors) const;
455 
464  void Reset();
465 
473  bool InterruptSolve();
474 
483  std::string* error_message);
492  const MPModelProto& input_model, std::string* error_message);
493 
495  void FillSolutionResponseProto(MPSolutionResponse* response) const;
496 
506  static void SolveWithProto(const MPModelRequest& model_request,
507  MPSolutionResponse* response);
508 
510  void ExportModelToProto(MPModelProto* output_model) const;
511 
543  util::Status LoadSolutionFromProto(
544  const MPSolutionResponse& response,
545  double tolerance = kDefaultPrimalTolerance);
546 
551  util::Status ClampSolutionWithinBounds();
552 
559  bool ExportModelAsLpFormat(bool obfuscate, std::string* model_str) const;
560  bool ExportModelAsMpsFormat(bool fixed_format, bool obfuscate,
561  std::string* model_str) const;
562 
573  util::Status SetNumThreads(int num_threads);
574 
576  int GetNumThreads() const { return num_threads_; }
577 
588  bool SetSolverSpecificParametersAsString(const std::string& parameters);
590  return solver_specific_parameter_string_;
591  }
592 
606  void SetHint(std::vector<std::pair<const MPVariable*, double> > hint);
607 
612  enum BasisStatus {
613  FREE = 0,
618  };
619 
631  void SetStartingLpBasis(
632  const std::vector<MPSolver::BasisStatus>& variable_statuses,
633  const std::vector<MPSolver::BasisStatus>& constraint_statuses);
634 
640  static double infinity() { return std::numeric_limits<double>::infinity(); }
641 
650  bool OutputIsEnabled() const;
651 
652  void EnableOutput();
653 
655  void SuppressOutput();
656 
657  absl::Duration TimeLimit() const { return time_limit_; }
658  void SetTimeLimit(absl::Duration time_limit) {
659  DCHECK_GE(time_limit, absl::ZeroDuration());
660  time_limit_ = time_limit;
661  }
662 
663  absl::Duration DurationSinceConstruction() const {
664  return absl::Now() - construction_time_;
665  }
666 
668  int64 iterations() const;
669 
675  int64 nodes() const;
676 
678  std::string SolverVersion() const;
679 
693  void* underlying_solver();
694 
718  double ComputeExactConditionNumber() const;
719 
734  ABSL_MUST_USE_RESULT bool NextSolution();
735 
736  // DEPRECATED: Use TimeLimit() and SetTimeLimit(absl::Duration) instead.
737  // NOTE: These deprecated functions used the convention time_limit = 0 to mean
738  // "no limit", which now corresponds to time_limit_ = InfiniteDuration().
739  int64 time_limit() const {
740  return time_limit_ == absl::InfiniteDuration()
741  ? 0
742  : absl::ToInt64Milliseconds(time_limit_);
743  }
744  void set_time_limit(int64 time_limit_milliseconds) {
745  SetTimeLimit(time_limit_milliseconds == 0
746  ? absl::InfiniteDuration()
747  : absl::Milliseconds(time_limit_milliseconds));
748  }
749  double time_limit_in_secs() const {
750  return static_cast<double>(time_limit()) / 1000.0;
751  }
752 
753  // DEPRECATED: Use DurationSinceConstruction() instead.
754  int64 wall_time() const {
755  return absl::ToInt64Milliseconds(DurationSinceConstruction());
756  }
757 
758  friend class GLPKInterface;
759  friend class CLPInterface;
760  friend class CBCInterface;
761  friend class SCIPInterface;
762  friend class GurobiInterface;
763  friend class CplexInterface;
764  friend class SLMInterface;
765  friend class MPSolverInterface;
766  friend class GLOPInterface;
767  friend class BopInterface;
768  friend class SatInterface;
769  friend class KnapsackInterface;
770 
771  // Debugging: verify that the given MPVariable* belongs to this solver.
772  bool OwnsVariable(const MPVariable* var) const;
773 
774  private:
775  // Computes the size of the constraint with the largest number of
776  // coefficients with index in [min_constraint_index,
777  // max_constraint_index)
778  int ComputeMaxConstraintSize(int min_constraint_index,
779  int max_constraint_index) const;
780 
781  // Returns true if the model has constraints with lower bound > upper bound.
782  bool HasInfeasibleConstraints() const;
783 
784  // Returns true if the model has at least 1 integer variable.
785  bool HasIntegerVariables() const;
786 
787  // Generates the map from variable names to their indices.
788  void GenerateVariableNameIndex() const;
789 
790  // Generates the map from constraint names to their indices.
791  void GenerateConstraintNameIndex() const;
792 
793  // The name of the linear programming problem.
794  const std::string name_;
795 
796  // The type of the linear programming problem.
797  const OptimizationProblemType problem_type_;
798 
799  // The solver interface.
800  std::unique_ptr<MPSolverInterface> interface_;
801 
802  // The vector of variables in the problem.
803  std::vector<MPVariable*> variables_;
804  // A map from a variable's name to its index in variables_.
805  mutable absl::optional<absl::flat_hash_map<std::string, int> >
806  variable_name_to_index_;
807  // Whether variables have been extracted to the underlying interface.
808  std::vector<bool> variable_is_extracted_;
809 
810  // The vector of constraints in the problem.
811  std::vector<MPConstraint*> constraints_;
812  // A map from a constraint's name to its index in constraints_.
813  mutable absl::optional<absl::flat_hash_map<std::string, int> >
814  constraint_name_to_index_;
815  // Whether constraints have been extracted to the underlying interface.
816  std::vector<bool> constraint_is_extracted_;
817 
818  // The linear objective function.
819  std::unique_ptr<MPObjective> objective_;
820 
821  // Initial values for all or some of the problem variables that can be
822  // exploited as a starting hint by a solver.
823  //
824  // Note(user): as of 05/05/2015, we can't use >> because of some SWIG errors.
825  //
826  // TODO(user): replace by two vectors, a std::vector<bool> to indicate if a
827  // hint is provided and a std::vector<double> for the hint value.
828  std::vector<std::pair<const MPVariable*, double> > solution_hint_;
829 
830  absl::Duration time_limit_ = absl::InfiniteDuration(); // Default = No limit.
831 
832  const absl::Time construction_time_;
833 
834  // Permanent storage for the number of threads.
835  int num_threads_ = 1;
836 
837  // Permanent storage for SetSolverSpecificParametersAsString().
838  std::string solver_specific_parameter_string_;
839 
840  MPSolverResponseStatus LoadModelFromProtoInternal(
841  const MPModelProto& input_model, bool clear_names,
842  std::string* error_message);
843 
844  DISALLOW_COPY_AND_ASSIGN(MPSolver);
845 };
846 
847 const absl::string_view ToString(
848  MPSolver::OptimizationProblemType optimization_problem_type);
849 
850 inline std::ostream& operator<<(
851  std::ostream& os,
852  MPSolver::OptimizationProblemType optimization_problem_type) {
853  return os << ToString(optimization_problem_type);
854 }
855 
856 inline std::ostream& operator<<(std::ostream& os,
857  MPSolver::ResultStatus status) {
858  return os << ProtoEnumToString<MPSolverResponseStatus>(
859  static_cast<MPSolverResponseStatus>(status));
860 }
861 
862 bool AbslParseFlag(absl::string_view text,
864  std::string* error);
865 
866 inline std::string AbslUnparseFlag(
867  MPSolver::OptimizationProblemType solver_type) {
868  return std::string(ToString(solver_type));
869 }
870 
872 class MPObjective {
873  public:
878  void Clear();
879 
886  void SetCoefficient(const MPVariable* const var, double coeff);
887 
893  double GetCoefficient(const MPVariable* const var) const;
894 
900  const absl::flat_hash_map<const MPVariable*, double>& terms() const {
901  return coefficients_;
902  }
903 
905  void SetOffset(double value);
906 
908  double offset() const { return offset_; }
909 
914  void OptimizeLinearExpr(const LinearExpr& linear_expr, bool is_maximization);
915 
917  void MaximizeLinearExpr(const LinearExpr& linear_expr) {
918  OptimizeLinearExpr(linear_expr, true);
919  }
921  void MinimizeLinearExpr(const LinearExpr& linear_expr) {
922  OptimizeLinearExpr(linear_expr, false);
923  }
924 
926  void AddLinearExpr(const LinearExpr& linear_expr);
927 
929  void SetOptimizationDirection(bool maximize);
930 
933 
936 
938  bool maximization() const;
939 
941  bool minimization() const;
942 
954  double Value() const;
955 
962  double BestBound() const;
963 
964  private:
965  friend class MPSolver;
966  friend class MPSolverInterface;
967  friend class CBCInterface;
968  friend class CLPInterface;
969  friend class GLPKInterface;
970  friend class SCIPInterface;
971  friend class SLMInterface;
972  friend class GurobiInterface;
973  friend class CplexInterface;
974  friend class GLOPInterface;
975  friend class BopInterface;
976  friend class SatInterface;
977  friend class KnapsackInterface;
978 
979  // Constructor. An objective points to a single MPSolverInterface
980  // that is specified in the constructor. An objective cannot belong
981  // to several models.
982  // At construction, an MPObjective has no terms (which is equivalent
983  // on having a coefficient of 0 for all variables), and an offset of 0.
984  explicit MPObjective(MPSolverInterface* const interface_in)
985  : interface_(interface_in), coefficients_(1), offset_(0.0) {}
986 
987  MPSolverInterface* const interface_;
988 
989  // Mapping var -> coefficient.
990  absl::flat_hash_map<const MPVariable*, double> coefficients_;
991  // Constant term.
992  double offset_;
993 
994  DISALLOW_COPY_AND_ASSIGN(MPObjective);
995 };
996 
998 class MPVariable {
999  public:
1001  const std::string& name() const { return name_; }
1002 
1004  void SetInteger(bool integer);
1005 
1007  bool integer() const { return integer_; }
1008 
1016  double solution_value() const;
1017 
1019  int index() const { return index_; }
1020 
1022  double lb() const { return lb_; }
1023 
1025  double ub() const { return ub_; }
1026 
1028  void SetLB(double lb) { SetBounds(lb, ub_); }
1029 
1031  void SetUB(double ub) { SetBounds(lb_, ub); }
1032 
1034  void SetBounds(double lb, double ub);
1035 
1042  double unrounded_solution_value() const;
1043 
1048  double reduced_cost() const;
1049 
1057 
1068  int branching_priority() const { return branching_priority_; }
1069  void SetBranchingPriority(int priority);
1070 
1071  protected:
1072  friend class MPSolver;
1073  friend class MPSolverInterface;
1074  friend class CBCInterface;
1075  friend class CLPInterface;
1076  friend class GLPKInterface;
1077  friend class SCIPInterface;
1078  friend class SLMInterface;
1079  friend class GurobiInterface;
1080  friend class CplexInterface;
1081  friend class GLOPInterface;
1083  friend class BopInterface;
1084  friend class SatInterface;
1085  friend class KnapsackInterface;
1086 
1087  // Constructor. A variable points to a single MPSolverInterface that
1088  // is specified in the constructor. A variable cannot belong to
1089  // several models.
1090  MPVariable(int index, double lb, double ub, bool integer,
1091  const std::string& name, MPSolverInterface* const interface_in)
1092  : index_(index),
1093  lb_(lb),
1094  ub_(ub),
1095  integer_(integer),
1096  name_(name.empty() ? absl::StrFormat("auto_v_%09d", index) : name),
1097  solution_value_(0.0),
1098  reduced_cost_(0.0),
1099  interface_(interface_in) {}
1100 
1101  void set_solution_value(double value) { solution_value_ = value; }
1102  void set_reduced_cost(double reduced_cost) { reduced_cost_ = reduced_cost; }
1103 
1104  private:
1105  const int index_;
1106  double lb_;
1107  double ub_;
1108  bool integer_;
1109  const std::string name_;
1110  double solution_value_;
1111  double reduced_cost_;
1112  int branching_priority_ = 0;
1113  MPSolverInterface* const interface_;
1114  DISALLOW_COPY_AND_ASSIGN(MPVariable);
1115 };
1116 
1123  public:
1125  const std::string& name() const { return name_; }
1126 
1128  void Clear();
1129 
1136  void SetCoefficient(const MPVariable* const var, double coeff);
1137 
1142  double GetCoefficient(const MPVariable* const var) const;
1143 
1149  const absl::flat_hash_map<const MPVariable*, double>& terms() const {
1150  return coefficients_;
1151  }
1152 
1154  double lb() const { return lb_; }
1155 
1157  double ub() const { return ub_; }
1158 
1160  void SetLB(double lb) { SetBounds(lb, ub_); }
1161 
1163  void SetUB(double ub) { SetBounds(lb_, ub); }
1164 
1166  void SetBounds(double lb, double ub);
1167 
1169  bool is_lazy() const { return is_lazy_; }
1170 
1184  void set_is_lazy(bool laziness) { is_lazy_ = laziness; }
1185 
1186  const MPVariable* indicator_variable() const { return indicator_variable_; }
1187  bool indicator_value() const { return indicator_value_; }
1188 
1190  int index() const { return index_; }
1191 
1196  double dual_value() const;
1197 
1211 
1212  protected:
1213  friend class MPSolver;
1214  friend class MPSolverInterface;
1215  friend class CBCInterface;
1216  friend class CLPInterface;
1217  friend class GLPKInterface;
1218  friend class SCIPInterface;
1219  friend class SLMInterface;
1220  friend class GurobiInterface;
1221  friend class CplexInterface;
1222  friend class GLOPInterface;
1223  friend class BopInterface;
1224  friend class SatInterface;
1225  friend class KnapsackInterface;
1226 
1227  // Constructor. A constraint points to a single MPSolverInterface
1228  // that is specified in the constructor. A constraint cannot belong
1229  // to several models.
1230  MPConstraint(int index, double lb, double ub, const std::string& name,
1231  MPSolverInterface* const interface_in)
1232  : coefficients_(1),
1233  index_(index),
1234  lb_(lb),
1235  ub_(ub),
1236  name_(name.empty() ? absl::StrFormat("auto_c_%09d", index) : name),
1237  is_lazy_(false),
1238  indicator_variable_(nullptr),
1239  dual_value_(0.0),
1240  interface_(interface_in) {}
1241 
1242  void set_dual_value(double dual_value) { dual_value_ = dual_value; }
1243 
1244  private:
1245  // Returns true if the constraint contains variables that have not
1246  // been extracted yet.
1247  bool ContainsNewVariables();
1248 
1249  // Mapping var -> coefficient.
1250  absl::flat_hash_map<const MPVariable*, double> coefficients_;
1251 
1252  const int index_; // See index().
1253 
1254  // The lower bound for the linear constraint.
1255  double lb_;
1256 
1257  // The upper bound for the linear constraint.
1258  double ub_;
1259 
1260  // Name.
1261  const std::string name_;
1262 
1263  // True if the constraint is "lazy", i.e. the constraint is added to the
1264  // underlying Linear Programming solver only if it is violated.
1265  // By default this parameter is 'false'.
1266  bool is_lazy_;
1267 
1268  // If given, this constraint is only active if `indicator_variable_`'s value
1269  // is equal to `indicator_value_`.
1270  const MPVariable* indicator_variable_;
1271  bool indicator_value_;
1272 
1273  double dual_value_;
1274  MPSolverInterface* const interface_;
1275  DISALLOW_COPY_AND_ASSIGN(MPConstraint);
1276 };
1277 
1305  public:
1310 
1320  };
1321 
1325  PRESOLVE = 1000,
1331  SCALING = 1003
1332  };
1333 
1340  };
1341 
1345  DUAL = 10,
1347  PRIMAL = 11,
1349  BARRIER = 12
1350  };
1351 
1356 
1362  };
1363 
1370  };
1371 
1372  // Placeholder value to indicate that a parameter is set to
1373  // the default value defined in the wrapper.
1374  static const double kDefaultDoubleParamValue;
1375  static const int kDefaultIntegerParamValue;
1376 
1377  // Placeholder value to indicate that a parameter is unknown.
1378  static const double kUnknownDoubleParamValue;
1379  static const int kUnknownIntegerParamValue;
1380 
1381  // Default values for parameters. Only parameters that define the
1382  // properties of the solution returned need to have a default value
1383  // (that is the same for all solvers). You can also define a default
1384  // value for performance parameters when you are confident it is a
1385  // good choice (example: always turn presolve on).
1386  static const double kDefaultRelativeMipGap;
1387  static const double kDefaultPrimalTolerance;
1388  static const double kDefaultDualTolerance;
1391 
1394 
1396  void SetDoubleParam(MPSolverParameters::DoubleParam param, double value);
1397 
1399  void SetIntegerParam(MPSolverParameters::IntegerParam param, int value);
1400 
1407 
1414 
1416  void Reset();
1417 
1419  double GetDoubleParam(MPSolverParameters::DoubleParam param) const;
1420 
1423 
1424  private:
1425  // Parameter value for each parameter.
1426  // @see DoubleParam
1427  // @see IntegerParam
1428  double relative_mip_gap_value_;
1429  double primal_tolerance_value_;
1430  double dual_tolerance_value_;
1431  int presolve_value_;
1432  int scaling_value_;
1433  int lp_algorithm_value_;
1434  int incrementality_value_;
1435 
1436  // Boolean value indicating whether each parameter is set to the
1437  // solver's default value. Only parameters for which the wrapper
1438  // does not define a default value need such an indicator.
1439  bool lp_algorithm_is_default_;
1440 
1441  DISALLOW_COPY_AND_ASSIGN(MPSolverParameters);
1442 };
1443 
1444 // This class wraps the actual mathematical programming solvers. Each
1445 // solver (GLOP, CLP, CBC, GLPK, SCIP) has its own interface class that
1446 // derives from this abstract class. This class is never directly
1447 // accessed by the user.
1448 // @see glop_interface.cc
1449 // @see cbc_interface.cc
1450 // @see clp_interface.cc
1451 // @see glpk_interface.cc
1452 // @see scip_interface.cc
1454  public:
1456  // The underlying solver (CLP, GLPK, ...) and MPSolver are not in
1457  // sync for the model nor for the solution.
1459  // The underlying solver and MPSolver are in sync for the model
1460  // but not for the solution: the model has changed since the
1461  // solution was computed last.
1463  // The underlying solver and MPSolver are in sync for the model and
1464  // the solution.
1466  };
1467 
1468  // When the underlying solver does not provide the number of simplex
1469  // iterations.
1470  static const int64 kUnknownNumberOfIterations = -1;
1471  // When the underlying solver does not provide the number of
1472  // branch-and-bound nodes.
1473  static const int64 kUnknownNumberOfNodes = -1;
1474 
1475  // Constructor. The user will access the MPSolverInterface through the
1476  // MPSolver passed as argument.
1477  explicit MPSolverInterface(MPSolver* const solver);
1478  virtual ~MPSolverInterface();
1479 
1480  // ----- Solve -----
1481  // Solves problem with specified parameter values. Returns true if the
1482  // solution is optimal.
1483  virtual MPSolver::ResultStatus Solve(const MPSolverParameters& param) = 0;
1484 
1485  // Writes the model using the solver internal write function. Currently only
1486  // available for GurobiInterface.
1487  virtual void Write(const std::string& filename);
1488 
1489  // ----- Model modifications and extraction -----
1490  // Resets extracted model.
1491  virtual void Reset() = 0;
1492 
1493  // Sets the optimization direction (min/max).
1494  virtual void SetOptimizationDirection(bool maximize) = 0;
1495 
1496  // Modifies bounds of an extracted variable.
1497  virtual void SetVariableBounds(int index, double lb, double ub) = 0;
1498 
1499  // Modifies integrality of an extracted variable.
1500  virtual void SetVariableInteger(int index, bool integer) = 0;
1501 
1502  // Modify bounds of an extracted variable.
1503  virtual void SetConstraintBounds(int index, double lb, double ub) = 0;
1504 
1505  // Adds a linear constraint.
1506  virtual void AddRowConstraint(MPConstraint* const ct) = 0;
1507 
1508  // Adds an indicator constraint. Returns true if the feature is supported by
1509  // the underlying solver.
1510  virtual bool AddIndicatorConstraint(MPConstraint* const ct) {
1511  LOG(ERROR) << "Solver doesn't support indicator constraints.";
1512  return false;
1513  }
1514 
1515  // Add a variable.
1516  virtual void AddVariable(MPVariable* const var) = 0;
1517 
1518  // Changes a coefficient in a constraint.
1519  virtual void SetCoefficient(MPConstraint* const constraint,
1520  const MPVariable* const variable,
1521  double new_value, double old_value) = 0;
1522 
1523  // Clears a constraint from all its terms.
1524  virtual void ClearConstraint(MPConstraint* const constraint) = 0;
1525 
1526  // Changes a coefficient in the linear objective.
1527  virtual void SetObjectiveCoefficient(const MPVariable* const variable,
1528  double coefficient) = 0;
1529 
1530  // Changes the constant term in the linear objective.
1531  virtual void SetObjectiveOffset(double value) = 0;
1532 
1533  // Clears the objective from all its terms.
1534  virtual void ClearObjective() = 0;
1535 
1536  virtual void BranchingPriorityChangedForVariable(int var_index) {}
1537  // ------ Query statistics on the solution and the solve ------
1538  // Returns the number of simplex iterations. The problem must be discrete,
1539  // otherwise it crashes, or returns kUnknownNumberOfIterations in NDEBUG mode.
1540  virtual int64 iterations() const = 0;
1541  // Returns the number of branch-and-bound nodes. The problem must be discrete,
1542  // otherwise it crashes, or returns kUnknownNumberOfNodes in NDEBUG mode.
1543  virtual int64 nodes() const = 0;
1544  // Returns the best objective bound. The problem must be discrete, otherwise
1545  // it crashes, or returns trivial_worst_objective_bound() in NDEBUG mode.
1546  virtual double best_objective_bound() const = 0;
1547  // A trivial objective bound: the worst possible value of the objective,
1548  // which will be +infinity if minimizing and -infinity if maximing.
1549  double trivial_worst_objective_bound() const;
1550  // Returns the objective value of the best solution found so far.
1551  double objective_value() const;
1552 
1553  // Returns the basis status of a row.
1554  virtual MPSolver::BasisStatus row_status(int constraint_index) const = 0;
1555  // Returns the basis status of a constraint.
1556  virtual MPSolver::BasisStatus column_status(int variable_index) const = 0;
1557 
1558  // Checks whether the solution is synchronized with the model, i.e. whether
1559  // the model has changed since the solution was computed last.
1560  // If it isn't, it crashes in NDEBUG, and returns false othwerwise.
1561  bool CheckSolutionIsSynchronized() const;
1562  // Checks whether a feasible solution exists. The behavior is similar to
1563  // CheckSolutionIsSynchronized() above.
1564  virtual bool CheckSolutionExists() const;
1565  // Handy shortcut to do both checks above (it is often used).
1568  }
1569  // Checks whether information on the best objective bound exists. The behavior
1570  // is similar to CheckSolutionIsSynchronized() above.
1571  virtual bool CheckBestObjectiveBoundExists() const;
1572 
1573  // ----- Misc -----
1574  // Queries problem type. For simplicity, the distinction between
1575  // continuous and discrete is based on the declaration of the user
1576  // when the solver is created (example: GLPK_LINEAR_PROGRAMMING
1577  // vs. GLPK_MIXED_INTEGER_PROGRAMMING), not on the actual content of
1578  // the model.
1579  // Returns true if the problem is continuous.
1580  virtual bool IsContinuous() const = 0;
1581  // Returns true if the problem is continuous and linear.
1582  virtual bool IsLP() const = 0;
1583  // Returns true if the problem is discrete and linear.
1584  virtual bool IsMIP() const = 0;
1585 
1586  // Returns the index of the last variable extracted.
1588 
1589  bool variable_is_extracted(int var_index) const {
1590  return solver_->variable_is_extracted_[var_index];
1591  }
1592  void set_variable_as_extracted(int var_index, bool extracted) {
1593  solver_->variable_is_extracted_[var_index] = extracted;
1594  }
1595  bool constraint_is_extracted(int ct_index) const {
1596  return solver_->constraint_is_extracted_[ct_index];
1597  }
1598  void set_constraint_as_extracted(int ct_index, bool extracted) {
1599  solver_->constraint_is_extracted_[ct_index] = extracted;
1600  }
1601 
1602  // Returns the boolean indicating the verbosity of the solver output.
1603  bool quiet() const { return quiet_; }
1604  // Sets the boolean indicating the verbosity of the solver output.
1605  void set_quiet(bool quiet_value) { quiet_ = quiet_value; }
1606 
1607  // Returns the result status of the last solve.
1610  return result_status_;
1611  }
1612 
1613  // Returns a std::string describing the underlying solver and its version.
1614  virtual std::string SolverVersion() const = 0;
1615 
1616  // Returns the underlying solver.
1617  virtual void* underlying_solver() = 0;
1618 
1619  // Computes exact condition number. Only available for continuous
1620  // problems and only implemented in GLPK.
1621  virtual double ComputeExactConditionNumber() const;
1622 
1623  // See MPSolver::SetStartingLpBasis().
1624  virtual void SetStartingLpBasis(
1625  const std::vector<MPSolver::BasisStatus>& variable_statuses,
1626  const std::vector<MPSolver::BasisStatus>& constraint_statuses) {
1627  LOG(FATAL) << "Not supported by this solver.";
1628  }
1629 
1630  virtual bool InterruptSolve() { return false; }
1631 
1632  // See MPSolver::NextSolution() for contract.
1633  virtual bool NextSolution() { return false; }
1634 
1635  friend class MPSolver;
1636 
1637  // To access the maximize_ bool and the MPSolver.
1638  friend class MPConstraint;
1639  friend class MPObjective;
1640 
1641  protected:
1643  // Indicates whether the model and the solution are synchronized.
1645  // Indicates whether the solve has reached optimality,
1646  // infeasibility, a limit, etc.
1648  // Optimization direction.
1650 
1651  // Index in MPSolver::variables_ of last constraint extracted.
1653  // Index in MPSolver::constraints_ of last variable extracted.
1655 
1656  // The value of the objective function.
1658 
1659  // Boolean indicator for the verbosity of the solver output.
1660  bool quiet_;
1661 
1662  // Index of dummy variable created for empty constraints or the
1663  // objective offset.
1664  static const int kDummyVariableIndex;
1665 
1666  // Extracts model stored in MPSolver.
1667  void ExtractModel();
1668  // Extracts the variables that have not been extracted yet.
1669  virtual void ExtractNewVariables() = 0;
1670  // Extracts the constraints that have not been extracted yet.
1671  virtual void ExtractNewConstraints() = 0;
1672  // Extracts the objective.
1673  virtual void ExtractObjective() = 0;
1674  // Resets the extraction information.
1676  // Change synchronization status from SOLUTION_SYNCHRONIZED to
1677  // MODEL_SYNCHRONIZED. To be used for model changes.
1679 
1680  // Sets parameters common to LP and MIP in the underlying solver.
1681  void SetCommonParameters(const MPSolverParameters& param);
1682  // Sets MIP specific parameters in the underlying solver.
1683  void SetMIPParameters(const MPSolverParameters& param);
1684  // Sets all parameters in the underlying solver.
1685  virtual void SetParameters(const MPSolverParameters& param) = 0;
1686  // Sets an unsupported double parameter.
1688  // Sets an unsupported integer parameter.
1689  virtual void SetUnsupportedIntegerParam(
1691  // Sets a supported double parameter to an unsupported value.
1693  double value);
1694  // Sets a supported integer parameter to an unsupported value.
1695  virtual void SetIntegerParamToUnsupportedValue(
1696  MPSolverParameters::IntegerParam param, int value);
1697  // Sets each parameter in the underlying solver.
1698  virtual void SetRelativeMipGap(double value) = 0;
1699  virtual void SetPrimalTolerance(double value) = 0;
1700  virtual void SetDualTolerance(double value) = 0;
1701  virtual void SetPresolveMode(int value) = 0;
1702 
1703  // Sets the number of threads to be used by the solver.
1704  virtual util::Status SetNumThreads(int num_threads);
1705 
1706  // Pass solver specific parameters in text format. The format is
1707  // solver-specific and is the same as the corresponding solver configuration
1708  // file format. Returns true if the operation was successful.
1709  //
1710  // The default implementation of this method stores the parameters in a
1711  // temporary file and calls ReadParameterFile to import the parameter file
1712  // into the solver. Solvers that support passing the parameters directly can
1713  // override this method to skip the temporary file logic.
1715  const std::string& parameters);
1716 
1717  // Reads a solver-specific file of parameters and set them.
1718  // Returns true if there was no errors.
1719  virtual bool ReadParameterFile(const std::string& filename);
1720 
1721  // Returns a file extension like ".tmp", this is needed because some solvers
1722  // require a given extension for the ReadParameterFile() filename and we need
1723  // to know it to generate a temporary parameter file.
1724  virtual std::string ValidFileExtensionForParameterFile() const;
1725 
1726  // Sets the scaling mode.
1727  virtual void SetScalingMode(int value) = 0;
1728  virtual void SetLpAlgorithm(int value) = 0;
1729 };
1730 
1731 } // namespace operations_research
1732 
1733 #endif // OR_TOOLS_LINEAR_SOLVER_LINEAR_SOLVER_H_
util::Status LoadSolutionFromProto(const MPSolutionResponse &response, double tolerance=kDefaultPrimalTolerance)
Load a solution encoded in a protocol buffer onto this solver for easy access via the MPSolver interf...
Advanced usage: incrementality from one solve to the next.
virtual util::Status SetNumThreads(int num_threads)
double GetCoefficient(const MPVariable *const var) const
Gets the coefficient of a given variable in the objective.
double GetCoefficient(const MPVariable *const var) const
Gets the coefficient of a given variable on the constraint (which is 0 if the variable does not appea...
virtual MPSolver::BasisStatus column_status(int variable_index) const =0
bool integer() const
Returns the integrality requirement of the variable.
void SetIntegerParam(MPSolverParameters::IntegerParam param, int value)
Sets a integer parameter to a specific value.
void set_variable_as_extracted(int var_index, bool extracted)
void * underlying_solver()
Advanced usage: returns the underlying solver.
virtual void SetIntegerParamToUnsupportedValue(MPSolverParameters::IntegerParam param, int value)
int branching_priority() const
Advanced usage: Certain MIP solvers (e.g.
void Clear()
Clears the offset, all variables and coefficients, and the optimization direction.
IntegerParam
Enumeration of parameters that take integer or categorical values.
This mathematical programming (MP) solver class is the main class though which users build and solve ...
void SetCommonParameters(const MPSolverParameters &param)
const std::vector< MPVariable * > & variables() const
Returns the array of variables handled by the MPSolver.
void SetLB(double lb)
Sets the lower bound.
double reduced_cost() const
Advanced usage: returns the reduced cost of the variable in the current solution (only available for ...
void SetBounds(double lb, double ub)
Sets both the lower and upper bounds.
int64 iterations() const
Returns the number of simplex iterations.
const absl::flat_hash_map< const MPVariable *, double > & terms() const
Returns a map from variables to their coefficients in the constraint.
MPVariable * LookupVariableOrNull(const std::string &var_name) const
Looks up a variable by name, and returns nullptr if it does not exist.
virtual void Write(const std::string &filename)
void SetHint(std::vector< std::pair< const MPVariable *, double > > hint)
Sets a hint for solution.
the model is trivially invalid (NaN coefficients, etc).
void MakeBoolVarArray(int nb, const std::string &name, std::vector< MPVariable * > *vars)
Creates an array of boolean variables.
MPSolver(const std::string &name, OptimizationProblemType problem_type)
Create a solver with the given name and underlying solver backend.
virtual double best_objective_bound() const =0
void set_is_lazy(bool laziness)
Advanced usage: sets the constraint "laziness".
An expression of the form:
Definition: linear_expr.h:180
virtual void SetUnsupportedIntegerParam(MPSolverParameters::IntegerParam param)
Mixed integer Programming Solver using Coin CBC.
virtual MPSolver::ResultStatus Solve(const MPSolverParameters &param)=0
const std::string & name() const
Returns the name of the variable.
bool is_lazy() const
Advanced usage: returns true if the constraint is "lazy" (see below).
static bool ParseSolverType(absl::string_view solver, OptimizationProblemType *type)
Parses the name of the solver.
double offset() const
Gets the constant term in the objective.
const MPObjective & Objective() const
Returns the objective object.
void set_solution_value(double value)
void SetCoefficient(const MPVariable *const var, double coeff)
Sets the coefficient of the variable in the objective.
void SetOptimizationDirection(bool maximize)
Sets the optimization direction (maximize: true or minimize: false).
bool variable_is_extracted(int var_index) const
virtual bool AddIndicatorConstraint(MPConstraint *const ct)
bool constraint_is_extracted(int ct_index) const
IncrementalityValues
Advanced usage: Incrementality options.
int index() const
Returns the index of the constraint in the MPSolver::constraints_.
void SetStartingLpBasis(const std::vector< MPSolver::BasisStatus > &variable_statuses, const std::vector< MPSolver::BasisStatus > &constraint_statuses)
Advanced usage: Incrementality.
Reuse results from previous solve as much as the underlying solver allows.
bool ExportModelAsMpsFormat(bool fixed_format, bool obfuscate, std::string *model_str) const
void SetBranchingPriority(int priority)
MPVariable * MakeIntVar(double lb, double ub, const std::string &name)
Creates an integer variable.
virtual void SetCoefficient(MPConstraint *const constraint, const MPVariable *const variable, double new_value, double old_value)=0
void Clear()
Clears the objective (including the optimization direction), all variables and constraints.
virtual void SetScalingMode(int value)=0
constexpr double kDefaultPrimalTolerance
int NumVariables() const
Returns the number of variables.
double dual_value() const
Advanced usage: returns the dual value of the constraint in the current solution (only available for ...
virtual void SetDualTolerance(double value)=0
void SetCoefficient(const MPVariable *const var, double coeff)
Sets the coefficient of the variable on the constraint.
virtual std::string SolverVersion() const =0
static void SolveWithProto(const MPModelRequest &model_request, MPSolutionResponse *response)
Solves the model encoded by a MPModelRequest protocol buffer and fills the solution encoded as a MPSo...
MPSolver::ResultStatus result_status() const
virtual std::string ValidFileExtensionForParameterFile() const
PresolveValues
For each categorical parameter, enumeration of possible values.
const MPVariable * indicator_variable() const
MPObjective * MutableObjective()
Returns the mutable objective object.
void ExportModelToProto(MPModelProto *output_model) const
Exports model to protocol buffer.
void OptimizeLinearExpr(const LinearExpr &linear_expr, bool is_maximization)
Resets the current objective to take the value of linear_expr, and sets the objective direction to ma...
virtual void SetObjectiveCoefficient(const MPVariable *const variable, double coefficient)=0
int GetIntegerParam(MPSolverParameters::IntegerParam param) const
Returns the value of an integer parameter.
void SetMaximization()
Sets the optimization direction to maximize.
void SetDoubleParamToUnsupportedValue(MPSolverParameters::DoubleParam param, double value)
bool SetSolverSpecificParametersAsString(const std::string &parameters)
Advanced usage: pass solver specific parameters in text format.
Mixed integer Programming Solver using SCIP.
static const IncrementalityValues kDefaultIncrementality
virtual int64 nodes() const =0
ABSL_MUST_USE_RESULT bool NextSolution()
Some solvers (MIP only, not LP) can produce multiple solutions to the problem.
void MakeIntVarArray(int nb, double lb, double ub, const std::string &name, std::vector< MPVariable * > *vars)
Creates an array of integer variables.
virtual void ClearConstraint(MPConstraint *const constraint)=0
void Write(const std::string &file_name)
Writes the model using the solver internal write function.
MPSolver::BasisStatus basis_status() const
Advanced usage: returns the basis status of the variable in the current solution (only available for ...
virtual OptimizationProblemType ProblemType() const
Returns the optimization problem type set at construction.
void SuppressOutput()
Suppress output.
void Clear()
Clears all variables and coefficients. Does not clear the bounds.
void set_constraint_as_extracted(int ct_index, bool extracted)
void SetTimeLimit(absl::Duration time_limit)
MPSolverResponseStatus LoadModelFromProtoWithUniqueNamesOrDie(const MPModelProto &input_model, std::string *error_message)
Loads model from protocol buffer.
static bool SupportsProblemType(OptimizationProblemType problem_type)
Whether the given problem type is supported (this will depend on the targets that you linked).
double ComputeExactConditionNumber() const
Advanced usage: computes the exact condition number of the current scaled basis: L1norm(B) * L1norm(i...
bool minimization() const
Is the optimization direction set to minimize?
virtual void SetOptimizationDirection(bool maximize)=0
void AddLinearExpr(const LinearExpr &linear_expr)
Adds linear_expr to the current objective, does not change the direction.
void SetMinimization()
Sets the optimization direction to minimize.
void MinimizeLinearExpr(const LinearExpr &linear_expr)
Resets the current objective to minimize linear_expr.
std::ostream & operator<<(std::ostream &os, MPSolver::OptimizationProblemType optimization_problem_type)
void MakeNumVarArray(int nb, double lb, double ub, const std::string &name, std::vector< MPVariable * > *vars)
Creates an array of continuous variables.
virtual bool CheckBestObjectiveBoundExists() const
LinearExpr models a quantity that is linear in the decision variables (MPVariable) of an optimization...
Definition: linear_expr.h:110
bool VerifySolution(double tolerance, bool log_errors) const
Advanced usage: Verifies the correctness of the solution.
void ResetIntegerParam(MPSolverParameters::IntegerParam param)
Sets an integer parameter to its default value (default value defined in MPSolverParameters if it exi...
virtual bool SetSolverSpecificParametersAsString(const std::string &parameters)
int64 nodes() const
Returns the number of branch-and-bound nodes evaluated during the solve.
Linear Programming solver using GLOP (Recommended solver).
static double infinity()
Infinity.
bool OwnsVariable(const MPVariable *var) const
virtual void AddVariable(MPVariable *const var)=0
void MakeVarArray(int nb, double lb, double ub, bool integer, const std::string &name_prefix, std::vector< MPVariable * > *vars)
Creates an array of variables.
virtual void SetVariableBounds(int index, double lb, double ub)=0
void SetLB(double lb)
Sets the lower bound.
void SetMIPParameters(const MPSolverParameters &param)
void SetInteger(bool integer)
Sets the integrality requirement of the variable.
virtual void SetPrimalTolerance(double value)=0
void set_time_limit(int64 time_limit_milliseconds)
ResultStatus Solve()
Solves the problem using default parameter values.
MPConstraint * MakeRowConstraint()
Creates a constraint with -infinity and +infinity bounds.
void SetDoubleParam(MPSolverParameters::DoubleParam param, double value)
Sets a double parameter to a specific value.
OptimizationProblemType
The type of problems (LP or MIP) that will be solved and the underlying solver (GLOP,...
const std::string & Name() const
Returns the name of the model set at construction.
MPSolverParameters()
The constructor sets all parameters to their default value.
const absl::string_view ToString(MPSolver::OptimizationProblemType optimization_problem_type)
BasisStatus
Advanced usage: possible basis status values for a variable and the slack variable of a linear constr...
MPSolver::BasisStatus basis_status() const
Advanced usage: returns the basis status of the constraint.
ResultStatus
The status of solving the problem.
Advanced usage: tolerance for primal feasibility of basic solutions.
virtual void SetVariableInteger(int index, bool integer)=0
double BestBound() const
Returns the best objective bound.
const absl::flat_hash_map< const MPVariable *, double > & terms() const
Returns a map from variables to their coefficients in the objective.
This file allows you to write natural code (like a mathematical equation) to model optimization probl...
virtual MPSolver::BasisStatus row_status(int constraint_index) const =0
double ub() const
Returns the upper bound.
This class stores parameter settings for LP and MIP solvers.
const std::string & name() const
Returns the name of the constraint.
The class for constraints of a Mathematical Programming (MP) model.
virtual void BranchingPriorityChangedForVariable(int var_index)
int NumConstraints() const
Returns the number of constraints.
void set_dual_value(double dual_value)
double unrounded_solution_value() const
Advanced usage: unrounded solution value.
std::vector< double > ComputeConstraintActivities() const
Advanced usage: compute the "activities" of all constraints, which are the sums of their linear terms...
util::Status SetNumThreads(int num_threads)
Sets the number of threads to use by the underlying solver.
ScalingValues
Advanced usage: Scaling options.
std::string AbslUnparseFlag(MPSolver::OptimizationProblemType solver_type)
bool AbslParseFlag(absl::string_view text, MPSolver::OptimizationProblemType *solver_type, std::string *error)
abnormal, i.e., error of some kind.
MPVariable(int index, double lb, double ub, bool integer, const std::string &name, MPSolverInterface *const interface_in)
void SetUB(double ub)
Sets the upper bound.
bool ExportModelAsLpFormat(bool obfuscate, std::string *model_str) const
Shortcuts to the homonymous MPModelProtoExporter methods, via exporting to a MPModelProto with Export...
void Reset()
Sets all parameters to their default value.
absl::Duration DurationSinceConstruction() const
void ResetDoubleParam(MPSolverParameters::DoubleParam param)
Sets a double parameter to its default value (default value defined in MPSolverParameters if it exist...
MPSolverResponseStatus LoadModelFromProto(const MPModelProto &input_model, std::string *error_message)
Loads model from protocol buffer.
virtual void AddRowConstraint(MPConstraint *const ct)=0
Linear Programming solver using Coin CBC.
std::string SolverVersion() const
Returns a std::string describing the underlying solver and its version.
virtual double ComputeExactConditionNumber() const
MPVariable * MakeNumVar(double lb, double ub, const std::string &name)
Creates a continuous variable.
MPConstraint(int index, double lb, double ub, const std::string &name, MPSolverInterface *const interface_in)
MPSolverInterface(MPSolver *const solver)
void SetUnsupportedDoubleParam(MPSolverParameters::DoubleParam param)
MPVariable * MakeBoolVar(const std::string &name)
Creates a boolean variable.
bool maximization() const
Is the optimization direction set to maximize?
int GetNumThreads() const
Returns the number of threads to be used during solve.
MPConstraint * LookupConstraintOrNull(const std::string &constraint_name) const
Looks up a constraint by name, and returns nullptr if it does not exist.
virtual void SetObjectiveOffset(double value)=0
The class for variables of a Mathematical Programming (MP) model.
virtual bool ReadParameterFile(const std::string &filename)
void SetBounds(double lb, double ub)
Sets both the lower and upper bounds.
Advanced usage: tolerance for dual feasibility of basic solutions.
virtual void SetPresolveMode(int value)=0
virtual void SetParameters(const MPSolverParameters &param)=0
double ub() const
Returns the upper bound.
MPVariable * MakeVar(double lb, double ub, bool integer, const std::string &name)
Creates a variable with the given bounds, integrality requirement and name.
void MaximizeLinearExpr(const LinearExpr &linear_expr)
Resets the current objective to maximize linear_expr.
util::Status ClampSolutionWithinBounds()
Resets values of out of bound variables to the corresponding bound and returns an error if any of the...
feasible, or stopped by limit.
static const PresolveValues kDefaultPresolve
bool InterruptSolve()
Interrupts the Solve() execution to terminate processing if possible.
Advanced usage: enable or disable matrix scaling.
double GetDoubleParam(MPSolverParameters::DoubleParam param) const
Returns the value of a double parameter.
void SetUB(double ub)
Sets the upper bound.
virtual bool CheckSolutionExists() const
double lb() const
Returns the lower bound.
std::string GetSolverSpecificParametersAsString() const
void FillSolutionResponseProto(MPSolutionResponse *response) const
Encodes the current solution in a solution response protocol buffer.
const std::vector< MPConstraint * > & constraints() const
Returns the array of constraints handled by the MPSolver.
DoubleParam
Enumeration of parameters that take continuous values.
virtual int64 iterations() const =0
bool OutputIsEnabled() const
Controls (or queries) the amount of output produced by the underlying solver.
double lb() const
Returns the lower bound.
double solution_value() const
Returns the value of the variable in the current solution.
void set_reduced_cost(double reduced_cost)
void SetOffset(double value)
Sets the constant term in the objective.
absl::Duration TimeLimit() const
virtual void SetRelativeMipGap(double value)=0
int index() const
Returns the index of the variable in the MPSolver::variables_.
A class to express a linear objective.
virtual void SetConstraintBounds(int index, double lb, double ub)=0
virtual bool IsContinuous() const =0
virtual void SetLpAlgorithm(int value)=0
virtual void SetStartingLpBasis(const std::vector< MPSolver::BasisStatus > &variable_statuses, const std::vector< MPSolver::BasisStatus > &constraint_statuses)
void Reset()
Advanced usage: resets extracted model to solve from scratch.
double Value() const
Returns the objective value of the best solution found so far.