Merge pull request #3966 from rte-france/feature/xpress_only
Improve the Xpress interface and add dynamic loading of the Xpress library
This commit is contained in:
@@ -274,8 +274,8 @@ option(USE_CPLEX "Use the CPLEX solver" OFF)
|
||||
message(STATUS "CPLEX support: ${USE_CPLEX}")
|
||||
|
||||
## XPRESS
|
||||
option(USE_XPRESS "Use the XPRESS solver" OFF)
|
||||
message(STATUS "XPRESS support: ${USE_XPRESS}")
|
||||
# Since it is dynamicaly loaded upon use, OFF is currently not supported.
|
||||
CMAKE_DEPENDENT_OPTION(USE_XPRESS "Use the Xpress solver" ON "BUILD_CXX" OFF)
|
||||
|
||||
# Language specific options
|
||||
if(BUILD_CXX)
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
# Copyright 2010-2022 Google LLC
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindXPRESS
|
||||
--------
|
||||
|
||||
This module determines the XPRESS library of the system.
|
||||
|
||||
IMPORTED Targets
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
This module defines :prop_tgt:`IMPORTED` target ``XPRESS::XPRESS``, if
|
||||
XPRESS has been found.
|
||||
|
||||
Result Variables
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
This module defines the following variables:
|
||||
|
||||
::
|
||||
|
||||
XPRESS_FOUND - True if XPRESS found.
|
||||
|
||||
Hints
|
||||
^^^^^
|
||||
|
||||
A user may set ``XPRESS_ROOT`` to a XPRESS installation root to tell this
|
||||
module where to look.
|
||||
#]=======================================================================]
|
||||
set(XPRESS_FOUND FALSE)
|
||||
|
||||
if(CMAKE_C_COMPILER_LOADED)
|
||||
include (CheckIncludeFile)
|
||||
include (CheckCSourceCompiles)
|
||||
elseif(CMAKE_CXX_COMPILER_LOADED)
|
||||
include (CheckIncludeFileCXX)
|
||||
include (CheckCXXSourceCompiles)
|
||||
else()
|
||||
message(FATAL_ERROR "FindXPRESS only works if either C or CXX language is enabled")
|
||||
endif()
|
||||
|
||||
if(NOT XPRESS_ROOT)
|
||||
set(XPRESS_ROOT $ENV{XPRESS_ROOT})
|
||||
endif()
|
||||
message(STATUS "XPRESS_ROOT: ${XPRESS_ROOT}")
|
||||
if(NOT XPRESS_ROOT)
|
||||
message(FATAL_ERROR "XPRESS_ROOT: not found")
|
||||
else()
|
||||
set(XPRESS_FOUND TRUE)
|
||||
endif()
|
||||
|
||||
if(XPRESS_FOUND AND NOT TARGET XPRESS::XPRESS)
|
||||
add_library(XPRESS::XPRESS UNKNOWN IMPORTED)
|
||||
|
||||
if(UNIX)
|
||||
target_include_directories(XPRESS::XPRESS SYSTEM INTERFACE "${XPRESS_ROOT}/include")
|
||||
endif()
|
||||
|
||||
if(APPLE) # be aware that `UNIX` is `TRUE` on OS X, so this check must be first
|
||||
set_target_properties(XPRESS::XPRESS PROPERTIES
|
||||
#INSTALL_RPATH_USE_LINK_PATH TRUE
|
||||
#BUILD_WITH_INSTALL_RPATH TRUE
|
||||
#INTERFACE_LINK_DIRECTORIES "${XPRESS_ROOT}/lib"
|
||||
#INSTALL_RPATH "${XPRESS_ROOT}/lib;${INSTALL_RPATH}"
|
||||
IMPORTED_LOCATION "${XPRESS_ROOT}/lib/libxprs.dylib")
|
||||
elseif(UNIX)
|
||||
set_target_properties(XPRESS::XPRESS PROPERTIES
|
||||
INTERFACE_LINK_DIRECTORIES "${XPRESS_ROOT}/lib"
|
||||
IMPORTED_LOCATION ${XPRESS_ROOT}/lib/libxprs.so)
|
||||
elseif(MSVC)
|
||||
set_target_properties(XPRESS::XPRESS PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${XPRESS_ROOT}\\include"
|
||||
IMPORTED_LOCATION "${XPRESS_ROOT}\\lib\\xprs.lib")
|
||||
else()
|
||||
message(FATAL_ERROR "XPRESS not supported for ${CMAKE_SYSTEM}")
|
||||
endif()
|
||||
endif()
|
||||
@@ -91,7 +91,7 @@ Here the list of supported solvers:
|
||||
* HiGHS\*
|
||||
* PDLP
|
||||
* SCIP
|
||||
* XPRESS\*
|
||||
* XPRESS
|
||||
|
||||
\*: these solvers are disabled by default.
|
||||
|
||||
@@ -127,7 +127,6 @@ support for the following third-party solvers:
|
||||
note: You must enable the support of GLPK solver by using `-DUSE_GLPK=ON`
|
||||
(`OFF` by default).
|
||||
* CPLEX (`USE_CPLEX`),
|
||||
* XPRESS (`USE_XPRESS`)
|
||||
|
||||
**warning: Since these solvers are either proprietary (and require a specific
|
||||
license) or available under the GPL, we can't test them on public CI and their
|
||||
@@ -145,14 +144,6 @@ For ease of migration from legacy `make third_party` builds, CMake will also
|
||||
read the CPLEX installation path from the `UNIX_CPLEX_DIR` environment variable,
|
||||
if defined.
|
||||
|
||||
### Enabling XPRESS Support
|
||||
|
||||
To enable XPRESS support, configure with `-DUSE_XPRESS=ON` and
|
||||
`-DXPRESS_ROOT=/absolute/path/to/XPRESS/root/dir`, replacing
|
||||
`/absolute/path/to/XPRESS/root/dir` with the path to your XPRESS installation.
|
||||
`XPRESS_ROOT` can also be defined as an environment variable rather than an
|
||||
option at configure time.
|
||||
|
||||
## CMake Options
|
||||
|
||||
There are several options that can be passed to CMake to modify how the code
|
||||
@@ -217,8 +208,6 @@ cmake -S. -Bbuild -LH
|
||||
| | | |
|
||||
| `USE_CPLEX` | OFF | Enable CPLEX support |
|
||||
| | | |
|
||||
| `USE_XPRESS` | OFF | Enable XPRESS support |
|
||||
| | | |
|
||||
| `BUILD_DOC` | OFF\* | Build all documentations |
|
||||
| `BUILD_CXX_DOC` | OFF\* | Build C++ documentation<br>**Forced** to ON if `BUILD_DOC=ON` |
|
||||
| `BUILD_DOTNET_DOC` | OFF\* | Build .Net documentation<br>**Forced** to ON if `BUILD_DOC=ON` |
|
||||
|
||||
@@ -66,14 +66,6 @@ endif()
|
||||
if(USE_CPLEX)
|
||||
list(APPEND OR_TOOLS_COMPILE_DEFINITIONS "USE_CPLEX")
|
||||
endif()
|
||||
if(USE_XPRESS)
|
||||
list(APPEND OR_TOOLS_COMPILE_DEFINITIONS "USE_XPRESS")
|
||||
if(MSVC)
|
||||
list(APPEND OR_TOOLS_COMPILE_DEFINITIONS "XPRESS_PATH=\"${XPRESS_ROOT}\"")
|
||||
else()
|
||||
list(APPEND OR_TOOLS_COMPILE_DEFINITIONS "XPRESS_PATH=${XPRESS_ROOT}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND OR_TOOLS_COMPILE_DEFINITIONS "__WIN32__")
|
||||
@@ -327,7 +319,8 @@ foreach(SUBPROJECT IN ITEMS
|
||||
port
|
||||
sat
|
||||
scheduling
|
||||
util)
|
||||
util
|
||||
xpress)
|
||||
add_subdirectory(ortools/${SUBPROJECT})
|
||||
#target_link_libraries(${PROJECT_NAME} PRIVATE ${PROJECT_NAME}_${SUBPROJECT})
|
||||
target_sources(${PROJECT_NAME} PRIVATE $<TARGET_OBJECTS:${PROJECT_NAME}_${SUBPROJECT}>)
|
||||
@@ -365,7 +358,6 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
$<$<BOOL:${USE_HIGHS}>:HIGHS::HIGHS>
|
||||
${PDLP_DEPS}
|
||||
$<$<BOOL:${USE_SCIP}>:libscip>
|
||||
$<$<BOOL:${USE_XPRESS}>:XPRESS::XPRESS>
|
||||
Threads::Threads)
|
||||
if(WIN32)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC psapi.lib ws2_32.lib)
|
||||
|
||||
@@ -145,10 +145,6 @@ if(USE_CPLEX)
|
||||
find_package(CPLEX REQUIRED)
|
||||
endif()
|
||||
|
||||
if(USE_XPRESS)
|
||||
find_package(XPRESS REQUIRED)
|
||||
endif()
|
||||
|
||||
# Check language Dependencies
|
||||
if(BUILD_PYTHON)
|
||||
if(NOT BUILD_pybind11)
|
||||
|
||||
@@ -87,6 +87,7 @@ void RunAllExamples() {
|
||||
RunIntegerProgrammingExample("GUROBI");
|
||||
RunIntegerProgrammingExample("GLPK");
|
||||
RunIntegerProgrammingExample("CPLEX");
|
||||
RunIntegerProgrammingExample("XPRESS");
|
||||
}
|
||||
} // namespace operations_research
|
||||
|
||||
|
||||
104
examples/cpp/xpress_use.cc
Normal file
104
examples/cpp/xpress_use.cc
Normal file
@@ -0,0 +1,104 @@
|
||||
// Copyright Artelys for RTE.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// This example that shows how to use Xpress Solver.
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include "ortools/base/init_google.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/linear_solver/linear_solver.h"
|
||||
|
||||
using namespace operations_research;
|
||||
|
||||
/**
|
||||
* This method shows two ways to initialize a Xpress solver instance.
|
||||
* Two environment variables are used to specify the Xpress installation paths:
|
||||
* * XPRESSDIR : Path to the Xpress root directory (containing bin and lib folders)
|
||||
* * XPRESS : Path to the directory containing Xpress license
|
||||
*/
|
||||
void useXpressSolver(bool solveAsMip, bool useFactory) {
|
||||
std::unique_ptr<MPSolver> solver = nullptr;
|
||||
if (useFactory) {
|
||||
/* This is the preferred way as the program won't stop if anything went
|
||||
wrong. In such a case, `solver` will take value `nullptr` */
|
||||
std::string xpressName = (solveAsMip ? "XPRESS" : "XPRESS_LP");
|
||||
solver.reset(MPSolver::CreateSolver(xpressName));
|
||||
} else {
|
||||
MPSolver::OptimizationProblemType problemType = (solveAsMip ?
|
||||
MPSolver::XPRESS_MIXED_INTEGER_PROGRAMMING
|
||||
: MPSolver::XPRESS_LINEAR_PROGRAMMING);
|
||||
/* MPSolver::SupportsProblemType(problem_type) will test if Xpress is
|
||||
correctly loaded and has a valid license. This check is important to keep
|
||||
the program running if Xpress is not correctly installed. With the
|
||||
constructor usage, if Xpress is badly loaded or if there is a problem
|
||||
with the license, the program will abort (SIGABRT)
|
||||
*/
|
||||
if (MPSolver::SupportsProblemType(problemType)) {
|
||||
solver.reset(new MPSolver("IntegerProgrammingExample", problemType));
|
||||
}
|
||||
}
|
||||
if (solver == nullptr) {
|
||||
LOG(WARNING) << "Xpress solver is not available";
|
||||
return;
|
||||
}
|
||||
// Use the solver
|
||||
/*
|
||||
max -100 x1 + 10 x2
|
||||
s.t. x2 <= 20 x1;
|
||||
30 x1 + 3.5 x2 <= 350
|
||||
0 <= x1 <= 5
|
||||
0 <= x2
|
||||
*/
|
||||
const double infinity = MPSolver::infinity();
|
||||
const MPVariable* x1 = solver->MakeIntVar(0, 5, "x1");
|
||||
const MPVariable* x2 = solver->MakeNumVar(0.0, infinity, "x2");
|
||||
|
||||
MPObjective* const objective = solver->MutableObjective();
|
||||
objective->SetCoefficient(x1, -100);
|
||||
objective->SetCoefficient(x2, 10);
|
||||
objective->SetMaximization();
|
||||
|
||||
MPConstraint* const c0 = solver->MakeRowConstraint(-infinity, 0.0);
|
||||
c0->SetCoefficient(x1, -20.0);
|
||||
c0->SetCoefficient(x2, 1);
|
||||
|
||||
MPConstraint* const c1 = solver->MakeRowConstraint(-infinity, 350.0);
|
||||
c1->SetCoefficient(x1, 30.0);
|
||||
c1->SetCoefficient(x2, 3.5);
|
||||
|
||||
|
||||
const MPSolver::ResultStatus result_status = solver->Solve();
|
||||
|
||||
// Check that the problem has an optimal solution.
|
||||
if (result_status != MPSolver::OPTIMAL) {
|
||||
LOG(FATAL) << "Solver returned with non-optimal status.";
|
||||
} else {
|
||||
LOG(WARNING) << "Optimal solution found: obj=" << objective->Value();
|
||||
}
|
||||
}
|
||||
#define ABSL_MIN_LOG_LEVEL INFO;
|
||||
int main(int argc, char** argv) {
|
||||
absl::SetFlag(&FLAGS_stderrthreshold, 0);
|
||||
absl::SetFlag(&FLAGS_logtostderr, true);
|
||||
InitGoogle(argv[0], &argc, &argv, true);
|
||||
std::cout << "start\n";
|
||||
LOG(WARNING) << "start";
|
||||
for (bool solveAsMip: {true, false}) {
|
||||
for (bool useFactory: {true, false}) {
|
||||
useXpressSolver(solveAsMip, useFactory);
|
||||
}
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -117,6 +117,8 @@ public class CsIntegerProgramming
|
||||
RunIntegerProgrammingExample("SAT");
|
||||
Console.WriteLine("---- Linear programming example with GUROBI ----");
|
||||
RunIntegerProgrammingExample("GUROBI");
|
||||
Console.WriteLine("---- Linear programming example with XPRESS ----");
|
||||
RunIntegerProgrammingExample("XPRESS");
|
||||
Console.WriteLine("---- Integer programming example (Natural API) with GLPK ----");
|
||||
RunIntegerProgrammingExampleNaturalApi("GLPK");
|
||||
Console.WriteLine("---- Linear programming example (Natural API) with CBC ----");
|
||||
@@ -127,5 +129,7 @@ public class CsIntegerProgramming
|
||||
RunIntegerProgrammingExampleNaturalApi("SAT");
|
||||
Console.WriteLine("---- Linear programming example (Natural API) with GUROBI ----");
|
||||
RunIntegerProgrammingExampleNaturalApi("GUROBI");
|
||||
Console.WriteLine("---- Linear programming example (Natural API) with XPRESS ----");
|
||||
RunIntegerProgrammingExampleNaturalApi("XPRESS");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,6 +160,7 @@ public class CsLinearProgramming
|
||||
RunLinearProgrammingExample("GLOP");
|
||||
RunLinearProgrammingExample("GLPK_LP");
|
||||
RunLinearProgrammingExample("CLP");
|
||||
RunLinearProgrammingExample("XPRESS_LP");
|
||||
|
||||
RunLinearProgrammingExampleNaturalApi("GLOP", true);
|
||||
RunLinearProgrammingExampleNaturalApi("GLPK_LP", false);
|
||||
|
||||
@@ -84,5 +84,7 @@ public class IntegerProgramming {
|
||||
runIntegerProgrammingExample("GLPK");
|
||||
System.out.println("---- Integer programming example with CP-SAT ----");
|
||||
runIntegerProgrammingExample("SAT");
|
||||
System.out.println("---- Integer programming example with XPRESS ----");
|
||||
runIntegerProgrammingExample("XPRESS");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,5 +116,7 @@ public class LinearProgramming {
|
||||
runLinearProgrammingExample("GLOP", true);
|
||||
System.out.println("---- Linear programming example with CLP ----");
|
||||
runLinearProgrammingExample("CLP", false);
|
||||
System.out.println("---- Linear programming example with XPRESS ----");
|
||||
runLinearProgrammingExample("XPRESS_LP", false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,6 +102,7 @@ def RunAllIntegerExampleNaturalLanguageAPI():
|
||||
# RunIntegerExampleNaturalLanguageAPI('CBC')
|
||||
RunIntegerExampleNaturalLanguageAPI("SCIP")
|
||||
RunIntegerExampleNaturalLanguageAPI("SAT")
|
||||
RunIntegerExampleNaturalLanguageAPI("XPRESS")
|
||||
|
||||
|
||||
def RunAllIntegerExampleCppStyleAPI():
|
||||
@@ -110,6 +111,7 @@ def RunAllIntegerExampleCppStyleAPI():
|
||||
# RunIntegerExampleCppStyleAPI('CBC')
|
||||
RunIntegerExampleCppStyleAPI("SCIP")
|
||||
RunIntegerExampleCppStyleAPI("SAT")
|
||||
RunIntegerExampleCppStyleAPI("XPRESS")
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
@@ -138,11 +138,13 @@ def main():
|
||||
RunLinearExampleNaturalLanguageAPI("GLPK_LP")
|
||||
RunLinearExampleNaturalLanguageAPI("CLP")
|
||||
RunLinearExampleNaturalLanguageAPI("PDLP")
|
||||
RunLinearExampleNaturalLanguageAPI("XPRESS_LP")
|
||||
|
||||
RunLinearExampleCppStyleAPI("GLOP")
|
||||
RunLinearExampleCppStyleAPI("GLPK_LP")
|
||||
RunLinearExampleCppStyleAPI("CLP")
|
||||
RunLinearExampleCppStyleAPI("PDLP")
|
||||
RunLinearExampleCppStyleAPI("XPRESS_LP")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -39,7 +39,6 @@ USE_HIGHS ?= OFF
|
||||
USE_PDLP := ON # OFF not supported
|
||||
USE_SCIP ?= ON
|
||||
USE_CPLEX ?= OFF
|
||||
USE_XPRESS ?= OFF
|
||||
|
||||
USE_DOTNET_CORE_31 ?= OFF
|
||||
USE_DOTNET_6 ?= ON
|
||||
@@ -72,7 +71,6 @@ third_party:
|
||||
-DUSE_PDLP=$(USE_PDLP) \
|
||||
-DUSE_SCIP=$(USE_SCIP) \
|
||||
-DUSE_CPLEX=$(USE_CPLEX) \
|
||||
-DUSE_XPRESS=$(USE_XPRESS) \
|
||||
-DUSE_DOTNET_CORE_31=$(USE_DOTNET_CORE_31) \
|
||||
-DUSE_DOTNET_6=$(USE_DOTNET_6) \
|
||||
-DBUILD_VENV=$(BUILD_VENV) \
|
||||
@@ -665,7 +663,6 @@ detect_cpp:
|
||||
@echo USE_SCIP = $(USE_SCIP)
|
||||
@echo USE_GLPK = $(USE_GLPK)
|
||||
@echo USE_CPLEX = $(USE_CPLEX)
|
||||
@echo USE_XPRESS = $(USE_XPRESS)
|
||||
ifdef GLPK_ROOT
|
||||
@echo GLPK_ROOT = $(GLPK_ROOT)
|
||||
endif
|
||||
|
||||
@@ -143,18 +143,6 @@ config_setting(
|
||||
},
|
||||
)
|
||||
|
||||
bool_flag(
|
||||
name = "with_xpress",
|
||||
build_setting_default = False,
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "use_xpress",
|
||||
flag_values = {
|
||||
":with_xpress": "true",
|
||||
},
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "linear_solver_proto",
|
||||
srcs = ["linear_solver.proto"],
|
||||
@@ -187,6 +175,7 @@ cc_library(
|
||||
"linear_solver_callback.cc",
|
||||
"lpi_glop.cpp",
|
||||
"sat_interface.cc",
|
||||
"xpress_interface.cc",
|
||||
] + select({
|
||||
":use_bop": ["bop_interface.cc"],
|
||||
"//conditions:default": [],
|
||||
@@ -220,9 +209,6 @@ cc_library(
|
||||
}) + select({
|
||||
":use_cplex": ["cplex_interface.cc"],
|
||||
"//conditions:default": [],
|
||||
}) + select({
|
||||
":use_xpress": ["xpress_interface.cc"],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
hdrs = [
|
||||
"linear_expr.h",
|
||||
@@ -261,9 +247,6 @@ cc_library(
|
||||
}) + select({
|
||||
":use_cplex": ["-DUSE_CPLEX"],
|
||||
"//conditions:default": [],
|
||||
}) + select({
|
||||
":use_xpress": ["-DUSE_XPRESS"],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
deps = [
|
||||
":linear_solver_cc_proto",
|
||||
@@ -279,6 +262,7 @@ cc_library(
|
||||
"//ortools/base:stl_util",
|
||||
"//ortools/base:timer",
|
||||
"//ortools/gurobi:environment",
|
||||
"//ortools/xpress:environment",
|
||||
"//ortools/gurobi:gurobi_util",
|
||||
"//ortools/linear_solver/proto_solver:glop_proto_solver",
|
||||
"//ortools/linear_solver/proto_solver:gurobi_proto_solver",
|
||||
|
||||
@@ -16,6 +16,7 @@ list(REMOVE_ITEM _SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/solve.cc
|
||||
)
|
||||
list(FILTER _SRCS EXCLUDE REGEX "/model_exporter_main\\.cc")
|
||||
list(FILTER _SRCS EXCLUDE REGEX ".*/.*_test.cc")
|
||||
if(USE_SCIP)
|
||||
list(APPEND _SRCS ${LPI_GLOP_SRC})
|
||||
endif()
|
||||
@@ -44,7 +45,6 @@ target_link_libraries(${NAME} PRIVATE
|
||||
$<$<BOOL:${USE_HIGHS}>:HIGHS::HIGHS>
|
||||
$<$<BOOL:${USE_PDLP}>:Eigen3::Eigen>
|
||||
$<$<BOOL:${USE_SCIP}>:libscip>
|
||||
$<$<BOOL:${USE_XPRESS}>:XPRESS::XPRESS>
|
||||
${PROJECT_NAMESPACE}::${PROJECT_NAME}_proto)
|
||||
#add_library(${PROJECT_NAMESPACE}::linear_solver ALIAS ${NAME})
|
||||
|
||||
@@ -68,3 +68,18 @@ elseif(UNIX)
|
||||
endif()
|
||||
|
||||
install(TARGETS solve)
|
||||
|
||||
if (BUILD_CXX_EXAMPLES)
|
||||
if (APPLE)
|
||||
set(CMAKE_INSTALL_RPATH
|
||||
"@loader_path/../${CMAKE_INSTALL_LIBDIR};@loader_path")
|
||||
elseif (UNIX)
|
||||
set(CMAKE_INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}:$ORIGIN:$ORIGIN/../lib:$ORIGIN")
|
||||
endif ()
|
||||
|
||||
add_executable(test_xprs_interface xpress_interface_test.cc)
|
||||
target_compile_features(test_xprs_interface PRIVATE cxx_std_17)
|
||||
target_link_libraries(test_xprs_interface PRIVATE ortools::ortools GTest::gtest_main)
|
||||
|
||||
add_test(NAME cxx_unittests_xpress_interface COMMAND test_xprs_interface)
|
||||
endif ()
|
||||
|
||||
@@ -390,6 +390,7 @@ PROTO2_RETURN(
|
||||
%rename (suppressOutput) operations_research::MPSolver::SuppressOutput; // no test
|
||||
%rename (lookupConstraintOrNull) operations_research::MPSolver::LookupConstraintOrNull; // no test
|
||||
%rename (lookupVariableOrNull) operations_research::MPSolver::LookupVariableOrNull; // no test
|
||||
%rename (write) operations_research::MPSolver::Write;
|
||||
|
||||
// Expose very advanced parts of the MPSolver API. For expert users only.
|
||||
%rename (computeConstraintActivities) operations_research::MPSolver::ComputeConstraintActivities;
|
||||
|
||||
@@ -403,10 +403,9 @@ extern MPSolverInterface* BuildGurobiInterface(bool mip,
|
||||
#if defined(USE_CPLEX)
|
||||
extern MPSolverInterface* BuildCplexInterface(bool mip, MPSolver* const solver);
|
||||
#endif
|
||||
#if defined(USE_XPRESS)
|
||||
extern MPSolverInterface* BuildXpressInterface(bool mip,
|
||||
MPSolver* const solver);
|
||||
#endif
|
||||
|
||||
|
||||
namespace {
|
||||
MPSolverInterface* BuildSolverInterface(MPSolver* const solver) {
|
||||
@@ -460,12 +459,10 @@ MPSolverInterface* BuildSolverInterface(MPSolver* const 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.
|
||||
LOG(FATAL) << "Linear solver not recognized.";
|
||||
@@ -501,6 +498,7 @@ MPSolver::MPSolver(const std::string& name,
|
||||
MPSolver::~MPSolver() { Clear(); }
|
||||
|
||||
extern bool GurobiIsCorrectlyInstalled();
|
||||
extern bool XpressIsCorrectlyInstalled();
|
||||
|
||||
// static
|
||||
bool MPSolver::SupportsProblemType(OptimizationProblemType problem_type) {
|
||||
@@ -545,12 +543,10 @@ bool MPSolver::SupportsProblemType(OptimizationProblemType problem_type) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_XPRESS
|
||||
if (problem_type == XPRESS_MIXED_INTEGER_PROGRAMMING ||
|
||||
problem_type == XPRESS_LINEAR_PROGRAMMING) {
|
||||
return true;
|
||||
return XpressIsCorrectlyInstalled();
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1661,7 +1661,7 @@ class MPSolverInterface {
|
||||
}
|
||||
|
||||
// Writes the model using the solver internal write function. Currently only
|
||||
// available for GurobiInterface.
|
||||
// available for GurobiInterface and XpressInterface.
|
||||
virtual void Write(const std::string& filename);
|
||||
|
||||
// ----- Model modifications and extraction -----
|
||||
|
||||
@@ -366,6 +366,7 @@ PY_CONVERT(MPVariable);
|
||||
%unignore operations_research::MPSolver::NextSolution;
|
||||
// ExportModelAsLpFormat() is also visible: it's overridden by an %extend, above.
|
||||
// ExportModelAsMpsFormat() is also visible: it's overridden by an %extend, above.
|
||||
%unignore operations_research::MPSolver::Write;
|
||||
|
||||
// Expose very advanced parts of the MPSolver API. For expert users only.
|
||||
%unignore operations_research::MPSolver::ComputeConstraintActivities;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1362
ortools/linear_solver/xpress_interface_test.cc
Normal file
1362
ortools/linear_solver/xpress_interface_test.cc
Normal file
File diff suppressed because it is too large
Load Diff
22
ortools/xpress/BUILD.bazel
Normal file
22
ortools/xpress/BUILD.bazel
Normal file
@@ -0,0 +1,22 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
cc_library(
|
||||
name = "environment",
|
||||
srcs = [
|
||||
"environment.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"environment.h",
|
||||
],
|
||||
deps = [
|
||||
"//ortools/base",
|
||||
"//ortools/base:dynamic_library",
|
||||
"//ortools/base:file",
|
||||
"//ortools/base:status_macros",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@com_google_absl//absl/types:optional",
|
||||
],
|
||||
)
|
||||
21
ortools/xpress/CMakeLists.txt
Normal file
21
ortools/xpress/CMakeLists.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
file(GLOB _SRCS "*.h" "*.cc")
|
||||
set(NAME ${PROJECT_NAME}_xpress)
|
||||
|
||||
add_library(${NAME} OBJECT ${_SRCS})
|
||||
set_target_properties(${NAME} PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS OFF
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
)
|
||||
target_include_directories(${NAME} PRIVATE
|
||||
${PROJECT_SOURCE_DIR}
|
||||
${PROJECT_BINARY_DIR})
|
||||
target_link_libraries(${NAME} PRIVATE
|
||||
absl::hash
|
||||
absl::meta
|
||||
absl::memory
|
||||
absl::strings
|
||||
absl::str_format
|
||||
protobuf::libprotobuf
|
||||
${PROJECT_NAMESPACE}::${PROJECT_NAME}_proto)
|
||||
362
ortools/xpress/environment.cc
Normal file
362
ortools/xpress/environment.cc
Normal file
@@ -0,0 +1,362 @@
|
||||
// Copyright 2019-2023 RTE
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Initial version of this code was provided by RTE
|
||||
|
||||
#include "ortools/xpress/environment.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/strings/match.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_join.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "ortools/base/logging.h"
|
||||
|
||||
namespace operations_research {
|
||||
|
||||
#define STRINGIFY2(X) #X
|
||||
#define STRINGIFY(X) STRINGIFY2(X)
|
||||
|
||||
// This was generated with the parse_header_xpress.py script.
|
||||
// See the comment at the top of the script.
|
||||
|
||||
// This is the 'define' section.
|
||||
std::function<int(XPRSprob* p_prob)> XPRScreateprob = nullptr;
|
||||
std::function<int(XPRSprob prob)> XPRSdestroyprob = nullptr;
|
||||
std::function<int(const char* path)> XPRSinit = nullptr;
|
||||
std::function<int(void)> XPRSfree = nullptr;
|
||||
std::function<int(char* buffer, int maxbytes)> XPRSgetlicerrmsg = nullptr;
|
||||
std::function<int(int* p_i, char* p_c)> XPRSlicense = nullptr;
|
||||
std::function<int(char* banner)> XPRSgetbanner = nullptr;
|
||||
std::function<int(char* version)> XPRSgetversion = nullptr;
|
||||
std::function<int(XPRSprob prob, int control)> XPRSsetdefaultcontrol = nullptr;
|
||||
std::function<int(XPRSprob prob, int reason)> XPRSinterrupt = nullptr;
|
||||
std::function<int(XPRSprob prob, int control, int value)> XPRSsetintcontrol = nullptr;
|
||||
std::function<int(XPRSprob prob, int control, XPRSint64 value)> XPRSsetintcontrol64 = nullptr;
|
||||
std::function<int(XPRSprob prob, int control, double value)> XPRSsetdblcontrol = nullptr;
|
||||
std::function<int(XPRSprob prob, int control, const char* value)> XPRSsetstrcontrol = nullptr;
|
||||
std::function<int(XPRSprob prob, int control, int* p_value)> XPRSgetintcontrol = nullptr;
|
||||
std::function<int(XPRSprob prob, int control, XPRSint64* p_value)> XPRSgetintcontrol64 = nullptr;
|
||||
std::function<int(XPRSprob prob, int control, double* p_value)> XPRSgetdblcontrol = nullptr;
|
||||
std::function<int(XPRSprob prob, int control, char* value, int maxbytes, int* p_nbytes)> XPRSgetstringcontrol = nullptr;
|
||||
std::function<int(XPRSprob prob, int attrib, int* p_value)> XPRSgetintattrib = nullptr;
|
||||
std::function<int(XPRSprob prob, int attrib, double* p_value)> XPRSgetdblattrib = nullptr;
|
||||
std::function<int(XPRSprob prob, const char* name, int* p_id, int* p_type)> XPRSgetcontrolinfo = nullptr;
|
||||
std::function<int(XPRSprob prob, const char* probname, int ncols, int nrows, const char rowtype[], const double rhs[], const double rng[], const double objcoef[], const int start[], const int collen[], const int rowind[], const double rowcoef[], const double lb[], const double ub[])> XPRSloadlp = nullptr;
|
||||
std::function<int(XPRSprob prob, const char* probname, int ncols, int nrows, const char rowtype[], const double rhs[], const double rng[], const double objcoef[], const XPRSint64 start[], const int collen[], const int rowind[], const double rowcoef[], const double lb[], const double ub[])> XPRSloadlp64 = nullptr;
|
||||
std::function<int(XPRSprob prob, double objcoef[], int first, int last)> XPRSgetobj = nullptr;
|
||||
std::function<int(XPRSprob prob, double rhs[], int first, int last)> XPRSgetrhs = nullptr;
|
||||
std::function<int(XPRSprob prob, double rng[], int first, int last)> XPRSgetrhsrange = nullptr;
|
||||
std::function<int(XPRSprob prob, double lb[], int first, int last)> XPRSgetlb = nullptr;
|
||||
std::function<int(XPRSprob prob, double ub[], int first, int last)> XPRSgetub = nullptr;
|
||||
std::function<int(XPRSprob prob, int row, int col, double* p_coef)> XPRSgetcoef = nullptr;
|
||||
std::function<int(XPRSprob prob, int nrows, int ncoefs, const char rowtype[], const double rhs[], const double rng[], const int start[], const int colind[], const double rowcoef[])> XPRSaddrows = nullptr;
|
||||
std::function<int(XPRSprob prob, int nrows, const int rowind[])> XPRSdelrows = nullptr;
|
||||
std::function<int(XPRSprob prob, int ncols, int ncoefs, const double objcoef[], const int start[], const int rowind[], const double rowcoef[], const double lb[], const double ub[])> XPRSaddcols = nullptr;
|
||||
std::function<int(XPRSprob prob, int type, const char names[], int first, int last)> XPRSaddnames = nullptr;
|
||||
std::function<int(XPRSprob prob, int type, char names[], int first, int last)> XPRSgetnames = nullptr;
|
||||
std::function<int(XPRSprob prob, int ncols, const int colind[])> XPRSdelcols = nullptr;
|
||||
std::function<int(XPRSprob prob, int ncols, const int colind[], const char coltype[])> XPRSchgcoltype = nullptr;
|
||||
std::function<int(XPRSprob prob, const int rowstat[], const int colstat[])> XPRSloadbasis = nullptr;
|
||||
std::function<int(XPRSprob prob)> XPRSpostsolve = nullptr;
|
||||
std::function<int(XPRSprob prob, int objsense)> XPRSchgobjsense = nullptr;
|
||||
std::function<int(XPRSprob prob, char* errmsg)> XPRSgetlasterror = nullptr;
|
||||
std::function<int(XPRSprob prob, int rowstat[], int colstat[])> XPRSgetbasis = nullptr;
|
||||
std::function<int(XPRSprob prob, const char* filename, const char* flags)> XPRSwriteprob = nullptr;
|
||||
std::function<int(XPRSprob prob, char rowtype[], int first, int last)> XPRSgetrowtype = nullptr;
|
||||
std::function<int(XPRSprob prob, char coltype[], int first, int last)> XPRSgetcoltype = nullptr;
|
||||
std::function<int(XPRSprob prob, int nbounds, const int colind[], const char bndtype[], const double bndval[])> XPRSchgbounds = nullptr;
|
||||
std::function<int(XPRSprob prob, int length, const double solval[], const int colind[], const char* name)> XPRSaddmipsol = nullptr;
|
||||
std::function<int(XPRSprob prob, double x[], double slack[], double duals[], double djs[])> XPRSgetlpsol = nullptr;
|
||||
std::function<int(XPRSprob prob, double x[], double slack[])> XPRSgetmipsol = nullptr;
|
||||
std::function<int(XPRSprob prob, int ncols, const int colind[], const double objcoef[])> XPRSchgobj = nullptr;
|
||||
std::function<int(XPRSprob prob, int row, int col, double coef)> XPRSchgcoef = nullptr;
|
||||
std::function<int(XPRSprob prob, int ncoefs, const int rowind[], const int colind[], const double rowcoef[])> XPRSchgmcoef = nullptr;
|
||||
std::function<int(XPRSprob prob, int nrows, const int rowind[], const double rhs[])> XPRSchgrhs = nullptr;
|
||||
std::function<int(XPRSprob prob, int nrows, const int rowind[], const double rng[])> XPRSchgrhsrange = nullptr;
|
||||
std::function<int(XPRSprob prob, int nrows, const int rowind[], const char rowtype[])> XPRSchgrowtype = nullptr;
|
||||
std::function<int(XPRSprob prob, void (XPRS_CC *f_intsol)(XPRSprob cbprob, void* cbdata), void* p, int priority)> XPRSaddcbintsol = nullptr;
|
||||
std::function<int(XPRSprob prob, void (XPRS_CC *f_intsol)(XPRSprob cbprob, void* cbdata), void* p)> XPRSremovecbintsol = nullptr;
|
||||
std::function<int(XPRSprob prob, void (XPRS_CC *f_message)(XPRSprob cbprob, void* cbdata, const char* msg, int msglen, int msgtype), void* p, int priority)> XPRSaddcbmessage = nullptr;
|
||||
std::function<int(XPRSprob prob, const char* flags)> XPRSlpoptimize = nullptr;
|
||||
std::function<int(XPRSprob prob, const char* flags)> XPRSmipoptimize = nullptr;
|
||||
|
||||
void LoadXpressFunctions(DynamicLibrary* xpress_dynamic_library) {
|
||||
// This was generated with the parse_header_xpress.py script.
|
||||
// See the comment at the top of the script.
|
||||
|
||||
// This is the 'assign' section.
|
||||
xpress_dynamic_library->GetFunction(&XPRScreateprob, "XPRScreateprob");
|
||||
xpress_dynamic_library->GetFunction(&XPRSdestroyprob, "XPRSdestroyprob");
|
||||
xpress_dynamic_library->GetFunction(&XPRSinit, "XPRSinit");
|
||||
xpress_dynamic_library->GetFunction(&XPRSfree, "XPRSfree");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetlicerrmsg, "XPRSgetlicerrmsg");
|
||||
xpress_dynamic_library->GetFunction(&XPRSlicense, "XPRSlicense");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetbanner, "XPRSgetbanner");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetversion, "XPRSgetversion");
|
||||
xpress_dynamic_library->GetFunction(&XPRSsetdefaultcontrol, "XPRSsetdefaultcontrol");
|
||||
xpress_dynamic_library->GetFunction(&XPRSinterrupt, "XPRSinterrupt");
|
||||
xpress_dynamic_library->GetFunction(&XPRSsetintcontrol, "XPRSsetintcontrol");
|
||||
xpress_dynamic_library->GetFunction(&XPRSsetintcontrol64, "XPRSsetintcontrol64");
|
||||
xpress_dynamic_library->GetFunction(&XPRSsetdblcontrol, "XPRSsetdblcontrol");
|
||||
xpress_dynamic_library->GetFunction(&XPRSsetstrcontrol, "XPRSsetstrcontrol");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetintcontrol, "XPRSgetintcontrol");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetintcontrol64, "XPRSgetintcontrol64");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetdblcontrol, "XPRSgetdblcontrol");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetstringcontrol, "XPRSgetstringcontrol");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetintattrib, "XPRSgetintattrib");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetdblattrib, "XPRSgetdblattrib");
|
||||
xpress_dynamic_library->GetFunction(&XPRSloadlp, "XPRSloadlp");
|
||||
xpress_dynamic_library->GetFunction(&XPRSloadlp64, "XPRSloadlp64");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetobj, "XPRSgetobj");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetrhs, "XPRSgetrhs");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetrhsrange, "XPRSgetrhsrange");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetlb, "XPRSgetlb");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetub, "XPRSgetub");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetcoef, "XPRSgetcoef");
|
||||
xpress_dynamic_library->GetFunction(&XPRSaddrows, "XPRSaddrows");
|
||||
xpress_dynamic_library->GetFunction(&XPRSdelrows, "XPRSdelrows");
|
||||
xpress_dynamic_library->GetFunction(&XPRSaddcols, "XPRSaddcols");
|
||||
xpress_dynamic_library->GetFunction(&XPRSaddnames, "XPRSaddnames");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetnames, "XPRSgetnames");
|
||||
xpress_dynamic_library->GetFunction(&XPRSdelcols, "XPRSdelcols");
|
||||
xpress_dynamic_library->GetFunction(&XPRSchgcoltype, "XPRSchgcoltype");
|
||||
xpress_dynamic_library->GetFunction(&XPRSloadbasis, "XPRSloadbasis");
|
||||
xpress_dynamic_library->GetFunction(&XPRSpostsolve, "XPRSpostsolve");
|
||||
xpress_dynamic_library->GetFunction(&XPRSchgobjsense, "XPRSchgobjsense");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetlasterror, "XPRSgetlasterror");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetbasis, "XPRSgetbasis");
|
||||
xpress_dynamic_library->GetFunction(&XPRSwriteprob, "XPRSwriteprob");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetrowtype, "XPRSgetrowtype");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetcoltype, "XPRSgetcoltype");
|
||||
xpress_dynamic_library->GetFunction(&XPRSchgbounds, "XPRSchgbounds");
|
||||
xpress_dynamic_library->GetFunction(&XPRSaddmipsol, "XPRSaddmipsol");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetlpsol, "XPRSgetlpsol");
|
||||
xpress_dynamic_library->GetFunction(&XPRSgetmipsol, "XPRSgetmipsol");
|
||||
xpress_dynamic_library->GetFunction(&XPRSchgobj, "XPRSchgobj");
|
||||
xpress_dynamic_library->GetFunction(&XPRSchgcoef, "XPRSchgcoef");
|
||||
xpress_dynamic_library->GetFunction(&XPRSchgmcoef, "XPRSchgmcoef");
|
||||
xpress_dynamic_library->GetFunction(&XPRSchgrhs, "XPRSchgrhs");
|
||||
xpress_dynamic_library->GetFunction(&XPRSchgrhsrange, "XPRSchgrhsrange");
|
||||
xpress_dynamic_library->GetFunction(&XPRSchgrowtype, "XPRSchgrowtype");
|
||||
xpress_dynamic_library->GetFunction(&XPRSaddcbintsol, "XPRSaddcbintsol");
|
||||
xpress_dynamic_library->GetFunction(&XPRSremovecbintsol, "XPRSremovecbintsol");
|
||||
xpress_dynamic_library->GetFunction(&XPRSaddcbmessage, "XPRSaddcbmessage");
|
||||
xpress_dynamic_library->GetFunction(&XPRSlpoptimize, "XPRSlpoptimize");
|
||||
xpress_dynamic_library->GetFunction(&XPRSmipoptimize, "XPRSmipoptimize");
|
||||
}
|
||||
|
||||
void printXpressBanner(bool error) {
|
||||
char banner[XPRS_MAXBANNERLENGTH];
|
||||
XPRSgetbanner(banner);
|
||||
|
||||
if (error) {
|
||||
LOG(ERROR) << "XpressInterface : Xpress banner :\n" << banner << "\n";
|
||||
} else {
|
||||
LOG(WARNING) << "XpressInterface : Xpress banner :\n" << banner << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> XpressDynamicLibraryPotentialPaths() {
|
||||
std::vector<std::string> potential_paths;
|
||||
|
||||
// Look for libraries pointed by XPRESSDIR first.
|
||||
const char* xpressdir_from_env = getenv("XPRESSDIR");
|
||||
if (xpressdir_from_env != nullptr) {
|
||||
LOG(INFO) << "Environment variable XPRESSDIR = " << xpressdir_from_env;
|
||||
#if defined(_MSC_VER) // Windows
|
||||
potential_paths.push_back(
|
||||
absl::StrCat(xpressdir_from_env, "\\bin\\xprs.dll"));
|
||||
#elif defined(__APPLE__) // OS X
|
||||
potential_paths.push_back(
|
||||
absl::StrCat(xpressdir_from_env, "/lib/libxprs.dylib"));
|
||||
#elif defined(__GNUC__) // Linux
|
||||
potential_paths.push_back(
|
||||
absl::StrCat(xpressdir_from_env, "/lib/libxprs.so"));
|
||||
#else
|
||||
LOG(ERROR) << "OS Not recognized by xpress/environment.cc."
|
||||
<< " You won't be able to use Xpress.";
|
||||
#endif
|
||||
} else {
|
||||
LOG(WARNING) << "Environment variable XPRESSDIR undefined.";
|
||||
}
|
||||
|
||||
// Search for canonical places.
|
||||
#if defined(_MSC_VER) // Windows
|
||||
potential_paths.push_back(absl::StrCat("C:\\xpressmp\\bin\\xprs.dll"));
|
||||
potential_paths.push_back(
|
||||
absl::StrCat("C:\\Program Files\\xpressmp\\bin\\xprs.dll"));
|
||||
#elif defined(__APPLE__) // OS X
|
||||
potential_paths.push_back(
|
||||
absl::StrCat("/Library/xpressmp/lib/libxprs.dylib"));
|
||||
#elif defined(__GNUC__) // Linux
|
||||
potential_paths.push_back(absl::StrCat("/opt/xpressmp/lib/libxprs.so"));
|
||||
#else
|
||||
LOG(ERROR) << "OS Not recognized by xpress/environment.cc."
|
||||
<< " You won't be able to use Xpress.";
|
||||
#endif
|
||||
return potential_paths;
|
||||
}
|
||||
|
||||
absl::Status LoadXpressDynamicLibrary(std::string& xpresspath) {
|
||||
static std::string xpress_lib_path;
|
||||
static std::once_flag xpress_loading_done;
|
||||
static absl::Status xpress_load_status;
|
||||
static DynamicLibrary xpress_library;
|
||||
static absl::Mutex mutex;
|
||||
|
||||
absl::MutexLock lock(&mutex);
|
||||
|
||||
std::call_once(xpress_loading_done, []() {
|
||||
const std::vector<std::string> canonical_paths =
|
||||
XpressDynamicLibraryPotentialPaths();
|
||||
for (const std::string& path : canonical_paths) {
|
||||
if (xpress_library.TryToLoad(path)) {
|
||||
LOG(INFO) << "Found the Xpress library in " << path << ".";
|
||||
xpress_lib_path.clear();
|
||||
std::filesystem::path p(path);
|
||||
p.remove_filename();
|
||||
xpress_lib_path.append(p.string());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (xpress_library.LibraryIsLoaded()) {
|
||||
LOG(INFO) << "Loading all Xpress functions";
|
||||
LoadXpressFunctions(&xpress_library);
|
||||
xpress_load_status = absl::OkStatus();
|
||||
} else {
|
||||
xpress_load_status = absl::NotFoundError(
|
||||
absl::StrCat("Could not find the Xpress shared library. Looked in: [",
|
||||
absl::StrJoin(canonical_paths, "', '"),
|
||||
"]. Please check environment variable XPRESSDIR"));
|
||||
}
|
||||
});
|
||||
xpresspath.clear();
|
||||
xpresspath.append(xpress_lib_path);
|
||||
return xpress_load_status;
|
||||
}
|
||||
|
||||
void log_message_about_XPRSinit_argument();
|
||||
void log_full_license_error(int code, const std::string& xpress_lib_dir);
|
||||
/** init XPRESS environment */
|
||||
bool initXpressEnv(bool verbose, int xpress_oem_license_key) {
|
||||
std::string xpress_lib_dir;
|
||||
absl::Status status = LoadXpressDynamicLibrary(xpress_lib_dir);
|
||||
if (!status.ok()) {
|
||||
LOG(WARNING) << status << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
int code;
|
||||
// if not an OEM key
|
||||
if (xpress_oem_license_key == 0) {
|
||||
if (verbose) {
|
||||
log_message_about_XPRSinit_argument();
|
||||
}
|
||||
|
||||
code = XPRSinit(nullptr);
|
||||
|
||||
if (!code) {
|
||||
// XPRSbanner informs about Xpress version, options and error messages
|
||||
if (verbose) {
|
||||
printXpressBanner(false);
|
||||
char version[16];
|
||||
XPRSgetversion(version);
|
||||
LOG(WARNING) << "Optimizer version: " << version
|
||||
<< " (OR-Tools was compiled with version " << XPVERSION
|
||||
<< ").\n";
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
log_full_license_error(code, xpress_lib_dir);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// if OEM key
|
||||
if (verbose) {
|
||||
LOG(WARNING) << "XpressInterface : Initialising xpress-MP with OEM key "
|
||||
<< xpress_oem_license_key << "\n";
|
||||
}
|
||||
|
||||
int nvalue = 0;
|
||||
int ierr;
|
||||
char slicmsg[256] = "";
|
||||
char errmsg[256];
|
||||
|
||||
XPRSlicense(&nvalue, slicmsg);
|
||||
if (verbose) {
|
||||
VLOG(0) << "XpressInterface : First message from XPRSLicense : "
|
||||
<< slicmsg << "\n";
|
||||
}
|
||||
|
||||
nvalue = xpress_oem_license_key - ((nvalue * nvalue) / 19);
|
||||
ierr = XPRSlicense(&nvalue, slicmsg);
|
||||
|
||||
if (verbose) {
|
||||
VLOG(0) << "XpressInterface : Second message from XPRSLicense : "
|
||||
<< slicmsg << "\n";
|
||||
}
|
||||
if (ierr == 16) {
|
||||
if (verbose) {
|
||||
VLOG(0)
|
||||
<< "XpressInterface : Optimizer development software detected\n";
|
||||
}
|
||||
} else if (ierr != 0) {
|
||||
// get the license error message
|
||||
XPRSgetlicerrmsg(errmsg, 256);
|
||||
|
||||
LOG(ERROR) << "XpressInterface : " << errmsg << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
code = XPRSinit(NULL);
|
||||
|
||||
if (!code) {
|
||||
return true;
|
||||
} else {
|
||||
LOG(ERROR) << "XPRSinit returned code : " << code << "\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
void log_full_license_error(int code, const std::string& xpress_lib_dir) {
|
||||
LOG(WARNING) << "XpressInterface: Xpress found at " << xpress_lib_dir
|
||||
<< "\n";
|
||||
char errmsg[256];
|
||||
XPRSgetlicerrmsg(errmsg, 256);
|
||||
|
||||
LOG(ERROR) << "XpressInterface : License error : " << errmsg
|
||||
<< " (XPRSinit returned code " << code << "). \n";
|
||||
LOG(ERROR)
|
||||
<< "|_Your Xpress installation should have set the env var XPAUTH_PATH"
|
||||
" to the full path of your licence file\n";
|
||||
}
|
||||
void log_message_about_XPRSinit_argument() {
|
||||
LOG(WARNING)
|
||||
<< "XpressInterface : Initialising xpress-MP with default parameters";
|
||||
}
|
||||
|
||||
bool XpressIsCorrectlyInstalled() {
|
||||
bool correctlyInstalled = initXpressEnv(false);
|
||||
if (correctlyInstalled) {
|
||||
XPRSfree();
|
||||
}
|
||||
return correctlyInstalled;
|
||||
}
|
||||
|
||||
} // namespace operations_research
|
||||
499
ortools/xpress/environment.h
Normal file
499
ortools/xpress/environment.h
Normal file
@@ -0,0 +1,499 @@
|
||||
// Copyright 2019-2023 RTE
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Initial version of this code was provided by RTE
|
||||
|
||||
#ifndef OR_TOOLS_XPRESS_ENVIRONMENT_H
|
||||
#define OR_TOOLS_XPRESS_ENVIRONMENT_H
|
||||
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/status/statusor.h"
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include "ortools/base/dynamic_library.h"
|
||||
#include "ortools/base/logging.h"
|
||||
|
||||
extern "C" {
|
||||
typedef struct xo_prob_struct* XPRSprob;
|
||||
}
|
||||
|
||||
namespace operations_research {
|
||||
|
||||
void printXpressBanner(bool error);
|
||||
|
||||
bool initXpressEnv(bool verbose = true, int xpress_oem_license_key = 0);
|
||||
|
||||
bool XpressIsCorrectlyInstalled();
|
||||
// clang-format off
|
||||
// Force the loading of the xpress dynamic library. It returns true if the
|
||||
// library was successfully loaded. This method can only be called once.
|
||||
// Successive calls are no-op.
|
||||
//
|
||||
// Note that it does not check if a token license can be grabbed.
|
||||
absl::Status LoadXpressDynamicLibrary(std::string &xpresspath);
|
||||
|
||||
// The list of #define and extern std::function<> below is generated directly
|
||||
// from xprs.h via parse_header_xpress.py
|
||||
// See the top comment on the parse_header_xpress.py file.
|
||||
// This is the header section
|
||||
#if defined(_WIN32)
|
||||
#define XPRSint64 __int64
|
||||
#elif defined(__LP64__) || defined(_LP64) || defined(__ILP64__) || defined(_ILP64)
|
||||
#define XPRSint64 long
|
||||
#else
|
||||
#define XPRSint64 long long
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define XPRS_CC __stdcall
|
||||
#else
|
||||
#define XPRS_CC
|
||||
#endif
|
||||
/***************************************************************************\
|
||||
* values related to XPRSinterrupt *
|
||||
\***************************************************************************/
|
||||
#define XPRS_STOP_NONE 0
|
||||
#define XPRS_STOP_TIMELIMIT 1
|
||||
#define XPRS_STOP_CTRLC 2
|
||||
#define XPRS_STOP_NODELIMIT 3
|
||||
#define XPRS_STOP_ITERLIMIT 4
|
||||
#define XPRS_STOP_MIPGAP 5
|
||||
#define XPRS_STOP_SOLLIMIT 6
|
||||
#define XPRS_STOP_GENERICERROR 7
|
||||
#define XPRS_STOP_MEMORYERROR 8
|
||||
#define XPRS_STOP_USER 9
|
||||
#define XPRS_STOP_SOLVECOMPLETE 10
|
||||
#define XPRS_STOP_LICENSELOST 11
|
||||
#define XPRS_STOP_NUMERICALERROR 13
|
||||
/***************************************************************************\
|
||||
* values related to Set/GetControl/Attribinfo *
|
||||
\***************************************************************************/
|
||||
#define XPRS_TYPE_NOTDEFINED 0
|
||||
#define XPRS_TYPE_INT 1
|
||||
#define XPRS_TYPE_INT64 2
|
||||
#define XPRS_TYPE_DOUBLE 3
|
||||
#define XPRS_TYPE_STRING 4
|
||||
/***************************************************************************\
|
||||
* values related to NAMESPACES *
|
||||
\***************************************************************************/
|
||||
#define XPRS_NAMES_ROW 1
|
||||
#define XPRS_NAMES_COLUMN 2
|
||||
|
||||
|
||||
#define XPRS_PLUSINFINITY 1.0e+20
|
||||
#define XPRS_MINUSINFINITY -1.0e+20
|
||||
#define XPRS_MAXBANNERLENGTH 512
|
||||
#define XPVERSION 41
|
||||
#define XPRS_MPSRHSNAME 6001
|
||||
#define XPRS_MPSOBJNAME 6002
|
||||
#define XPRS_MPSRANGENAME 6003
|
||||
#define XPRS_MPSBOUNDNAME 6004
|
||||
#define XPRS_OUTPUTMASK 6005
|
||||
#define XPRS_TUNERMETHODFILE 6017
|
||||
#define XPRS_TUNEROUTPUTPATH 6018
|
||||
#define XPRS_TUNERSESSIONNAME 6019
|
||||
#define XPRS_COMPUTEEXECSERVICE 6022
|
||||
#define XPRS_MAXCUTTIME 8149
|
||||
#define XPRS_MAXSTALLTIME 8443
|
||||
#define XPRS_TUNERMAXTIME 8364
|
||||
#define XPRS_MATRIXTOL 7001
|
||||
#define XPRS_PIVOTTOL 7002
|
||||
#define XPRS_FEASTOL 7003
|
||||
#define XPRS_OUTPUTTOL 7004
|
||||
#define XPRS_SOSREFTOL 7005
|
||||
#define XPRS_OPTIMALITYTOL 7006
|
||||
#define XPRS_ETATOL 7007
|
||||
#define XPRS_RELPIVOTTOL 7008
|
||||
#define XPRS_MIPTOL 7009
|
||||
#define XPRS_MIPTOLTARGET 7010
|
||||
#define XPRS_BARPERTURB 7011
|
||||
#define XPRS_MIPADDCUTOFF 7012
|
||||
#define XPRS_MIPABSCUTOFF 7013
|
||||
#define XPRS_MIPRELCUTOFF 7014
|
||||
#define XPRS_PSEUDOCOST 7015
|
||||
#define XPRS_PENALTY 7016
|
||||
#define XPRS_BIGM 7018
|
||||
#define XPRS_MIPABSSTOP 7019
|
||||
#define XPRS_MIPRELSTOP 7020
|
||||
#define XPRS_CROSSOVERACCURACYTOL 7023
|
||||
#define XPRS_PRIMALPERTURB 7024
|
||||
#define XPRS_DUALPERTURB 7025
|
||||
#define XPRS_BAROBJSCALE 7026
|
||||
#define XPRS_BARRHSSCALE 7027
|
||||
#define XPRS_CHOLESKYTOL 7032
|
||||
#define XPRS_BARGAPSTOP 7033
|
||||
#define XPRS_BARDUALSTOP 7034
|
||||
#define XPRS_BARPRIMALSTOP 7035
|
||||
#define XPRS_BARSTEPSTOP 7036
|
||||
#define XPRS_ELIMTOL 7042
|
||||
#define XPRS_MARKOWITZTOL 7047
|
||||
#define XPRS_MIPABSGAPNOTIFY 7064
|
||||
#define XPRS_MIPRELGAPNOTIFY 7065
|
||||
#define XPRS_BARLARGEBOUND 7067
|
||||
#define XPRS_PPFACTOR 7069
|
||||
#define XPRS_REPAIRINDEFINITEQMAX 7071
|
||||
#define XPRS_BARGAPTARGET 7073
|
||||
#define XPRS_DUMMYCONTROL 7075
|
||||
#define XPRS_BARSTARTWEIGHT 7076
|
||||
#define XPRS_BARFREESCALE 7077
|
||||
#define XPRS_SBEFFORT 7086
|
||||
#define XPRS_HEURDIVERANDOMIZE 7089
|
||||
#define XPRS_HEURSEARCHEFFORT 7090
|
||||
#define XPRS_CUTFACTOR 7091
|
||||
#define XPRS_EIGENVALUETOL 7097
|
||||
#define XPRS_INDLINBIGM 7099
|
||||
#define XPRS_TREEMEMORYSAVINGTARGET 7100
|
||||
#define XPRS_INDPRELINBIGM 7102
|
||||
#define XPRS_RELAXTREEMEMORYLIMIT 7105
|
||||
#define XPRS_MIPABSGAPNOTIFYOBJ 7108
|
||||
#define XPRS_MIPABSGAPNOTIFYBOUND 7109
|
||||
#define XPRS_PRESOLVEMAXGROW 7110
|
||||
#define XPRS_HEURSEARCHTARGETSIZE 7112
|
||||
#define XPRS_CROSSOVERRELPIVOTTOL 7113
|
||||
#define XPRS_CROSSOVERRELPIVOTTOLSAFE 7114
|
||||
#define XPRS_DETLOGFREQ 7116
|
||||
#define XPRS_MAXIMPLIEDBOUND 7120
|
||||
#define XPRS_FEASTOLTARGET 7121
|
||||
#define XPRS_OPTIMALITYTOLTARGET 7122
|
||||
#define XPRS_PRECOMPONENTSEFFORT 7124
|
||||
#define XPRS_LPLOGDELAY 7127
|
||||
#define XPRS_HEURDIVEITERLIMIT 7128
|
||||
#define XPRS_BARKERNEL 7130
|
||||
#define XPRS_FEASTOLPERTURB 7132
|
||||
#define XPRS_CROSSOVERFEASWEIGHT 7133
|
||||
#define XPRS_LUPIVOTTOL 7139
|
||||
#define XPRS_MIPRESTARTGAPTHRESHOLD 7140
|
||||
#define XPRS_NODEPROBINGEFFORT 7141
|
||||
#define XPRS_INPUTTOL 7143
|
||||
#define XPRS_MIPRESTARTFACTOR 7145
|
||||
#define XPRS_BAROBJPERTURB 7146
|
||||
#define XPRS_CPIALPHA 7149
|
||||
#define XPRS_GLOBALBOUNDINGBOX 7154
|
||||
#define XPRS_TIMELIMIT 7158
|
||||
#define XPRS_SOLTIMELIMIT 7159
|
||||
#define XPRS_REPAIRINFEASTIMELIMIT 7160
|
||||
#define XPRS_EXTRAROWS 8004
|
||||
#define XPRS_EXTRACOLS 8005
|
||||
#define XPRS_LPITERLIMIT 8007
|
||||
#define XPRS_LPLOG 8009
|
||||
#define XPRS_SCALING 8010
|
||||
#define XPRS_PRESOLVE 8011
|
||||
#define XPRS_CRASH 8012
|
||||
#define XPRS_PRICINGALG 8013
|
||||
#define XPRS_INVERTFREQ 8014
|
||||
#define XPRS_INVERTMIN 8015
|
||||
#define XPRS_MAXNODE 8018
|
||||
#define XPRS_MAXTIME 8020
|
||||
#define XPRS_MAXMIPSOL 8021
|
||||
#define XPRS_SIFTPASSES 8022
|
||||
#define XPRS_DEFAULTALG 8023
|
||||
#define XPRS_VARSELECTION 8025
|
||||
#define XPRS_NODESELECTION 8026
|
||||
#define XPRS_BACKTRACK 8027
|
||||
#define XPRS_MIPLOG 8028
|
||||
#define XPRS_KEEPNROWS 8030
|
||||
#define XPRS_MPSECHO 8032
|
||||
#define XPRS_MAXPAGELINES 8034
|
||||
#define XPRS_OUTPUTLOG 8035
|
||||
#define XPRS_BARSOLUTION 8038
|
||||
#define XPRS_CACHESIZE 8043
|
||||
#define XPRS_CROSSOVER 8044
|
||||
#define XPRS_BARITERLIMIT 8045
|
||||
#define XPRS_CHOLESKYALG 8046
|
||||
#define XPRS_BAROUTPUT 8047
|
||||
#define XPRS_EXTRAMIPENTS 8051
|
||||
#define XPRS_REFACTOR 8052
|
||||
#define XPRS_BARTHREADS 8053
|
||||
#define XPRS_KEEPBASIS 8054
|
||||
#define XPRS_CROSSOVEROPS 8060
|
||||
#define XPRS_VERSION 8061
|
||||
#define XPRS_CROSSOVERTHREADS 8065
|
||||
#define XPRS_BIGMMETHOD 8068
|
||||
#define XPRS_MPSNAMELENGTH 8071
|
||||
#define XPRS_ELIMFILLIN 8073
|
||||
#define XPRS_PRESOLVEOPS 8077
|
||||
#define XPRS_MIPPRESOLVE 8078
|
||||
#define XPRS_MIPTHREADS 8079
|
||||
#define XPRS_BARORDER 8080
|
||||
#define XPRS_BREADTHFIRST 8082
|
||||
#define XPRS_AUTOPERTURB 8084
|
||||
#define XPRS_DENSECOLLIMIT 8086
|
||||
#define XPRS_CALLBACKFROMMASTERTHREAD 8090
|
||||
#define XPRS_MAXMCOEFFBUFFERELEMS 8091
|
||||
#define XPRS_REFINEOPS 8093
|
||||
#define XPRS_LPREFINEITERLIMIT 8094
|
||||
#define XPRS_MIPREFINEITERLIMIT 8095
|
||||
#define XPRS_DUALIZEOPS 8097
|
||||
#define XPRS_CROSSOVERITERLIMIT 8104
|
||||
#define XPRS_PREBASISRED 8106
|
||||
#define XPRS_PRESORT 8107
|
||||
#define XPRS_PREPERMUTE 8108
|
||||
#define XPRS_PREPERMUTESEED 8109
|
||||
#define XPRS_MAXMEMORYSOFT 8112
|
||||
#define XPRS_CUTFREQ 8116
|
||||
#define XPRS_SYMSELECT 8117
|
||||
#define XPRS_SYMMETRY 8118
|
||||
#define XPRS_MAXMEMORYHARD 8119
|
||||
#define XPRS_MIQCPALG 8125
|
||||
#define XPRS_QCCUTS 8126
|
||||
#define XPRS_QCROOTALG 8127
|
||||
#define XPRS_PRECONVERTSEPARABLE 8128
|
||||
#define XPRS_ALGAFTERNETWORK 8129
|
||||
#define XPRS_TRACE 8130
|
||||
#define XPRS_MAXIIS 8131
|
||||
#define XPRS_CPUTIME 8133
|
||||
#define XPRS_COVERCUTS 8134
|
||||
#define XPRS_GOMCUTS 8135
|
||||
#define XPRS_LPFOLDING 8136
|
||||
#define XPRS_MPSFORMAT 8137
|
||||
#define XPRS_CUTSTRATEGY 8138
|
||||
#define XPRS_CUTDEPTH 8139
|
||||
#define XPRS_TREECOVERCUTS 8140
|
||||
#define XPRS_TREEGOMCUTS 8141
|
||||
#define XPRS_CUTSELECT 8142
|
||||
#define XPRS_TREECUTSELECT 8143
|
||||
#define XPRS_DUALIZE 8144
|
||||
#define XPRS_DUALGRADIENT 8145
|
||||
#define XPRS_SBITERLIMIT 8146
|
||||
#define XPRS_SBBEST 8147
|
||||
#define XPRS_BARINDEFLIMIT 8153
|
||||
#define XPRS_HEURFREQ 8155
|
||||
#define XPRS_HEURDEPTH 8156
|
||||
#define XPRS_HEURMAXSOL 8157
|
||||
#define XPRS_HEURNODES 8158
|
||||
#define XPRS_LNPBEST 8160
|
||||
#define XPRS_LNPITERLIMIT 8161
|
||||
#define XPRS_BRANCHCHOICE 8162
|
||||
#define XPRS_BARREGULARIZE 8163
|
||||
#define XPRS_SBSELECT 8164
|
||||
#define XPRS_LOCALCHOICE 8170
|
||||
#define XPRS_LOCALBACKTRACK 8171
|
||||
#define XPRS_DUALSTRATEGY 8174
|
||||
#define XPRS_L1CACHE 8175
|
||||
#define XPRS_HEURDIVESTRATEGY 8177
|
||||
#define XPRS_HEURSELECT 8178
|
||||
#define XPRS_BARSTART 8180
|
||||
#define XPRS_PRESOLVEPASSES 8183
|
||||
#define XPRS_BARNUMSTABILITY 8186
|
||||
#define XPRS_BARORDERTHREADS 8187
|
||||
#define XPRS_EXTRASETS 8190
|
||||
#define XPRS_FEASIBILITYPUMP 8193
|
||||
#define XPRS_PRECOEFELIM 8194
|
||||
#define XPRS_PREDOMCOL 8195
|
||||
#define XPRS_HEURSEARCHFREQ 8196
|
||||
#define XPRS_HEURDIVESPEEDUP 8197
|
||||
#define XPRS_SBESTIMATE 8198
|
||||
#define XPRS_BARCORES 8202
|
||||
#define XPRS_MAXCHECKSONMAXTIME 8203
|
||||
#define XPRS_MAXCHECKSONMAXCUTTIME 8204
|
||||
#define XPRS_HISTORYCOSTS 8206
|
||||
#define XPRS_ALGAFTERCROSSOVER 8208
|
||||
#define XPRS_MUTEXCALLBACKS 8210
|
||||
#define XPRS_BARCRASH 8211
|
||||
#define XPRS_HEURDIVESOFTROUNDING 8215
|
||||
#define XPRS_HEURSEARCHROOTSELECT 8216
|
||||
#define XPRS_HEURSEARCHTREESELECT 8217
|
||||
#define XPRS_MPS18COMPATIBLE 8223
|
||||
#define XPRS_ROOTPRESOLVE 8224
|
||||
#define XPRS_CROSSOVERDRP 8227
|
||||
#define XPRS_FORCEOUTPUT 8229
|
||||
#define XPRS_PRIMALOPS 8231
|
||||
#define XPRS_DETERMINISTIC 8232
|
||||
#define XPRS_PREPROBING 8238
|
||||
#define XPRS_TREEMEMORYLIMIT 8242
|
||||
#define XPRS_TREECOMPRESSION 8243
|
||||
#define XPRS_TREEDIAGNOSTICS 8244
|
||||
#define XPRS_MAXTREEFILESIZE 8245
|
||||
#define XPRS_PRECLIQUESTRATEGY 8247
|
||||
#define XPRS_REPAIRINFEASMAXTIME 8250
|
||||
#define XPRS_IFCHECKCONVEXITY 8251
|
||||
#define XPRS_PRIMALUNSHIFT 8252
|
||||
#define XPRS_REPAIRINDEFINITEQ 8254
|
||||
#define XPRS_MIPRAMPUP 8255
|
||||
#define XPRS_MAXLOCALBACKTRACK 8257
|
||||
#define XPRS_USERSOLHEURISTIC 8258
|
||||
#define XPRS_FORCEPARALLELDUAL 8265
|
||||
#define XPRS_BACKTRACKTIE 8266
|
||||
#define XPRS_BRANCHDISJ 8267
|
||||
#define XPRS_MIPFRACREDUCE 8270
|
||||
#define XPRS_CONCURRENTTHREADS 8274
|
||||
#define XPRS_MAXSCALEFACTOR 8275
|
||||
#define XPRS_HEURTHREADS 8276
|
||||
#define XPRS_THREADS 8278
|
||||
#define XPRS_HEURBEFORELP 8280
|
||||
#define XPRS_PREDOMROW 8281
|
||||
#define XPRS_BRANCHSTRUCTURAL 8282
|
||||
#define XPRS_QUADRATICUNSHIFT 8284
|
||||
#define XPRS_BARPRESOLVEOPS 8286
|
||||
#define XPRS_QSIMPLEXOPS 8288
|
||||
#define XPRS_MIPRESTART 8290
|
||||
#define XPRS_CONFLICTCUTS 8292
|
||||
#define XPRS_PREPROTECTDUAL 8293
|
||||
#define XPRS_CORESPERCPU 8296
|
||||
#define XPRS_RESOURCESTRATEGY 8297
|
||||
#define XPRS_CLAMPING 8301
|
||||
#define XPRS_SLEEPONTHREADWAIT 8302
|
||||
#define XPRS_PREDUPROW 8307
|
||||
#define XPRS_CPUPLATFORM 8312
|
||||
#define XPRS_BARALG 8315
|
||||
#define XPRS_SIFTING 8319
|
||||
#define XPRS_LPLOGSTYLE 8326
|
||||
#define XPRS_RANDOMSEED 8328
|
||||
#define XPRS_TREEQCCUTS 8331
|
||||
#define XPRS_PRELINDEP 8333
|
||||
#define XPRS_DUALTHREADS 8334
|
||||
#define XPRS_PREOBJCUTDETECT 8336
|
||||
#define XPRS_PREBNDREDQUAD 8337
|
||||
#define XPRS_PREBNDREDCONE 8338
|
||||
#define XPRS_PRECOMPONENTS 8339
|
||||
#define XPRS_MAXMIPTASKS 8347
|
||||
#define XPRS_MIPTERMINATIONMETHOD 8348
|
||||
#define XPRS_PRECONEDECOMP 8349
|
||||
#define XPRS_HEURFORCESPECIALOBJ 8350
|
||||
#define XPRS_HEURSEARCHROOTCUTFREQ 8351
|
||||
#define XPRS_PREELIMQUAD 8353
|
||||
#define XPRS_PREIMPLICATIONS 8356
|
||||
#define XPRS_TUNERMODE 8359
|
||||
#define XPRS_TUNERMETHOD 8360
|
||||
#define XPRS_TUNERTARGET 8362
|
||||
#define XPRS_TUNERTHREADS 8363
|
||||
#define XPRS_TUNERHISTORY 8365
|
||||
#define XPRS_TUNERPERMUTE 8366
|
||||
#define XPRS_TUNERVERBOSE 8370
|
||||
#define XPRS_TUNEROUTPUT 8372
|
||||
#define XPRS_PREANALYTICCENTER 8374
|
||||
#define XPRS_NETCUTS 8382
|
||||
#define XPRS_LPFLAGS 8385
|
||||
#define XPRS_MIPKAPPAFREQ 8386
|
||||
#define XPRS_OBJSCALEFACTOR 8387
|
||||
#define XPRS_TREEFILELOGINTERVAL 8389
|
||||
#define XPRS_IGNORECONTAINERCPULIMIT 8390
|
||||
#define XPRS_IGNORECONTAINERMEMORYLIMIT 8391
|
||||
#define XPRS_MIPDUALREDUCTIONS 8392
|
||||
#define XPRS_GENCONSDUALREDUCTIONS 8395
|
||||
#define XPRS_PWLDUALREDUCTIONS 8396
|
||||
#define XPRS_BARFAILITERLIMIT 8398
|
||||
#define XPRS_AUTOSCALING 8406
|
||||
#define XPRS_GENCONSABSTRANSFORMATION 8408
|
||||
#define XPRS_COMPUTEJOBPRIORITY 8409
|
||||
#define XPRS_PREFOLDING 8410
|
||||
#define XPRS_NETSTALLLIMIT 8412
|
||||
#define XPRS_SERIALIZEPREINTSOL 8413
|
||||
#define XPRS_NUMERICALEMPHASIS 8416
|
||||
#define XPRS_PWLNONCONVEXTRANSFORMATION 8420
|
||||
#define XPRS_MIPCOMPONENTS 8421
|
||||
#define XPRS_MIPCONCURRENTNODES 8422
|
||||
#define XPRS_MIPCONCURRENTSOLVES 8423
|
||||
#define XPRS_OUTPUTCONTROLS 8424
|
||||
#define XPRS_SIFTSWITCH 8425
|
||||
#define XPRS_HEUREMPHASIS 8427
|
||||
#define XPRS_COMPUTEMATX 8428
|
||||
#define XPRS_COMPUTEMATX_IIS 8429
|
||||
#define XPRS_COMPUTEMATX_IISMAXTIME 8430
|
||||
#define XPRS_BARREFITER 8431
|
||||
#define XPRS_COMPUTELOG 8434
|
||||
#define XPRS_SIFTPRESOLVEOPS 8435
|
||||
#define XPRS_CHECKINPUTDATA 8436
|
||||
#define XPRS_ESCAPENAMES 8440
|
||||
#define XPRS_IOTIMEOUT 8442
|
||||
#define XPRS_AUTOCUTTING 8446
|
||||
#define XPRS_CALLBACKCHECKTIMEDELAY 8451
|
||||
#define XPRS_MULTIOBJOPS 8457
|
||||
#define XPRS_MULTIOBJLOG 8458
|
||||
#define XPRS_GLOBALSPATIALBRANCHIFPREFERORIG 8465
|
||||
#define XPRS_PRECONFIGURATION 8470
|
||||
#define XPRS_FEASIBILITYJUMP 8471
|
||||
#define XPRS_EXTRAELEMS 8006
|
||||
#define XPRS_EXTRASETELEMS 8191
|
||||
#define XPRS_LPOBJVAL 2001
|
||||
#define XPRS_MIPOBJVAL 2003
|
||||
#define XPRS_BESTBOUND 2004
|
||||
#define XPRS_OBJRHS 2005
|
||||
#define XPRS_OBJSENSE 2008
|
||||
#define XPRS_ROWS 1001
|
||||
#define XPRS_SIMPLEXITER 1009
|
||||
#define XPRS_LPSTATUS 1010
|
||||
#define XPRS_MIPSTATUS 1011
|
||||
#define XPRS_NODES 1013
|
||||
#define XPRS_COLS 1018
|
||||
#define XPRS_LP_OPTIMAL 1
|
||||
#define XPRS_LP_INFEAS 2
|
||||
#define XPRS_LP_UNBOUNDED 5
|
||||
#define XPRS_MIP_SOLUTION 4
|
||||
#define XPRS_MIP_INFEAS 5
|
||||
#define XPRS_MIP_OPTIMAL 6
|
||||
#define XPRS_MIP_UNBOUNDED 7
|
||||
#define XPRS_OBJ_MINIMIZE 1
|
||||
#define XPRS_OBJ_MAXIMIZE -1
|
||||
extern std::function<int(XPRSprob* p_prob)> XPRScreateprob;
|
||||
extern std::function<int(XPRSprob prob)> XPRSdestroyprob;
|
||||
extern std::function<int(const char* path)> XPRSinit;
|
||||
extern std::function<int(void)> XPRSfree;
|
||||
extern std::function<int(char* buffer, int maxbytes)> XPRSgetlicerrmsg;
|
||||
extern std::function<int(int* p_i, char* p_c)> XPRSlicense;
|
||||
extern std::function<int(char* banner)> XPRSgetbanner;
|
||||
extern std::function<int(char* version)> XPRSgetversion;
|
||||
extern std::function<int(XPRSprob prob, int control)> XPRSsetdefaultcontrol;
|
||||
extern std::function<int(XPRSprob prob, int reason)> XPRSinterrupt;
|
||||
extern std::function<int(XPRSprob prob, int control, int value)> XPRSsetintcontrol;
|
||||
extern std::function<int(XPRSprob prob, int control, XPRSint64 value)> XPRSsetintcontrol64;
|
||||
extern std::function<int(XPRSprob prob, int control, double value)> XPRSsetdblcontrol;
|
||||
extern std::function<int(XPRSprob prob, int control, const char* value)> XPRSsetstrcontrol;
|
||||
extern std::function<int(XPRSprob prob, int control, int* p_value)> XPRSgetintcontrol;
|
||||
extern std::function<int(XPRSprob prob, int control, XPRSint64* p_value)> XPRSgetintcontrol64;
|
||||
extern std::function<int(XPRSprob prob, int control, double* p_value)> XPRSgetdblcontrol;
|
||||
extern std::function<int(XPRSprob prob, int control, char* value, int maxbytes, int* p_nbytes)> XPRSgetstringcontrol;
|
||||
extern std::function<int(XPRSprob prob, int attrib, int* p_value)> XPRSgetintattrib;
|
||||
extern std::function<int(XPRSprob prob, int attrib, double* p_value)> XPRSgetdblattrib;
|
||||
extern std::function<int(XPRSprob prob, const char* name, int* p_id, int* p_type)> XPRSgetcontrolinfo;
|
||||
extern std::function<int(XPRSprob prob, const char* probname, int ncols, int nrows, const char rowtype[], const double rhs[], const double rng[], const double objcoef[], const int start[], const int collen[], const int rowind[], const double rowcoef[], const double lb[], const double ub[])> XPRSloadlp;
|
||||
extern std::function<int(XPRSprob prob, const char* probname, int ncols, int nrows, const char rowtype[], const double rhs[], const double rng[], const double objcoef[], const XPRSint64 start[], const int collen[], const int rowind[], const double rowcoef[], const double lb[], const double ub[])> XPRSloadlp64;
|
||||
extern std::function<int(XPRSprob prob, double objcoef[], int first, int last)> XPRSgetobj;
|
||||
extern std::function<int(XPRSprob prob, double rhs[], int first, int last)> XPRSgetrhs;
|
||||
extern std::function<int(XPRSprob prob, double rng[], int first, int last)> XPRSgetrhsrange;
|
||||
extern std::function<int(XPRSprob prob, double lb[], int first, int last)> XPRSgetlb;
|
||||
extern std::function<int(XPRSprob prob, double ub[], int first, int last)> XPRSgetub;
|
||||
extern std::function<int(XPRSprob prob, int row, int col, double* p_coef)> XPRSgetcoef;
|
||||
extern std::function<int(XPRSprob prob, int nrows, int ncoefs, const char rowtype[], const double rhs[], const double rng[], const int start[], const int colind[], const double rowcoef[])> XPRSaddrows;
|
||||
extern std::function<int(XPRSprob prob, int nrows, const int rowind[])> XPRSdelrows;
|
||||
extern std::function<int(XPRSprob prob, int ncols, int ncoefs, const double objcoef[], const int start[], const int rowind[], const double rowcoef[], const double lb[], const double ub[])> XPRSaddcols;
|
||||
extern std::function<int(XPRSprob prob, int type, const char names[], int first, int last)> XPRSaddnames;
|
||||
extern std::function<int(XPRSprob prob, int type, char names[], int first, int last)> XPRSgetnames;
|
||||
extern std::function<int(XPRSprob prob, int ncols, const int colind[])> XPRSdelcols;
|
||||
extern std::function<int(XPRSprob prob, int ncols, const int colind[], const char coltype[])> XPRSchgcoltype;
|
||||
extern std::function<int(XPRSprob prob, const int rowstat[], const int colstat[])> XPRSloadbasis;
|
||||
extern std::function<int(XPRSprob prob)> XPRSpostsolve;
|
||||
extern std::function<int(XPRSprob prob, int objsense)> XPRSchgobjsense;
|
||||
extern std::function<int(XPRSprob prob, char* errmsg)> XPRSgetlasterror;
|
||||
extern std::function<int(XPRSprob prob, int rowstat[], int colstat[])> XPRSgetbasis;
|
||||
extern std::function<int(XPRSprob prob, const char* filename, const char* flags)> XPRSwriteprob;
|
||||
extern std::function<int(XPRSprob prob, char rowtype[], int first, int last)> XPRSgetrowtype;
|
||||
extern std::function<int(XPRSprob prob, char coltype[], int first, int last)> XPRSgetcoltype;
|
||||
extern std::function<int(XPRSprob prob, int nbounds, const int colind[], const char bndtype[], const double bndval[])> XPRSchgbounds;
|
||||
extern std::function<int(XPRSprob prob, int length, const double solval[], const int colind[], const char* name)> XPRSaddmipsol;
|
||||
extern std::function<int(XPRSprob prob, double x[], double slack[], double duals[], double djs[])> XPRSgetlpsol;
|
||||
extern std::function<int(XPRSprob prob, double x[], double slack[])> XPRSgetmipsol;
|
||||
extern std::function<int(XPRSprob prob, int ncols, const int colind[], const double objcoef[])> XPRSchgobj;
|
||||
extern std::function<int(XPRSprob prob, int row, int col, double coef)> XPRSchgcoef;
|
||||
extern std::function<int(XPRSprob prob, int ncoefs, const int rowind[], const int colind[], const double rowcoef[])> XPRSchgmcoef;
|
||||
extern std::function<int(XPRSprob prob, int nrows, const int rowind[], const double rhs[])> XPRSchgrhs;
|
||||
extern std::function<int(XPRSprob prob, int nrows, const int rowind[], const double rng[])> XPRSchgrhsrange;
|
||||
extern std::function<int(XPRSprob prob, int nrows, const int rowind[], const char rowtype[])> XPRSchgrowtype;
|
||||
extern std::function<int(XPRSprob prob, void (XPRS_CC *f_intsol)(XPRSprob cbprob, void* cbdata), void* p, int priority)> XPRSaddcbintsol;
|
||||
extern std::function<int(XPRSprob prob, void (XPRS_CC *f_intsol)(XPRSprob cbprob, void* cbdata), void* p)> XPRSremovecbintsol;
|
||||
extern std::function<int(XPRSprob prob, void (XPRS_CC *f_message)(XPRSprob cbprob, void* cbdata, const char* msg, int msglen, int msgtype), void* p, int priority)> XPRSaddcbmessage;
|
||||
extern std::function<int(XPRSprob prob, const char* flags)> XPRSlpoptimize;
|
||||
extern std::function<int(XPRSprob prob, const char* flags)> XPRSmipoptimize;
|
||||
|
||||
} // namespace operations_research
|
||||
|
||||
#endif // OR_TOOLS_XPRESS_ENVIRONMENT_H
|
||||
Reference in New Issue
Block a user