backport from main:
* bump abseil to 20250814 * bump protobuf to v32.0 * cmake: add ccache auto support * backport flatzinc, math_opt and sat update
This commit is contained in:
@@ -395,7 +395,7 @@ MPSolver::ResultStatus CBCInterface::Solve(const MPSolverParameters& param) {
|
||||
|
||||
VLOG(1) << "cbc result status: " << tmp_status;
|
||||
/* Final status of problem
|
||||
(info from cbc/.../CbcSolver.cpp,
|
||||
(info from third_party/cbc/.../CbcSolver.cpp,
|
||||
See http://cs?q="cbc+status"+file:CbcSolver.cpp)
|
||||
Some of these can be found out by is...... functions
|
||||
-1 before branchAndBound
|
||||
|
||||
@@ -11,9 +11,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// This .i file is only used in the open-source export of
|
||||
// util/operations_research (github or-tools)
|
||||
//
|
||||
// It exposes the linear programming and integer programming solver.
|
||||
//
|
||||
// The C# API is quite different from the C++ API; mostly because it
|
||||
|
||||
@@ -168,7 +168,7 @@ class GurobiInterface : public MPSolverInterface {
|
||||
}
|
||||
|
||||
bool InterruptSolve() override {
|
||||
const absl::MutexLock lock(&hold_interruptions_mutex_);
|
||||
const absl::MutexLock lock(hold_interruptions_mutex_);
|
||||
if (model_ != nullptr) GRBterminate(model_);
|
||||
return true;
|
||||
}
|
||||
@@ -663,7 +663,7 @@ GurobiInterface::~GurobiInterface() {
|
||||
|
||||
void GurobiInterface::Reset() {
|
||||
// We hold calls to GRBterminate() until the new model_ is ready.
|
||||
const absl::MutexLock lock(&hold_interruptions_mutex_);
|
||||
const absl::MutexLock lock(hold_interruptions_mutex_);
|
||||
|
||||
GRBmodel* old_model = model_;
|
||||
CheckedGurobiCall(GRBnewmodel(global_env_, &model_, solver_->name_.c_str(),
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -102,6 +103,7 @@ class HighsInterface : public MPSolverInterface {
|
||||
void NonIncrementalChange();
|
||||
|
||||
const bool solve_as_a_mip_;
|
||||
std::optional<HighsSolveInfo> solve_info_;
|
||||
};
|
||||
|
||||
HighsInterface::HighsInterface(MPSolver* const solver, bool solve_as_a_mip)
|
||||
@@ -140,8 +142,9 @@ MPSolver::ResultStatus HighsInterface::Solve(const MPSolverParameters& param) {
|
||||
}
|
||||
|
||||
// Set parameters.
|
||||
solve_info_ = HighsSolveInfo();
|
||||
absl::StatusOr<MPSolutionResponse> response =
|
||||
HighsSolveProto(std::move(request));
|
||||
HighsSolveProto(std::move(request), &*solve_info_);
|
||||
|
||||
if (!response.ok()) {
|
||||
LOG(ERROR) << "Unexpected error solving with Highs: " << response.status();
|
||||
@@ -163,7 +166,10 @@ MPSolver::ResultStatus HighsInterface::Solve(const MPSolverParameters& param) {
|
||||
return result_status_;
|
||||
}
|
||||
|
||||
void HighsInterface::Reset() { ResetExtractionInformation(); }
|
||||
void HighsInterface::Reset() {
|
||||
ResetExtractionInformation();
|
||||
solve_info_.reset();
|
||||
}
|
||||
|
||||
void HighsInterface::SetOptimizationDirection(bool maximize) {
|
||||
NonIncrementalChange();
|
||||
@@ -215,8 +221,9 @@ int64_t HighsInterface::iterations() const {
|
||||
}
|
||||
|
||||
int64_t HighsInterface::nodes() const {
|
||||
LOG(DFATAL) << "Number of nodes only available for discrete problems";
|
||||
return MPSolverInterface::kUnknownNumberOfNodes;
|
||||
QCHECK(solve_info_.has_value())
|
||||
<< "Number of nodes only available after solve";
|
||||
return solve_info_->mip_node_count;
|
||||
}
|
||||
|
||||
MPSolver::BasisStatus HighsInterface::row_status(int constraint_index) const {
|
||||
|
||||
@@ -15,16 +15,16 @@
|
||||
|
||||
load("@contrib_rules_jvm//java:defs.bzl", "java_junit5_test")
|
||||
load("@rules_jvm_external//:defs.bzl", "artifact")
|
||||
load("//bazel:swig_java.bzl", "ortools_java_wrap_cc")
|
||||
load("//bazel:swig_java.bzl", "java_wrap_cc")
|
||||
|
||||
ortools_java_wrap_cc(
|
||||
java_wrap_cc(
|
||||
name = "modelbuilder",
|
||||
src = "modelbuilder.swig",
|
||||
srcs = ["modelbuilder.swig"],
|
||||
module = "modelbuilder",
|
||||
package = "com.google.ortools.modelbuilder",
|
||||
swig_includes = [
|
||||
"//ortools/base:base_swig",
|
||||
"//ortools/util/java:vector_swig",
|
||||
"//ortools/util/java:vector.swig",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
|
||||
@@ -1376,7 +1376,7 @@ absl::Status MPSolver::LoadSolutionFromProto(const MPSolutionResponse& response,
|
||||
|
||||
void MPSolver::Clear() {
|
||||
{
|
||||
absl::MutexLock lock(&global_count_mutex_);
|
||||
absl::MutexLock lock(global_count_mutex_);
|
||||
global_num_variables_ += variables_.size();
|
||||
global_num_constraints_ += constraints_.size();
|
||||
}
|
||||
@@ -1909,13 +1909,13 @@ int64_t MPSolver::global_num_constraints_ = 0;
|
||||
|
||||
// static
|
||||
int64_t MPSolver::global_num_variables() {
|
||||
absl::MutexLock lock(&global_count_mutex_);
|
||||
absl::MutexLock lock(global_count_mutex_);
|
||||
return global_num_variables_;
|
||||
}
|
||||
|
||||
// static
|
||||
int64_t MPSolver::global_num_constraints() {
|
||||
absl::MutexLock lock(&global_count_mutex_);
|
||||
absl::MutexLock lock(global_count_mutex_);
|
||||
return global_num_constraints_;
|
||||
}
|
||||
|
||||
|
||||
@@ -576,7 +576,6 @@ enum MPSolverResponseStatus {
|
||||
// Implementation error: the requested solver implementation is not
|
||||
// available (see MPModelRequest.solver_type).
|
||||
// The linear solver binary was probably not linked with the required library,
|
||||
// eg //ortools/linear_solver:linear_solver_scip for SCIP.
|
||||
MPSOLVER_SOLVER_TYPE_UNAVAILABLE = 0x7;
|
||||
// Some of the selected options were incompatible, e.g. a cancellable solve
|
||||
// was requested via SolverClient::SolveMipRemotely() with an underlying
|
||||
|
||||
@@ -46,7 +46,7 @@ absl::Status SetSolverSpecificParameters(const std::string& parameters,
|
||||
Highs& highs);
|
||||
|
||||
absl::StatusOr<MPSolutionResponse> HighsSolveProto(
|
||||
LazyMutableCopy<MPModelRequest> request) {
|
||||
LazyMutableCopy<MPModelRequest> request, HighsSolveInfo* solve_info) {
|
||||
MPSolutionResponse response;
|
||||
const std::optional<LazyMutableCopy<MPModelProto>> optional_model =
|
||||
GetMPModelOrPopulateResponse(request, &response);
|
||||
@@ -262,6 +262,10 @@ absl::StatusOr<MPSolutionResponse> HighsSolveProto(
|
||||
}
|
||||
}
|
||||
|
||||
if (solve_info != nullptr) {
|
||||
solve_info->mip_node_count = highs.getInfo().mip_node_count;
|
||||
}
|
||||
|
||||
const absl::Duration solving_duration = absl::Now() - time_before;
|
||||
user_timer.Stop();
|
||||
response.mutable_solve_info()->set_solve_wall_time_seconds(
|
||||
|
||||
@@ -14,8 +14,7 @@
|
||||
#ifndef OR_TOOLS_LINEAR_SOLVER_PROTO_SOLVER_HIGHS_PROTO_SOLVER_H_
|
||||
#define OR_TOOLS_LINEAR_SOLVER_PROTO_SOLVER_HIGHS_PROTO_SOLVER_H_
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
#include "absl/status/statusor.h"
|
||||
#include "ortools/linear_solver/linear_solver.pb.h"
|
||||
@@ -23,9 +22,16 @@
|
||||
|
||||
namespace operations_research {
|
||||
|
||||
// Solve the input MIP model with the HIGHS solver.
|
||||
// Information about the Highs solve.
|
||||
struct HighsSolveInfo {
|
||||
int64_t mip_node_count; // The number of nodes generated by the MIP solver.
|
||||
};
|
||||
|
||||
// Solve the input MIP model with the HIGHS solver and fills `solve_info` if
|
||||
// provided.
|
||||
absl::StatusOr<MPSolutionResponse> HighsSolveProto(
|
||||
LazyMutableCopy<MPModelRequest> request);
|
||||
LazyMutableCopy<MPModelRequest> request,
|
||||
HighsSolveInfo* solve_info = nullptr);
|
||||
|
||||
} // namespace operations_research
|
||||
|
||||
|
||||
@@ -58,8 +58,6 @@ def code_sample_py(name):
|
||||
"//ortools/init/python:init",
|
||||
"//ortools/linear_solver/python:model_builder",
|
||||
],
|
||||
python_version = "PY3",
|
||||
srcs_version = "PY3",
|
||||
)
|
||||
|
||||
py_test(
|
||||
@@ -77,8 +75,6 @@ def code_sample_py(name):
|
||||
requirement("numpy"),
|
||||
requirement("pandas"),
|
||||
],
|
||||
python_version = "PY3",
|
||||
srcs_version = "PY3",
|
||||
)
|
||||
|
||||
def code_sample_java(name):
|
||||
|
||||
@@ -166,7 +166,7 @@ ScipSeparationResult RunSeparation(internal::ScipCallbackRunner* runner,
|
||||
CHECK_OK(SCIP_TO_STATUS(SCIPreleaseRow(scip, &row)));
|
||||
// TODO(user): when infeasible is true, it better to have the scip
|
||||
// return status be cutoff instead of cutting plane added (e.g. see
|
||||
// cs/scip/src/scip/cons_knapsack.c). However, as we use
|
||||
// cs/third_party/scip/src/scip/cons_knapsack.c). However, as we use
|
||||
// SCIPaddRow(), it isn't clear this will even happen.
|
||||
if (result != ScipSeparationResult::kLazyConstraintAdded) {
|
||||
// NOTE(user): if we have already found a violated lazy constraint,
|
||||
|
||||
@@ -138,7 +138,7 @@ class SCIPInterface : public MPSolverInterface {
|
||||
}
|
||||
|
||||
bool InterruptSolve() override {
|
||||
const absl::MutexLock lock(&hold_interruptions_mutex_);
|
||||
const absl::MutexLock lock(hold_interruptions_mutex_);
|
||||
if (scip_ == nullptr) {
|
||||
LOG_IF(DFATAL, status_.ok()) << "scip_ is null is unexpected here, since "
|
||||
"status_ did not report any error";
|
||||
@@ -280,7 +280,7 @@ SCIPInterface::~SCIPInterface() { DeleteSCIP(); }
|
||||
|
||||
void SCIPInterface::Reset() {
|
||||
// We hold calls to SCIPinterruptSolve() until the new scip_ is fully built.
|
||||
const absl::MutexLock lock(&hold_interruptions_mutex_);
|
||||
const absl::MutexLock lock(hold_interruptions_mutex_);
|
||||
|
||||
// Remove existing one but keep it alive to copy parameters from it.
|
||||
SCIP* old_scip = DeleteSCIP(/*return_scip=*/true);
|
||||
|
||||
Reference in New Issue
Block a user