math_opt: backport from main
This commit is contained in:
@@ -11,6 +11,9 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
load("@rules_cc//cc:cc_library.bzl", "cc_library")
|
||||
load("@rules_cc//cc:cc_test.bzl", "cc_test")
|
||||
|
||||
package(default_visibility = ["//ortools/math_opt:__subpackages__"])
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
load("@rules_cc//cc:cc_library.bzl", "cc_library")
|
||||
load("@rules_cc//cc:cc_test.bzl", "cc_test")
|
||||
|
||||
package(default_visibility = ["//ortools/math_opt:__subpackages__"])
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
load("@rules_cc//cc:cc_library.bzl", "cc_library")
|
||||
load("@rules_cc//cc:cc_test.bzl", "cc_test")
|
||||
|
||||
package(default_visibility = ["//ortools/math_opt:__subpackages__"])
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
load("@rules_cc//cc:cc_library.bzl", "cc_library")
|
||||
load("@rules_cc//cc:cc_test.bzl", "cc_test")
|
||||
|
||||
package(default_visibility = ["//ortools/math_opt:__subpackages__"])
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
load("@rules_cc//cc:cc_library.bzl", "cc_library")
|
||||
load("@rules_cc//cc:cc_test.bzl", "cc_test")
|
||||
|
||||
package(default_visibility = ["//ortools/math_opt:__subpackages__"])
|
||||
|
||||
cc_library(
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
load("@rules_cc//cc:cc_library.bzl", "cc_library")
|
||||
|
||||
package(default_visibility = ["//ortools/math_opt:__subpackages__"])
|
||||
|
||||
cc_library(
|
||||
@@ -62,9 +64,9 @@ cc_library(
|
||||
deps = [
|
||||
"//ortools/base:linked_hash_map",
|
||||
"//ortools/base:status_macros",
|
||||
"//ortools/base:string_view_migration",
|
||||
"//ortools/math_opt:model_cc_proto",
|
||||
"//ortools/math_opt:model_update_cc_proto",
|
||||
"//ortools/base:string_view_migration",
|
||||
"@abseil-cpp//absl/algorithm:container",
|
||||
"@abseil-cpp//absl/container:flat_hash_map",
|
||||
"@abseil-cpp//absl/log:check",
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
load("@rules_cc//cc:cc_library.bzl", "cc_library")
|
||||
|
||||
# External users should depend only on ":math_opt" and include
|
||||
# "math_opt.h". Hence other libraries are private.
|
||||
package(default_visibility = [
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
load("@pip_deps//:requirements.bzl", "requirement")
|
||||
load("@pybind11_bazel//:build_defs.bzl", "pybind_extension")
|
||||
load("@rules_python//python:py_library.bzl", "py_library")
|
||||
load("@rules_python//python:py_test.bzl", "py_test")
|
||||
load("@rules_python//python:py_test.bzl", "py_test")
|
||||
|
||||
genrule(
|
||||
name = "generated_enums",
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
load("@pip_deps//:requirements.bzl", "requirement")
|
||||
load("@rules_python//python:py_library.bzl", "py_library")
|
||||
load("@rules_python//python:py_test.bzl", "py_test")
|
||||
load("@rules_python//python:py_test.bzl", "py_test")
|
||||
|
||||
# External users should depend only on ":mathopt" and import "mathopt".
|
||||
# Hence other libraries are private.
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
load("@pip_deps//:requirements.bzl", "requirement")
|
||||
load("@rules_python//python:defs.bzl", "py_library")
|
||||
load("@rules_python//python:py_library.bzl", "py_library")
|
||||
|
||||
py_library(
|
||||
name = "remote_http_solve",
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
load("@pip_deps//:requirements.bzl", "requirement")
|
||||
load("@rules_python//python:py_library.bzl", "py_library")
|
||||
load("@rules_python//python:py_test.bzl", "py_test")
|
||||
load("@rules_python//python:py_test.bzl", "py_test")
|
||||
|
||||
package(default_visibility = ["//ortools/math_opt:__subpackages__"])
|
||||
|
||||
|
||||
@@ -24,21 +24,25 @@ namespace operations_research::math_opt {
|
||||
|
||||
using ::testing::status::IsOkAndHolds;
|
||||
|
||||
#if defined(USE_SCIP)
|
||||
TEST(SmallModelTest, Integer) {
|
||||
const std::unique_ptr<const Model> model = SmallModel(/*integer=*/true);
|
||||
EXPECT_THAT(Solve(*model, SolverType::kGscip), IsOkAndHolds(IsOptimal(9.0)));
|
||||
}
|
||||
#endif // USE_SCIP
|
||||
|
||||
TEST(SmallModelTest, Continuous) {
|
||||
const std::unique_ptr<const Model> model = SmallModel(/*integer=*/false);
|
||||
EXPECT_THAT(Solve(*model, SolverType::kGlop), IsOkAndHolds(IsOptimal(12.0)));
|
||||
}
|
||||
|
||||
#if defined(USE_SCIP)
|
||||
TEST(DenseIndependentSetTest, Integer) {
|
||||
const std::unique_ptr<const Model> model =
|
||||
DenseIndependentSet(/*integer=*/true);
|
||||
EXPECT_THAT(Solve(*model, SolverType::kGscip), IsOkAndHolds(IsOptimal(7.0)));
|
||||
}
|
||||
#endif // USE_SCIP
|
||||
|
||||
TEST(DenseIndependentSetTest, Continuous) {
|
||||
const std::unique_ptr<const Model> model =
|
||||
@@ -47,6 +51,7 @@ TEST(DenseIndependentSetTest, Continuous) {
|
||||
IsOkAndHolds(IsOptimal(10.0 * (5 + 4 + 3) / 2.0)));
|
||||
}
|
||||
|
||||
#if defined(USE_SCIP)
|
||||
TEST(DenseIndependentSetHint5Test, HintIsFeasibleWithObjective5) {
|
||||
const std::unique_ptr<Model> model = DenseIndependentSet(/*integer=*/true, 5);
|
||||
ModelSolveParameters model_params;
|
||||
@@ -58,12 +63,15 @@ TEST(DenseIndependentSetHint5Test, HintIsFeasibleWithObjective5) {
|
||||
}
|
||||
EXPECT_THAT(Solve(*model, SolverType::kGscip), IsOkAndHolds(IsOptimal(5.0)));
|
||||
}
|
||||
#endif // USE_SCIP
|
||||
|
||||
#if defined(USE_SCIP)
|
||||
TEST(IndependentSetCompleteGraphTest, Integer) {
|
||||
const std::unique_ptr<const Model> model =
|
||||
IndependentSetCompleteGraph(/*integer=*/true);
|
||||
EXPECT_THAT(Solve(*model, SolverType::kGscip), IsOkAndHolds(IsOptimal(1.0)));
|
||||
}
|
||||
#endif // USE_SCIP
|
||||
|
||||
TEST(IndependentSetCompleteGraphTest, Continuous) {
|
||||
const std::unique_ptr<const Model> model =
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
// Unimplemented features:
|
||||
// * Quadratic objective
|
||||
// * TODO(b/272767311): initial basis, more precise returned basis.
|
||||
// * Starting solution
|
||||
// * TODO(b/271104776): Returning rays
|
||||
|
||||
#include "ortools/math_opt/solvers/highs_solver.h"
|
||||
@@ -925,6 +924,21 @@ absl::StatusOr<SolveResultProto> HighsSolver::Solve(
|
||||
return absl::OkStatus();
|
||||
};
|
||||
|
||||
if (model_parameters.solution_hints_size() > 0) {
|
||||
// Take the first solution hint and set the solution.
|
||||
const SolutionHintProto& hint = model_parameters.solution_hints(0);
|
||||
HighsInt num_entries = hint.variable_values().ids_size();
|
||||
std::vector<HighsInt> index(num_entries);
|
||||
std::vector<double> value(num_entries);
|
||||
size_t i = 0;
|
||||
for (const auto [id, val] : MakeView(hint.variable_values())) {
|
||||
index[i] = variable_data_.at(id).index;
|
||||
value[i] = val;
|
||||
++i;
|
||||
}
|
||||
RETURN_IF_ERROR(ToStatus(highs_->setSolution(num_entries, index.data(), value.data())));
|
||||
}
|
||||
|
||||
RETURN_IF_ERROR(ListInvertedBounds().ToStatus());
|
||||
// TODO(b/271595607): delete this code once we upgrade HiGHS, if HiGHS does
|
||||
// return a proper infeasibility status for models with empty integer bounds.
|
||||
|
||||
@@ -162,11 +162,20 @@ INSTANTIATE_TEST_SUITE_P(HighsLpModelSolveParametersTest,
|
||||
Values(LpModelSolveParametersTestParameters(
|
||||
SolverType::kHighs, /*exact_zeros=*/true,
|
||||
/*supports_duals=*/true,
|
||||
/*supports_primal_only_warm_starts=*/false)));
|
||||
/*supports_primal_only_warm_starts=*/true)));
|
||||
|
||||
// MIP hint appears to be supported by Highs::setSolution, this is not yet
|
||||
// implemented.
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MipSolutionHintTest);
|
||||
SolutionHintTestParams MakeHighsSolutionHintParams() {
|
||||
SolveParameters solve_params;
|
||||
solve_params.presolve = Emphasis::kOff;
|
||||
(*solve_params.highs.mutable_int_options())["mip_max_nodes"] = 0;
|
||||
std::string hint_message_regex =
|
||||
"Attempting to find feasible solution by "
|
||||
"solving MIP for user-supplied values of";
|
||||
return SolutionHintTestParams(SolverType::kHighs, solve_params, std::nullopt,
|
||||
hint_message_regex);
|
||||
}
|
||||
INSTANTIATE_TEST_SUITE_P(HighsSolutionHintTest, MipSolutionHintTest,
|
||||
Values(MakeHighsSolutionHintParams()));
|
||||
|
||||
// HiGHS does not support branching priority.
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BranchPrioritiesTest);
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
load("@rules_cc//cc:cc_library.bzl", "cc_library")
|
||||
|
||||
# Code specific to XPRESS used in xpress_solver.cc.
|
||||
package(default_visibility = ["//ortools/math_opt/solvers:__subpackages__"])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user