lpsolve
is a library for solving Mixed Integer Linear Programming (MILP) implemented in C.
It does have a Python extension but haven't been updated for a long time and only support
Python 2. As the Python C API changed a lot from 2 to 3, support for Python 3 is not as simple as
just recompile it for Python 3. This guide will walk through the process for compiling and
installing lpsolve
module for Python 3.
-
Download and extract the latest version of
lpsolve
and Python module source code. The current version is 5.5.2.5 and these two directories can be merged intolp_solve_5.5
(extra
directory insidelp_solve_5.5
). -
Compile the library following the readme. The script for building libraries are in
lp_solve_5.5/lpsolve55
. You should follow thereadme.txt
in this directory. This should produceliblpsolve55.a
andliblpsolve55.so
(liblpsolve55.dll
on Windows) inlp_solve_5.5/lpsolve55/bin/<your os>
. -
Copy (do not delete) these files to where installed libraries should go. On Linux/MacOS (it should be
/usr/local/lib
) -
In
lp_solve_5.5/extra/Python
, you will need to modify thesetup.py
to build it for Python3. The script is a bit messy and you need to perform the following changes:
- Change
print ...
toprint(...)
- Delete all the
if ... else
, everything after allimport ...
and abovesetup(...)
. Don't delete print(...)
you just changed.- Add the followings between
import ...
andprint(...)
- Add
LPSOLVE55 = '../../lpsolve55/bin/<your os>'
- Add
WIN32 = 'NOWIN32'
unless you are compiling forwin32
(not tested) - If you want to build with Numpy, add
NUMPY = 'NUMPY'
otherwiseNUMPY = 'NONUMPY'
- If you want to build with Numpy, you also need to find your Numpy include directory.
It should be located in
site-packages
directory of you Python installation directory, and the overall path looks something like this'<??>/Python/<3.x>/lib/python/site-packages/numpy/core/include'
. If you go to this directory, insidenumpy
directory, there should be a lot of.h
files. AddNUMPYPATH='<??>/Python/<3.x>/lib/python/site-packages/numpy/core/include'
- Add
- In
setup(...)
setinclude_dirs=['../..', NUMPYPATH]
-
If you are on MacOS, change
#include <malloc.h>
inhash.c
to#include <stdlib.h>
. -
Follow the changed to
pythonmod.c
mentioned here except for the followings: You should change allPyString_<...>
toPyBytes_<...>
. It is advised to use search and replace functionality of the text editor. DO NOT change it toPyUnicode_<...>
The code will compile, but you will run into issues when you use it in Python 3. This is because of the change of Python C API, if you want to learn more about the change, see this. The short answer is that String in C (lpsolve source code) is equivalent tobytes
type but notstr
type in Python3. -
Now you should be able to compile the library. Use
python3 setup.py install
to compile and install the package. (Note: if your system defaultpython
is Python 3, you can just runpython3 setup.py install
, it is important not to runsetup.py
from Python 2). -
If you see no errors, the package should be installed. To test whether it works, opens a Python 3 shell in your terminal, type
from lpsolve55 import *
. It should not print anything. If it prints errors, you probably need to change some code again :(. -
Follow the documentation to try a few examples. You need to change all string literals
'...'
to bytes literals b'...'
(just add ab
in the front of the literal) in order to make it work. All other things should be the same as the module in Python 2.
-
If your module could not found library
liblpsolve55.so
, it means your library is not in the path. Try to set the environmental variableLD_LIBRARY_PATH
to the location of your library. -
If your module could not initalize because of
unknown symbols xxx
. Double check the changes inpythonmod.c
, especially for the replacements. -
On Linux, if
gcc
throws error, try to compile withclang
(cc=clang
inccc
)
If you have other questions, please open issue.