xpress integration in or-tools
This commit is contained in:
@@ -7,6 +7,14 @@ if(POLICY CMP0068)
|
||||
cmake_policy(SET CMP0068 NEW)
|
||||
endif()
|
||||
|
||||
if(POLICY CMP0078)
|
||||
cmake_policy(SET CMP0078 OLD)
|
||||
endif()
|
||||
|
||||
if(POLICY CMP0086)
|
||||
cmake_policy(SET CMP0086 NEW)
|
||||
endif()
|
||||
|
||||
include(utils)
|
||||
set_version(VERSION)
|
||||
|
||||
@@ -32,10 +40,14 @@ option(BUILD_CXX "Build C++ library" ON)
|
||||
option(BUILD_PYTHON "Build Python Library" OFF)
|
||||
option(BUILD_JAVA "Build Java Library" OFF)
|
||||
option(BUILD_DOTNET "Build .NET Library" OFF)
|
||||
option(USE_XPRESS "Build and use XPRESS interface" OFF)
|
||||
option(USE_CPLEX "Build and use CPLEX interface" OFF)
|
||||
message(STATUS "Build C++ library: ${BUILD_CXX}")
|
||||
message(STATUS "Build Python: ${BUILD_PYTHON}")
|
||||
message(STATUS "Build Java: ${BUILD_JAVA}")
|
||||
message(STATUS "Build .Net: ${BUILD_DOTNET}")
|
||||
message(STATUS "USE_XPRESS: ${USE_XPRESS}")
|
||||
message(STATUS "USE_CPLEX: ${USE_CPLEX}")
|
||||
|
||||
#option(BUILD_DOC "Build doxygen" OFF)
|
||||
#message(STATUS "Build doxygen: ${BUILD_DOC}")
|
||||
@@ -79,6 +91,49 @@ message(STATUS "Build Clp: ${BUILD_Clp}")
|
||||
message(STATUS "Build Cgl: ${BUILD_Cgl}")
|
||||
message(STATUS "Build Cbc: ${BUILD_Cbc}")
|
||||
|
||||
if (USE_XPRESS)
|
||||
|
||||
if (APPLE)
|
||||
message(FATAL_ERROR "XPRESS not yet supported on MACOS")
|
||||
endif()
|
||||
|
||||
message(STATUS "XPRESS: configuring makefiles")
|
||||
if (NOT XPRESSDIR)
|
||||
set(XPRESSDIR $ENV{XPRESSDIR})
|
||||
endif(NOT XPRESSDIR)
|
||||
|
||||
message(STATUS "XPRESSDIR: ${XPRESSDIR}")
|
||||
|
||||
if (NOT XPRESSDIR)
|
||||
message(FATAL_ERROR "XPRESSDIR: not found")
|
||||
endif()
|
||||
|
||||
add_compile_definitions(USE_XPRESS)
|
||||
endif(USE_XPRESS)
|
||||
|
||||
|
||||
if (USE_CPLEX)
|
||||
|
||||
if (APPLE)
|
||||
message(FATAL_ERROR "CPLEX not yet supported on MACOS")
|
||||
elseif(UNIX)
|
||||
message(FATAL_ERROR "CPLEX not yet supported on LINUX")
|
||||
endif()
|
||||
|
||||
message(STATUS "CPLEX: configuring makefiles")
|
||||
if (NOT CPLEXDIR)
|
||||
set(CPLEXDIR $ENV{CPLEXDIR})
|
||||
endif(NOT CPLEXDIR)
|
||||
|
||||
message(STATUS "CPLEXDIR: ${CPLEXDIR}")
|
||||
|
||||
if (NOT CPLEXDIR)
|
||||
message(FATAL_ERROR "CPLEXDIR: not found")
|
||||
endif()
|
||||
|
||||
add_compile_definitions(USE_CPLEX)
|
||||
endif(USE_CPLEX)
|
||||
|
||||
# Build Needed dependencies
|
||||
add_subdirectory(cmake/dependencies dependencies)
|
||||
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR}/dependencies/install)
|
||||
@@ -90,3 +145,27 @@ include(cpp)
|
||||
include(python)
|
||||
include(java)
|
||||
include(dotnet)
|
||||
|
||||
if (USE_XPRESS)
|
||||
if (APPLE)
|
||||
message(FATAL_ERROR "XPRESS not yet supported on MACOS")
|
||||
#target_link_libraries(ortools PUBLIC ${XPRESSDIR}/lib/libxprs.dylib)
|
||||
elseif(UNIX)
|
||||
target_link_libraries(ortools PUBLIC ${XPRESSDIR}/lib/libxprs.so)
|
||||
elseif(MSVC)
|
||||
target_link_libraries(ortools PUBLIC ${XPRESSDIR}/lib/xprs.lib)
|
||||
endif()
|
||||
endif(USE_XPRESS)
|
||||
|
||||
|
||||
if (USE_CPLEX)
|
||||
if (APPLE)
|
||||
message(FATAL_ERROR "CPLEX not yet supported on MACOS")
|
||||
#target_link_libraries(ortools PUBLIC ${CPLEXDIR}/lib/x64_windows_vs2015/stat_mda/cplex1270.dylib)
|
||||
elseif(UNIX)
|
||||
message(FATAL_ERROR "CPLEX not yet supported on LINUX")
|
||||
#target_link_libraries(ortools PUBLIC ${CPLEXDIR}/lib/x64_windows_vs2015/stat_mda/cplex1270.so)
|
||||
elseif(MSVC)
|
||||
target_link_libraries(ortools PUBLIC ${CPLEXDIR}/lib/x64_windows_vs2015/stat_mda/cplex1270.lib)
|
||||
endif()
|
||||
endif(USE_CPLEX)
|
||||
|
||||
@@ -104,6 +104,7 @@ if(BUILD_Protobuf)
|
||||
TAG
|
||||
"v3.8.0"
|
||||
CMAKE_ARGS
|
||||
-Dprotobuf_MSVC_STATIC_RUNTIME:BOOL=OFF
|
||||
"SOURCE_SUBDIR cmake"
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -618,11 +618,26 @@ int main(int argc, char** argv) {
|
||||
found = true;
|
||||
}
|
||||
#endif // USE_GLOP
|
||||
#if defined(USE_XPRESS)
|
||||
if (FLAGS_colgen_solver == "xpress") {
|
||||
solver_type = operations_research::MPSolver::XPRESS_LINEAR_PROGRAMMING;
|
||||
//solver_type = operations_research::MPSolver::CPLEX_LINEAR_PROGRAMMING;
|
||||
found = true;
|
||||
}
|
||||
#endif
|
||||
#if defined(USE_CPLEX)
|
||||
if (FLAGS_colgen_solver == "cplex") {
|
||||
solver_type = operations_research::MPSolver::CPLEX_LINEAR_PROGRAMMING;
|
||||
found = true;
|
||||
}
|
||||
#endif
|
||||
if (!found) {
|
||||
LOG(ERROR) << "Unknown solver " << FLAGS_colgen_solver;
|
||||
return 1;
|
||||
}
|
||||
|
||||
LOG(INFO) << "Chosen solver: " << FLAGS_colgen_solver << std::endl;
|
||||
|
||||
if (FLAGS_colgen_instance == -1) {
|
||||
for (int i = 0; i < operations_research::kInstanceCount; ++i) {
|
||||
const operations_research::Instance& instance =
|
||||
|
||||
@@ -1153,6 +1153,18 @@ KnapsackSolver::KnapsackSolver(SolverType solver_type,
|
||||
MPSolver::SCIP_MIXED_INTEGER_PROGRAMMING, solver_name);
|
||||
break;
|
||||
#endif // USE_SCIP
|
||||
#if defined(USE_XPRESS)
|
||||
case KNAPSACK_MULTIDIMENSION_XPRESS_MIP_SOLVER:
|
||||
solver_ = absl::make_unique<KnapsackMIPSolver>(
|
||||
MPSolver::XPRESS_MIXED_INTEGER_PROGRAMMING, solver_name);
|
||||
break;
|
||||
#endif
|
||||
#if defined(USE_CPLEX)
|
||||
case KNAPSACK_MULTIDIMENSION_CPLEX_MIP_SOLVER:
|
||||
solver_ = absl::make_unique<KnapsackMIPSolver>(
|
||||
MPSolver::CPLEX_MIXED_INTEGER_PROGRAMMING, solver_name);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
LOG(FATAL) << "Unknown knapsack solver type.";
|
||||
}
|
||||
|
||||
@@ -157,7 +157,6 @@ class KnapsackSolver {
|
||||
*/
|
||||
KNAPSACK_MULTIDIMENSION_CBC_MIP_SOLVER = 3,
|
||||
#endif // USE_CBC
|
||||
|
||||
/** Generic Solver.
|
||||
*
|
||||
* This solver can deal with both large number of items and several
|
||||
@@ -173,6 +172,12 @@ class KnapsackSolver {
|
||||
*/
|
||||
KNAPSACK_MULTIDIMENSION_SCIP_MIP_SOLVER = 6,
|
||||
#endif // USE_SCIP
|
||||
#if defined(USE_XPRESS)
|
||||
KNAPSACK_MULTIDIMENSION_XPRESS_MIP_SOLVER = 7,
|
||||
#endif
|
||||
#if defined(USE_CPLEX)
|
||||
KNAPSACK_MULTIDIMENSION_CPLEX_MIP_SOLVER = 8,
|
||||
#endif
|
||||
};
|
||||
|
||||
explicit KnapsackSolver(const std::string& solver_name);
|
||||
|
||||
@@ -58,3 +58,23 @@ add_dependencies(${NAME}
|
||||
Coin::Cbc
|
||||
${PROJECT_NAME}::proto)
|
||||
add_library(${PROJECT_NAME}::linear_solver ALIAS ${NAME})
|
||||
|
||||
if (USE_XPRESS)
|
||||
target_include_directories(${NAME} PUBLIC ${XPRESSDIR}/include)
|
||||
if(UNIX)
|
||||
target_link_libraries(${NAME} PUBLIC ${XPRESSDIR}/lib/libxprs.so)
|
||||
elseif(MSVC)
|
||||
target_link_libraries(${NAME} PUBLIC ${XPRESSDIR}/lib/xprs.lib)
|
||||
endif()
|
||||
endif(USE_XPRESS)
|
||||
|
||||
if (USE_CPLEX)
|
||||
target_include_directories(${NAME} PUBLIC
|
||||
${CPLEXDIR}/include
|
||||
)
|
||||
if(UNIX)
|
||||
target_link_libraries(${NAME} PUBLIC ${CPLEXDIR}/lib/x64_windows_vs2015/stat_mda/cplex1270.a)
|
||||
elseif(MSVC)
|
||||
target_link_libraries(${NAME} PUBLIC ${CPLEXDIR}/lib/x64_windows_vs2015/stat_mda/cplex1270.lib)
|
||||
endif()
|
||||
endif(USE_CPLEX)
|
||||
@@ -349,6 +349,9 @@ extern MPSolverInterface* BuildCplexInterface(bool mip, MPSolver* const solver);
|
||||
|
||||
extern MPSolverInterface* BuildGLOPInterface(MPSolver* const solver);
|
||||
#endif
|
||||
#if defined(USE_XPRESS)
|
||||
extern MPSolverInterface* BuildXpressInterface(bool mip, MPSolver* const solver);
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
MPSolverInterface* BuildSolverInterface(MPSolver* const solver) {
|
||||
@@ -391,6 +394,12 @@ MPSolverInterface* BuildSolverInterface(MPSolver* const solver) {
|
||||
return BuildCplexInterface(false, solver);
|
||||
case MPSolver::CPLEX_MIXED_INTEGER_PROGRAMMING:
|
||||
return BuildCplexInterface(true, solver);
|
||||
#endif
|
||||
#if defined(USE_XPRESS)
|
||||
case MPSolver::XPRESS_MIXED_INTEGER_PROGRAMMING:
|
||||
return BuildXpressInterface(true, solver);
|
||||
case MPSolver::XPRESS_LINEAR_PROGRAMMING:
|
||||
return BuildXpressInterface(false, solver);
|
||||
#endif
|
||||
default:
|
||||
// TODO(user): Revert to the best *available* interface.
|
||||
@@ -455,6 +464,14 @@ bool MPSolver::SupportsProblemType(OptimizationProblemType problem_type) {
|
||||
#endif
|
||||
#ifdef USE_CBC
|
||||
if (problem_type == CBC_MIXED_INTEGER_PROGRAMMING) return true;
|
||||
#endif
|
||||
#ifdef USE_XPRESS
|
||||
if (problem_type == XPRESS_MIXED_INTEGER_PROGRAMMING) return true;
|
||||
if (problem_type == XPRESS_LINEAR_PROGRAMMING) return true;
|
||||
#endif
|
||||
#ifdef USE_CPLEX
|
||||
if (problem_type == CPLEX_LINEAR_PROGRAMMING) return true;
|
||||
if (problem_type == CPLEX_MIXED_INTEGER_PROGRAMMING) return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
@@ -1458,7 +1475,9 @@ void MPSolver::GenerateConstraintNameIndex() const {
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(USE_GUROBI)
|
||||
bool MPSolver::NextSolution() { return interface_->NextSolution(); }
|
||||
#endif
|
||||
|
||||
// ---------- MPSolverInterface ----------
|
||||
|
||||
|
||||
@@ -224,6 +224,10 @@ class MPSolver {
|
||||
#if defined(USE_BOP)
|
||||
/// Linear Boolean Programming Solver.
|
||||
BOP_INTEGER_PROGRAMMING = 12,
|
||||
#endif
|
||||
#if defined(USE_XPRESS)
|
||||
XPRESS_LINEAR_PROGRAMMING = 101,
|
||||
XPRESS_MIXED_INTEGER_PROGRAMMING = 102,
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -726,8 +730,10 @@ class MPSolver {
|
||||
* As of 2018-08-09, only Gurobi supports NextSolution(), see
|
||||
* linear_solver_underlying_gurobi_test for an example of how to configure
|
||||
* Gurobi for this purpose. The other solvers return false unconditionally.
|
||||
#if defined(USE_GUROBI)
|
||||
*/
|
||||
ABSL_MUST_USE_RESULT bool NextSolution();
|
||||
#endif
|
||||
|
||||
// DEPRECATED: Use TimeLimit() and SetTimeLimit(absl::Duration) instead.
|
||||
// NOTE: These deprecated functions used the convention time_limit = 0 to mean
|
||||
@@ -757,6 +763,7 @@ class MPSolver {
|
||||
friend class SCIPInterface;
|
||||
friend class GurobiInterface;
|
||||
friend class CplexInterface;
|
||||
friend class XpressInterface;
|
||||
friend class SLMInterface;
|
||||
friend class MPSolverInterface;
|
||||
friend class GLOPInterface;
|
||||
@@ -967,6 +974,7 @@ class MPObjective {
|
||||
friend class SLMInterface;
|
||||
friend class GurobiInterface;
|
||||
friend class CplexInterface;
|
||||
friend class XpressInterface;
|
||||
friend class GLOPInterface;
|
||||
friend class BopInterface;
|
||||
friend class SatInterface;
|
||||
@@ -1074,6 +1082,7 @@ class MPVariable {
|
||||
friend class SLMInterface;
|
||||
friend class GurobiInterface;
|
||||
friend class CplexInterface;
|
||||
friend class XpressInterface;
|
||||
friend class GLOPInterface;
|
||||
friend class MPVariableSolutionValueTest;
|
||||
friend class BopInterface;
|
||||
@@ -1215,6 +1224,7 @@ class MPConstraint {
|
||||
friend class SLMInterface;
|
||||
friend class GurobiInterface;
|
||||
friend class CplexInterface;
|
||||
friend class XpressInterface;
|
||||
friend class GLOPInterface;
|
||||
friend class BopInterface;
|
||||
friend class SatInterface;
|
||||
|
||||
1485
ortools/linear_solver/xpress_interface.cc
Normal file
1485
ortools/linear_solver/xpress_interface.cc
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user