Introduction
fifr::lpmod is a simple generic C++ interface for creating and solving linear programs. The library provides a simple abstraction to create models with variables and constraints in a solver independent way. The models can than be passed to various solvers like Cplex or Gurobi.
Documentation
The (very sparse) API documentation can found here.
Download
Latest development version: lpmod-trunk.tar.gz
The project lives in a fossil repository. In order to clone the repository, execute the following commands:
fossil clone http://fifr.spdns.de/cpp-lpmod path/to/cpp-lpmod.fossil
mkdir path/to/lpmod-sources
cd path/to/lpmod-sources
fossil open path/to/cpp-lpmod.fossil
Installation
fifr::lpmod comes with a cmake build script. The library can be compiled into a static library using
mkdir path/to/build-directory
cd path/to/build-directory
cmake path/to/lpmod-sources
make
This creates a (static) callable library in path/to/build-directory
,
usually called libfifrlpmod.a
on Linux systems. Note that this library
contains only solver independent parts.
The library can be installed on your system using
sudo make install
afterwards (usually you have to run this command as root because it installs the
library to a system directory). This command copies the header files and the
necessary cmake configuration files to /usr/local
(by default). The path can
be changed by setting the CMAKE_INSTALL_PREFIX
variable when running cmake
cmake -DCMAKE_INSTALL_PREFIX=/installation/path
Note that fifr::lpmod requires C++17.
Cplex
Cplex is looked for in the path set by the environment variable CPLEX_HOME
.
The variable can also be specified when calling cmake
:
env CPLEX_HOME=/path/to/cplex cmake
If Cplex has been found then the CplexSolver
class is compiled to its own
library libfifrlpmod-cpx.a
.
Gurobi
Gurobi is looked for in the path set by the environment variable GUROBI_HOME
.
(This variable should be set in a proper Gurobi installation). The variable can
also be specified when calling cmake
:
env GUROBI_HOME=/path/to/gurobi cmake
If Gurobi has been found then the GurobiSolver
class is compiled to its own
library libfifrlpmod-grb.a
.
Using fifr::lpmod in your own project
There are several ways to use fifr::lpmod in your own project depending on
whether you use cmake
or not. If you are unsure but you use cmake
we suggest
the cmake subdirectory
approach below.
As a cmake package
If you installed fifr::lpmod to a system directory (using the approach
described above), you can instruct cmake
to look for the library. The
following example can be used in your CMakeLists.txt to find fifr::lpmod and
link against Cplex or Gurobi if they could be found. If Cplex or Gurobi are
mandatory for your project, remove OPTIONAL_COMPONENTS
.
find_package(FifrLPmod REQUIRED OPTIONAL_COMPONENTS Cplex Gurobi)
target_link_libraries(${TARGET} Fifr::LPmod)
if (FifrLPmod_Cplex_FOUND)
target_compile_definitions(${TARGET} PRIVATE -DHAVE_CPLEX=1)
target_link_libraries(${TARGET} Fifr::LPmod::Cplex)
endif ()
if (FifrLPmod_Gurobi_FOUND)
target_compile_definitions(${TARGET} PRIVATE -DHAVE_GUROBI=1)
target_link_libraries(${TARGET} Fifr::LPmod::Gurobi)
endif ()
Note that these script will automatically add the necessary linking parameters for Cplex and Gurobi as well.
As a cmake package installed to a non-standard location
Do the same as above but ensure that the path to your non-standard location is
contained in the environment variable CMAKE_PREFIX_PATH
before you run
cmake
on your project:
export CMAKE_PREFIX_PATH=/non-standard/installation/path
cmake
...
Alternatively you can specify the path as cmake
define
cmake -DCMAKE_PREFIX_PATH=/non-standard/installation/path
...
As a cmake package without installation
This is similar to the previous approach but instead of installing
fifr::lpmod to some non-standard location you can use the build directory
directly. So do not execute make install
but add the build directory to
CMAKE_PREFIX_PATH
:
export CMAKE_PREFIX_PATH=path/to/fifrlpmod/build-directory
cmake
...
or
cmake -DCMAKE_PREFIX_PATH=path/to/fifrlpmod/build-directory
...
As a cmake subdirectory
This is probably the easiest way to create a cmake
buildable project that can
easily be deployed to other systems, because it does not need any fumbling with
the installation of fifr::lpmod itself. Simply copy the whole fifr::lpmod
source tree to a subdirectory of your project or checkout its fossil repository
to a subdirectory:
mkdir -p 3rdparty/lpmod
cd 3rdparty/lpmod
fossil open --nested path/to/lpmod/fossil/repo
Then add the same lines as above to your CMakeLists.txt
but replace the
find_package
command with an add_subdirectory
command:
add_subdirectory(3rdparty/lpmod)
target_link_libraries(${TARGET} Fifr::LPmod)
if (FifrLPmod_Cplex_FOUND)
target_compile_definitions(${TARGET} PRIVATE -DHAVE_CPLEX=1)
target_link_libraries(${TARGET} Fifr::LPmod::Cplex)
endif ()
if (FifrLPmod_Gurobi_FOUND)
target_compile_definitions(${TARGET} PRIVATE -DHAVE_GUROBI=1)
target_link_libraries(${TARGET} Fifr::LPmod::Gurobi)
endif ()
If you configure your project then fifr::lpmod is configured as well.
As part of your own source tree
You can copy the src/fifr/
subdirectory to your own source tree
cp -r /path/to/fifr/lpmod/src/fifr src/
and add that source tree as subdirectory
add_subdirectory(src/fifr/lpmod)
target_link_libraries(${TARGET} Fifr::LPmod)
if (FifrLPmod_Cplex_FOUND)
target_compile_definitions(${TARGET} PRIVATE -DHAVE_CPLEX=1)
target_link_libraries(${TARGET} Fifr::LPmod::Cplex)
endif ()
if (FifrLPmod_Gurobi_FOUND)
target_compile_definitions(${TARGET} PRIVATE -DHAVE_GUROBI=1)
target_link_libraries(${TARGET} Fifr::LPmod::Gurobi)
endif ()
The difference to the previous approach is that fifr::lpmod's source files are now part of your application's source tree and not contained in its own fossil source directory. So following updates of fifr::lpmod requires manually copying changes source files again.
Link manually
Of course, you can manually link against fifr::lpmod. Simply add the corresponding linker flags to your compiler, but do not forget that you need to links against the solvers, too:
g++ -o myapp myapp.cpp -L/path/to/fifr/lpmod \
-lfifrlpmod -lfifrlpmod-cpx -lfifrlpmod-grb \
-Lpath/to/gurobi -lgurobi100 \
-Lpath/to/cplex -lcplex \
-ldl -lpthread -lm