Skip to content

Commit

Permalink
xpress integration in or-tools
Browse files Browse the repository at this point in the history
  • Loading branch information
klorel committed Aug 6, 2019
1 parent 2c67e00 commit f50fc89
Show file tree
Hide file tree
Showing 9 changed files with 1,647 additions and 1 deletion.
79 changes: 79 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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}")
Expand Down Expand Up @@ -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)
Expand All @@ -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)
1 change: 1 addition & 0 deletions cmake/dependencies/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ if(BUILD_Protobuf)
TAG
"v3.8.0"
CMAKE_ARGS
-Dprotobuf_MSVC_STATIC_RUNTIME:BOOL=OFF
"SOURCE_SUBDIR cmake"
)
endif()
Expand Down
15 changes: 15 additions & 0 deletions examples/cpp/strawberry_fields_with_column_generation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
12 changes: 12 additions & 0 deletions ortools/algorithms/knapsack_solver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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.";
}
Expand Down
7 changes: 6 additions & 1 deletion ortools/algorithms/knapsack_solver.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand Down
20 changes: 20 additions & 0 deletions ortools/linear_solver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
19 changes: 19 additions & 0 deletions ortools/linear_solver/linear_solver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -1458,7 +1475,9 @@ void MPSolver::GenerateConstraintNameIndex() const {
}
}

#if defined(USE_GUROBI)
bool MPSolver::NextSolution() { return interface_->NextSolution(); }
#endif

// ---------- MPSolverInterface ----------

Expand Down
10 changes: 10 additions & 0 deletions ortools/linear_solver/linear_solver.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Loading

0 comments on commit f50fc89

Please sign in to comment.