Skip to content

Commit

Permalink
linear_solver: Export from google3
Browse files Browse the repository at this point in the history
  • Loading branch information
Mizux committed Oct 30, 2023
1 parent a581d5b commit 604313b
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 20 deletions.
39 changes: 36 additions & 3 deletions ortools/linear_solver/linear_solver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -38,18 +44,24 @@
#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/singleton.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,
Expand Down Expand Up @@ -617,7 +629,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) {
Expand Down Expand Up @@ -1022,6 +1034,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
Expand All @@ -1033,7 +1047,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())
Expand Down Expand Up @@ -2311,4 +2325,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
41 changes: 24 additions & 17 deletions ortools/linear_solver/linear_solver.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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<<(
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}
Expand All @@ -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.
Expand All @@ -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.
Expand Down Expand Up @@ -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.";
}

Expand All @@ -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.";
}

Expand Down

0 comments on commit 604313b

Please sign in to comment.