diff --git a/CMakeLists.txt b/CMakeLists.txt index 31b38a6d8b..b057b89d75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -209,6 +209,16 @@ if(USE_GLPK) message(STATUS "Build GLPK: ${BUILD_GLPK}") endif() +## HiGHS +# see: https://github.com/ERGO-Code/HiGHS +CMAKE_DEPENDENT_OPTION(USE_HIGHS "Use the HiGHS solver" ON "BUILD_CXX" OFF) +message(STATUS "HiGHS support: ${USE_HIGHS}") +if(USE_HIGHS) + CMAKE_DEPENDENT_OPTION(BUILD_HIGHS "Build the HiGHS dependency Library" OFF + "NOT BUILD_DEPS" ON) + message(STATUS "Build HiGHS: ${BUILD_HIGHS}") +endif() + ## PDLP CMAKE_DEPENDENT_OPTION(USE_PDLP "Use the PDLP solver" ON "BUILD_CXX" OFF) message(STATUS "PDLP support: ${USE_PDLP}") diff --git a/cmake/README.md b/cmake/README.md index f31f1137ea..faa89d125e 100644 --- a/cmake/README.md +++ b/cmake/README.md @@ -113,6 +113,9 @@ below). * COIN-OR Cbc (`BUILD_Cbc`),
note: You can disable the support of COIN-OR solvers (i.e. Cbc and Clp solver) by using `-DUSE_COINOR=OFF` (`ON` by default). +* HIGHS (`BUILD_HIGHS`),
+ note: You can disable the support of HiGHS solver + by using `-DUSE_HIGHS=OFF` (`ON` by default). * SCIP (`BUILD_SCIP`),
note: You can disable the support of SCIP solver by using `-DUSE_SCIP=OFF` (`ON` by default).
@@ -204,6 +207,8 @@ cmake -S. -Bbuild -LH | `BUILD_Cbc` | OFF\* | Static build the Cbc library
**Forced** to ON if `USE_COINOR=ON` **and** `BUILD_DEPS=ON` | | `USE_GLPK` | OFF\* | Enable GLPK support
**Forced** to OFF if `BUILD_CXX=OFF` | | `BUILD_GLPK` | OFF\* | Static build the GLPK libraries
**Forced** to ON if `USE_GLPK=ON` **and** `BUILD_DEPS=ON` | +| `USE_HIGHS` | ON\* | Enable HIGHS support
**Forced** to OFF if `BUILD_CXX=OFF` | +| `BUILD_HIGHS` | OFF\* | Static build the HiGHS libraries
**Forced** to ON if `USE_HIGHS=ON` **and** `BUILD_DEPS=ON` | | `USE_SCIP` | ON\* | Enable SCIP support
**Forced** to OFF if `BUILD_CXX=OFF` | | `BUILD_SCIP` | OFF\* | Static build the SCIP libraries
**Forced** to ON if `USE_SCIP=ON` **and** `BUILD_DEPS=ON` | | `USE_CPLEX` | OFF | Enable CPLEX support | diff --git a/cmake/cpp.cmake b/cmake/cpp.cmake index 5690b223ff..3ec53b6c4a 100644 --- a/cmake/cpp.cmake +++ b/cmake/cpp.cmake @@ -45,6 +45,9 @@ if(USE_GLPK) list(APPEND OR_TOOLS_COMPILE_DEFINITIONS "USE_GLPK") set(GLPK_DIR glpk) endif() +if(USE_HIGHS) + list(APPEND OR_TOOLS_COMPILE_DEFINITIONS "USE_HIGHS") +endif() if(USE_PDLP) list(APPEND OR_TOOLS_COMPILE_DEFINITIONS "USE_PDLP") set(PDLP_DIR pdlp) @@ -157,6 +160,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC ${COINOR_DEPS} $<$:CPLEX::CPLEX> $<$:GLPK::GLPK> + $<$:HIGHS::HIGHS> ${PDLP_DEPS} $<$:libscip> $<$:XPRESS::XPRESS> diff --git a/cmake/dependencies/CMakeLists.txt b/cmake/dependencies/CMakeLists.txt index 654dd6d4c2..e92638a1c5 100644 --- a/cmake/dependencies/CMakeLists.txt +++ b/cmake/dependencies/CMakeLists.txt @@ -190,6 +190,23 @@ if(BUILD_GLPK) message(CHECK_PASS "fetched") endif() +# ############################################################################## +# HiGHS +# ############################################################################## +if(BUILD_HIGHS) + message(CHECK_START "Fetching HiGHS") + list(APPEND CMAKE_MESSAGE_INDENT " ") + set(CI OFF) # disable CI tests + FetchContent_Declare( + highs + GIT_REPOSITORY "https://github.com/ERGO-Code/HiGHS.git" + GIT_TAG "v1.2.2" + ) + FetchContent_MakeAvailable(highs) + list(POP_BACK CMAKE_MESSAGE_INDENT) + message(CHECK_PASS "fetched") +endif() + # ############################################################################## # SCIP # ############################################################################## diff --git a/cmake/deps.cmake b/cmake/deps.cmake index 0f7ea73b8f..305e12a409 100644 --- a/cmake/deps.cmake +++ b/cmake/deps.cmake @@ -102,6 +102,12 @@ if(USE_GLPK) endif() endif() +if(USE_HIGHS) + if(NOT BUILD_HIGHS) + find_package(HIGHS REQUIRED) + endif() +endif() + if(USE_PDLP) if(NOT BUILD_PDLP) find_package(PDLP REQUIRED) diff --git a/cmake/docs/cmake.dot b/cmake/docs/cmake.dot index 3e5170284d..a5bb649628 100644 --- a/cmake/docs/cmake.dot +++ b/cmake/docs/cmake.dot @@ -127,6 +127,17 @@ digraph CMake { label = "GLPK Solver\n(-DUSE_GLPK=ON)"; } + subgraph clusterHIGHSSolver { + subgraph clusterHIGHS { + HIGHS [label="highs::highs"]; + + color=royalblue; + label = "ERGO-Code/HIGHS.git"; + } + color=royalblue; + label = "HIGHS Solver\n(-DUSE_HIGHS=ON)"; + } + subgraph clusterSCIPSolver { subgraph clusterSCIP { SCIP [label="scip::scip"]; diff --git a/cmake/docs/deps.dot b/cmake/docs/deps.dot index 1ef7666b4a..7ad3fc8bb9 100644 --- a/cmake/docs/deps.dot +++ b/cmake/docs/deps.dot @@ -123,6 +123,17 @@ digraph CMakeDeps { label = "-DUSE_GLPK=ON AND -DBUILD_GLPK=ON"; } + subgraph clusterHIGHSSolver { + subgraph clusterHIGHS { + HIGHS [label="highs::highs"]; + + color=royalblue; + label = "ERGO-Code/HIGHS.git"; + } + color=royalblue; + label = "-DUSE_HIGHS=ON AND -DBUILD_HIGHS=ON"; + } + subgraph clusterSCIPSolver { subgraph clusterSCIP { SCIP [label="scip::scip"]; diff --git a/cmake/dotnet.cmake b/cmake/dotnet.cmake index 1374cec43d..49df49ae08 100644 --- a/cmake/dotnet.cmake +++ b/cmake/dotnet.cmake @@ -229,6 +229,9 @@ endif() if(USE_GLPK) list(APPEND FLAGS "-DUSE_GLPK") endif() +if(USE_HIGHS) + list(APPEND FLAGS "-DUSE_HIGHS") +endif() if(USE_PDLP) list(APPEND FLAGS "-DUSE_PDLP") endif() diff --git a/cmake/java.cmake b/cmake/java.cmake index 60dfc1c72f..dace01649e 100644 --- a/cmake/java.cmake +++ b/cmake/java.cmake @@ -231,6 +231,9 @@ endif() if(USE_GLPK) list(APPEND FLAGS "-DUSE_GLPK") endif() +if(USE_HIGHS) + list(APPEND FLAGS "-DUSE_HIGHS") +endif() if(USE_PDLP) list(APPEND FLAGS "-DUSE_PDLP") endif() diff --git a/cmake/ortoolsConfig.cmake.in b/cmake/ortoolsConfig.cmake.in index 88cacd09f0..344e5a4e3f 100644 --- a/cmake/ortoolsConfig.cmake.in +++ b/cmake/ortoolsConfig.cmake.in @@ -53,6 +53,12 @@ if(@USE_GLPK@) endif() endif() +if(@USE_HIGHS@) + if(NOT HIGHS_FOUND AND NOT TARGET HIGHS::HIGHS) + find_dependency(HIGHS REQUIRED ${CONFIG_FLAG}) + endif() +endif() + if(@USE_PDLP@) if(NOT Eigen3_FOUND AND NOT TARGET Eigen3::Eigen) find_dependency(Eigen3 REQUIRED) diff --git a/cmake/python.cmake b/cmake/python.cmake index 46224d4467..caa4c96499 100644 --- a/cmake/python.cmake +++ b/cmake/python.cmake @@ -223,6 +223,9 @@ endif() if(USE_GLPK) list(APPEND FLAGS "-DUSE_GLPK") endif() +if(USE_HIGHS) + list(APPEND FLAGS "-DUSE_HIGHS") +endif() if(USE_PDLP) list(APPEND FLAGS "-DUSE_PDLP") endif() diff --git a/makefiles/Makefile.cpp.mk b/makefiles/Makefile.cpp.mk index c83c90778b..2a43d0bece 100644 --- a/makefiles/Makefile.cpp.mk +++ b/makefiles/Makefile.cpp.mk @@ -35,6 +35,7 @@ endif BUILD_TYPE ?= Release USE_COINOR ?= ON USE_GLPK ?= OFF +USE_HIGHS ?= OFF USE_PDLP := ON # OFF not supported USE_SCIP ?= ON USE_CPLEX ?= OFF @@ -65,6 +66,7 @@ third_party: -DBUILD_SAMPLES=OFF \ -DUSE_COINOR=$(USE_COINOR) \ -DUSE_GLPK=$(USE_GLPK) \ + -DUSE_HIGHS=$(USE_HIGHS) \ -DUSE_PDLP=$(USE_PDLP) \ -DUSE_SCIP=$(USE_SCIP) \ -DUSE_CPLEX=$(USE_CPLEX) \ diff --git a/ortools/linear_solver/CMakeLists.txt b/ortools/linear_solver/CMakeLists.txt index 830738db2c..8ea6ddab72 100644 --- a/ortools/linear_solver/CMakeLists.txt +++ b/ortools/linear_solver/CMakeLists.txt @@ -39,6 +39,7 @@ target_link_libraries(${NAME} PRIVATE $<$:Coin::Clp> $<$:CPLEX::CPLEX> $<$:GLPK::GLPK> + $<$:HIGHS::HIGHS> $<$:Eigen3::Eigen> $<$:libscip> $<$:XPRESS::XPRESS> diff --git a/ortools/linear_solver/linear_solver.cc b/ortools/linear_solver/linear_solver.cc index 9352ee8902..c171536763 100644 --- a/ortools/linear_solver/linear_solver.cc +++ b/ortools/linear_solver/linear_solver.cc @@ -373,6 +373,9 @@ extern MPSolverInterface* BuildCBCInterface(MPSolver* const solver); #if defined(USE_GLPK) extern MPSolverInterface* BuildGLPKInterface(bool mip, MPSolver* const solver); #endif +#if defined(USE_HIGHS) +extern MPSolverInterface* BuildHIGHSInterface(bool mip, MPSolver* const solver); +#endif extern MPSolverInterface* BuildBopInterface(MPSolver* const solver); extern MPSolverInterface* BuildGLOPInterface(MPSolver* const solver); extern MPSolverInterface* BuildPdlpInterface(MPSolver* const solver); @@ -408,6 +411,12 @@ MPSolverInterface* BuildSolverInterface(MPSolver* const solver) { case MPSolver::GLPK_MIXED_INTEGER_PROGRAMMING: return BuildGLPKInterface(true, solver); #endif +#if defined(USE_HIGHS) + case MPSolver::HIGHS_LINEAR_PROGRAMMING: + return BuildHIGHSInterface(false, solver); + case MPSolver::HIGHS_MIXED_INTEGER_PROGRAMMING: + return BuildHIGHSInterface(true, solver); +#endif #if defined(USE_CLP) || defined(USE_CBC) case MPSolver::CLP_LINEAR_PROGRAMMING: return BuildCLPInterface(solver);