linear_solver: Export from google3

This commit is contained in:
Corentin Le Molgat
2023-10-30 18:10:43 +01:00
committed by Mizux Seiha
parent 0ac38b751d
commit 3d41e4f748
2 changed files with 59 additions and 20 deletions

View File

@@ -23,12 +23,18 @@
#include <cstddef>
#include <cstdint>
#include <functional>
#include <iostream>
#include <limits>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include "absl/base/const_init.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/flags/flag.h"
#include "absl/log/check.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/ascii.h"
@@ -38,18 +44,23 @@
#include "absl/strings/str_replace.h"
#include "absl/synchronization/mutex.h"
#include "absl/synchronization/notification.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "google/protobuf/text_format.h"
#include "ortools/base/accurate_sum.h"
#include "ortools/base/commandlineflags.h"
#include "ortools/base/logging.h"
#include "ortools/base/map_util.h"
#include "ortools/base/stl_util.h"
#include "ortools/base/threadpool.h"
#include "ortools/linear_solver/linear_expr.h"
#include "ortools/linear_solver/linear_solver.pb.h"
#include "ortools/linear_solver/linear_solver_callback.h"
#include "ortools/linear_solver/model_exporter.h"
#include "ortools/linear_solver/model_validator.h"
#include "ortools/port/file.h"
#include "ortools/port/proto_utils.h"
#include "ortools/util/fp_utils.h"
#include "ortools/util/lazy_mutable_copy.h"
#include "ortools/util/time_limit.h"
ABSL_FLAG(bool, verify_solution, false,
@@ -617,7 +628,7 @@ bool MPSolver::ParseSolverType(absl::string_view solver_id,
return false;
}
const absl::string_view ToString(
absl::string_view ToString(
MPSolver::OptimizationProblemType optimization_problem_type) {
for (const auto& named_solver : kOptimizationProblemTypeNames) {
if (named_solver.problem_type == optimization_problem_type) {
@@ -1022,6 +1033,8 @@ void MPSolver::SolveWithProto(const MPModelRequest& model_request,
model_request.solver_type()));
if (model_request.enable_internal_solver_output()) {
solver.EnableOutput();
std::cout << "MPModelRequest info:\n"
<< GetMPModelRequestLoggingInfo(model_request) << std::endl;
}
// If interruption support is not required, we don't need access to the
@@ -1033,7 +1046,7 @@ void MPSolver::SolveWithProto(const MPModelRequest& model_request,
return;
}
const absl::optional<LazyMutableCopy<MPModelProto>> optional_model =
const std::optional<LazyMutableCopy<MPModelProto>> optional_model =
ExtractValidMPModelOrPopulateResponseStatus(model_request, response);
if (!optional_model) {
LOG_IF(WARNING, model_request.enable_internal_solver_output())
@@ -2311,4 +2324,23 @@ int MPSolverParameters::GetIntegerParam(
}
}
// static
std::string MPSolver::GetMPModelRequestLoggingInfo(
const MPModelRequest& request) {
std::string out;
#if !defined(__PORTABLE_PLATFORM__)
MPModelRequest abbreviated_request;
abbreviated_request = request;
abbreviated_request.clear_model();
abbreviated_request.clear_model_delta();
google::protobuf::TextFormat::PrintToString(abbreviated_request, &out);
#else // __PORTABLE_PLATFORM__
out = "<Info unavailable because: __PORTABLE_PLATFORM__>\n";
#endif // __PORTABLE_PLATFORM__
if (request.model().has_name()) {
absl::StrAppendFormat(&out, "model_name: '%s'\n", request.model().name());
}
return out;
}
} // namespace operations_research

View File

@@ -212,14 +212,6 @@ class MPSolver {
SCIP_MIXED_INTEGER_PROGRAMMING = 3,
GLPK_MIXED_INTEGER_PROGRAMMING = 4,
CBC_MIXED_INTEGER_PROGRAMMING = 5,
// Commercial software (need license).
GUROBI_LINEAR_PROGRAMMING = 6,
GUROBI_MIXED_INTEGER_PROGRAMMING = 7,
CPLEX_LINEAR_PROGRAMMING = 10,
CPLEX_MIXED_INTEGER_PROGRAMMING = 11,
XPRESS_LINEAR_PROGRAMMING = 101,
XPRESS_MIXED_INTEGER_PROGRAMMING = 102,
HIGHS_MIXED_INTEGER_PROGRAMMING = 16,
// Boolean optimization problem (requires only integer variables and works
@@ -235,6 +227,16 @@ class MPSolver {
// Dedicated knapsack solvers.
KNAPSACK_MIXED_INTEGER_PROGRAMMING = 13,
// Commercial software (need license).
GUROBI_LINEAR_PROGRAMMING = 6,
GUROBI_MIXED_INTEGER_PROGRAMMING = 7,
CPLEX_LINEAR_PROGRAMMING = 10,
CPLEX_MIXED_INTEGER_PROGRAMMING = 11,
XPRESS_LINEAR_PROGRAMMING = 101,
XPRESS_MIXED_INTEGER_PROGRAMMING = 102,
COPT_LINEAR_PROGRAMMING = 103,
COPT_MIXED_INTEGER_PROGRAMMING = 104,
};
/// Create a solver with the given name and underlying solver backend.
@@ -693,6 +695,11 @@ class MPSolver {
*/
void SetHint(std::vector<std::pair<const MPVariable*, double> > hint);
// Gives some brief (a few lines, at most) human-readable information about
// the given request, suitable for debug logging.
static std::string GetMPModelRequestLoggingInfo(
const MPModelRequest& request);
/**
* Advanced usage: possible basis status values for a variable and the slack
* variable of a linear constraint.
@@ -963,7 +970,7 @@ inline bool SolverTypeIsMip(MPSolver::OptimizationProblemType solver_type) {
return SolverTypeIsMip(static_cast<MPModelRequest::SolverType>(solver_type));
}
const absl::string_view ToString(
absl::string_view ToString(
MPSolver::OptimizationProblemType optimization_problem_type);
inline std::ostream& operator<<(
@@ -1642,10 +1649,10 @@ class MPSolverInterface {
// underlying solver (possibly because interrupt != nullptr), in which case
// the user should fall back to using MPSolver.
virtual std::optional<MPSolutionResponse> DirectlySolveProto(
const MPModelRequest& request,
const MPModelRequest& /*request*/,
// `interrupt` is non-const because the internal
// solver may set it to true itself, in some cases.
std::atomic<bool>* interrupt) {
std::atomic<bool>* /*interrupt*/) {
return std::nullopt;
}
@@ -1674,7 +1681,7 @@ class MPSolverInterface {
// Adds an indicator constraint. Returns true if the feature is supported by
// the underlying solver.
virtual bool AddIndicatorConstraint(MPConstraint* const ct) {
virtual bool AddIndicatorConstraint(MPConstraint* const /*ct*/) {
LOG(ERROR) << "Solver doesn't support indicator constraints.";
return false;
}
@@ -1700,7 +1707,7 @@ class MPSolverInterface {
// Clears the objective from all its terms.
virtual void ClearObjective() = 0;
virtual void BranchingPriorityChangedForVariable(int var_index) {}
virtual void BranchingPriorityChangedForVariable(int /*var_index*/) {}
// ------ Query statistics on the solution and the solve ------
// Returns the number of simplex iterations. The problem must be discrete,
// otherwise it crashes, or returns kUnknownNumberOfIterations in NDEBUG mode.
@@ -1721,7 +1728,7 @@ class MPSolverInterface {
// 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.
// If it isn't, it crashes in NDEBUG, and returns false otherwise.
bool CheckSolutionIsSynchronized() const;
// Checks whether a feasible solution exists. The behavior is similar to
// CheckSolutionIsSynchronized() above.
@@ -1783,8 +1790,8 @@ class MPSolverInterface {
// See MPSolver::SetStartingLpBasis().
virtual void SetStartingLpBasis(
const std::vector<MPSolver::BasisStatus>& variable_statuses,
const std::vector<MPSolver::BasisStatus>& constraint_statuses) {
const std::vector<MPSolver::BasisStatus>& /*variable_statuses*/,
const std::vector<MPSolver::BasisStatus>& /*constraint_statuses*/) {
LOG(FATAL) << "Not supported by this solver.";
}
@@ -1796,7 +1803,7 @@ class MPSolverInterface {
virtual bool NextSolution() { return false; }
// See MPSolver::SetCallback() for details.
virtual void SetCallback(MPCallback* mp_callback) {
virtual void SetCallback(MPCallback* /*mp_callback*/) {
LOG(FATAL) << "Callbacks not supported for this solver.";
}