# --------------------------------------------------------------------------
# File: _procedural.py
# ---------------------------------------------------------------------------
# Licensed Materials - Property of IBM
# 5725-A06 5725-A29 5724-Y48 5724-Y49 5724-Y54 5724-Y55 5655-Y21
# Copyright IBM Corporation 2008, 2024. All Rights Reserved.
#
# US Government Users Restricted Rights - Use, duplication or
# disclosure restricted by GSA ADP Schedule Contract with
# IBM Corp.
# ------------------------------------------------------------------------
"""Wrapper functions for the CPLEX C Callable Library"""
from collections import namedtuple
from contextlib import contextmanager
import os
from . import _constants as _const
from . import _list_array_utils as LAU
from . import _pycplex as CR
from ..exceptions import CplexSolverError, CplexError, ErrorChannelMessage
CPLEX_PY_DISABLE_SIGHANDLER = os.getenv("CPLEX_PY_DISABLE_SIGHANDLER")
# pylint: disable=missing-docstring
def _safeDoubleArray(arraylen):
# Make sure that we never request a zero-length array. This results in
# a malloc(0) call in the SWIG layer. On AIX this returns NULL which
# causes problems. By ensuring that the array is at least size 1, we
# avoid these problems and the overhead should be negligable.
if arraylen <= 0:
arraylen = 1
return CR.doubleArray(arraylen)
def _safeIntArray(arraylen):
# See comment for _safeDoubleArray above.
if arraylen <= 0:
arraylen = 1
return CR.intArray(arraylen)
def _safeLongArray(arraylen):
# See comment for _safeDoubleArray above.
if arraylen <= 0:
arraylen = 1
return CR.longArray(arraylen)
def _arraylen(seq):
"""If seq is None, return 0, else len(seq).
CPLEX often requires a count argument to specify the length of
subsequent array arguments. This function allows us to return a
length of 0 for None (i.e., NULL) arrays.
"""
if seq is None:
return 0
return len(seq)
def _rangelen(begin, end):
"""Returns length of the range specified by begin and end.
As this is typically used to calculate the length of a buffer, it
always returns a result >= 0.
See functions like `_safeDoubleArray` and `safeLongArray`.
"""
# We allow arguments like begin=0, end=-1 on purpose. This represents
# an empty range; the callable library should do nothing in this case
# (see RTC-31484).
result = end - begin + 1
if result < 0:
return 0
return result
[docs]
def getstatstring(env, statind):
output = []
CR.CPXXgetstatstring(env, statind, output)
return output[0]
[docs]
def geterrorstring(env, errcode):
output = []
CR.CPXXgeterrorstring(env, errcode, output)
return output[0]
[docs]
def cb_geterrorstring(env, status):
return CR.cb_geterrorstring(env, status)
[docs]
def new_native_int():
return CR.new_native_int()
[docs]
def delete_native_int(p):
CR.delete_native_int(p)
[docs]
def set_native_int(p, v):
CR.set_native_int(p, v)
[docs]
def get_native_int(p):
return CR.get_native_int(p)
[docs]
def setterminate(env, env_lp_ptr, p):
status = CR.setterminate(env_lp_ptr, p)
check_status(env, status)
# If the CPLEX_PY_DISABLE_SIGHANDLER environment variable is defined,
# we will not install our SIGINT handler (i.e., for Ctrl+C handling).
# This may be useful if the user wants to install their own handler.
if CPLEX_PY_DISABLE_SIGHANDLER:
class SigIntHandler():
"""A no-op signal handler (no handler installed).
:undocumented
"""
def __init__(self):
pass
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
pass
else:
# By default (i.e., if the CPLEX_PY_DISABLE_SIGHANDLER environment
# variable is not defined), then we install a custom SIGINT handler
# around long running CPLEX operations. This allows the user to abort
# the current optimization with a Ctrl+C.
[docs]
class SigIntHandler():
"""Handle Ctrl-C events during long running processes.
:undocumented
"""
[docs]
def __init__(self):
CR.sigint_register()
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
CR.sigint_unregister()
[docs]
def pack_env_lp_ptr(env, lp):
return CR.pack_env_lp_ptr(env, lp)
[docs]
@contextmanager
def chbmatrix(lolmat, env_lp_ptr, r_c):
"""See matrix_conversion.c:Pylolmat_to_CHBmat()."""
mat = Pylolmat_to_CHBmat(lolmat, env_lp_ptr, r_c)
try:
# yields ([matbeg, matind, matval], nnz)
yield mat[:-1], mat[-1]
finally:
free_CHBmat(mat)
[docs]
def Pylolmat_to_CHBmat(lolmat, env_lp_ptr, r_c):
return CR.Pylolmat_to_CHBmat(lolmat, env_lp_ptr, r_c)
[docs]
def free_CHBmat(lolmat):
CR.free_CHBmat(lolmat)
def _handle_cb_error(env, cberror):
"""Handle the callback exception.
These can be triggered either in the SWIG Python C API layer
(e.g., SWIG_callback.c) or in _ostream.py.
"""
if isinstance(cberror, Exception):
# If cberror is already an exception, then just throw it as is.
# We can only get here from: _ostream.py:_write_wrap.
raise cberror
if isinstance(cberror[1], Exception):
# In this case the first item is the type of exception and
# the second item is the exception. This is raised from the
# SWIG C layer (e.g., SWIG_callback.c:).
cberror = cberror[1]
elif isinstance(cberror[1], tuple):
# The second item is a tuple containing the error string and
# the error number. We can get this from, for example:
# SWIG_callback.c:fast_getcallbackinfo.
assert len(cberror[1]) == 2
cberror = cberror[0](cberror[1][0], env, cberror[1][1])
else:
# The second item is the error string or perhaps None.
# See code in SWIG_callback.c where the _callback_exception
# attribute is set.
cberror = cberror[0](cberror[1])
raise cberror
[docs]
class StatusChecker():
"""A callable object used for checking status codes.
:undocumented
"""
[docs]
def __init__(self):
class NoOp():
pass
self._pyenv = NoOp()
self._pyenv._callback_exception = None
def __call__(self, env, status, from_cb=False):
error_string = None
try:
if self._pyenv._callback_exception is not None:
callback_exception = self._pyenv._callback_exception
self._pyenv._callback_exception = None
if isinstance(callback_exception, ErrorChannelMessage):
# We can only get here from _ostream.py:_write_wrap.
# If we encounter an error, we use the last message
# from the error channel for the message (i.e., rather
# than calling CPXXgeterrorstring).
error_string = callback_exception.args[0]
else:
_handle_cb_error(env, callback_exception)
except ReferenceError:
pass
if status == CR.CPXERR_NO_ENVIRONMENT:
raise ValueError('illegal method invocation after Cplex.end()')
elif status != 0:
if error_string is None:
if from_cb:
error_string = cb_geterrorstring(env, status)
else:
error_string = geterrorstring(env, status)
raise CplexSolverError(error_string, env, status)
check_status = StatusChecker()
[docs]
def set_status_checker():
CR.set_status_checker(check_status)
# Environment
[docs]
def version(env):
return CR.CPXXversion(env)
[docs]
def versionnumber(env):
ver = CR.intPtr()
status = CR.CPXXversionnumber(env, ver)
check_status(env, status)
return ver.value()
[docs]
def openCPLEX():
status = CR.intPtr()
env = CR.CPXXopenCPLEX(status)
check_status(env, status.value())
# Always set the pyterminate flag immediately when initializing
# a CPLEX environment.
CR.setpyterminate(env)
return env
[docs]
def closeCPLEX(env):
envp = CR.CPXENVptrPtr()
envp.assign(env)
status = CR.CPXXcloseCPLEX(envp)
check_status(env, status)
[docs]
def getchannels(env):
results = CR.CPXCHANNELptrPtr()
warning = CR.CPXCHANNELptrPtr()
error = CR.CPXCHANNELptrPtr()
log = CR.CPXCHANNELptrPtr()
status = CR.CPXXgetchannels(env, results, warning, error, log)
check_status(env, status)
return (results.value(), warning.value(), error.value(), log.value())
[docs]
def addfuncdest(env, channel, fileobj):
status = CR.CPXXaddfuncdest(env, channel, fileobj)
check_status(env, status)
[docs]
def delfuncdest(env, channel, fileobj):
status = CR.CPXXdelfuncdest(env, channel, fileobj)
check_status(env, status)
[docs]
def setlpcallbackfunc(env, cbhandle):
status = CR.CPXXsetlpcallbackfunc(env, cbhandle)
check_status(env, status)
[docs]
def setnetcallbackfunc(env, cbhandle):
status = CR.CPXXsetnetcallbackfunc(env, cbhandle)
check_status(env, status)
[docs]
def settuningcallbackfunc(env, cbhandle):
status = CR.CPXXsettuningcallbackfunc(env, cbhandle)
check_status(env, status)
[docs]
def setheuristiccallbackfunc(env, cbhandle):
status = CR.CPXXsetheuristiccallbackfunc(env, cbhandle)
check_status(env, status)
[docs]
def setlazyconstraintcallbackfunc(env, cbhandle):
status = CR.CPXXsetlazyconstraintcallbackfunc(env, cbhandle)
check_status(env, status)
[docs]
def setusercutcallbackfunc(env, cbhandle):
status = CR.CPXXsetusercutcallbackfunc(env, cbhandle)
check_status(env, status)
[docs]
def setincumbentcallbackfunc(env, cbhandle):
status = CR.CPXXsetincumbentcallbackfunc(env, cbhandle)
check_status(env, status)
[docs]
def setnodecallbackfunc(env, cbhandle):
status = CR.CPXXsetnodecallbackfunc(env, cbhandle)
check_status(env, status)
[docs]
def setbranchcallbackfunc(env, cbhandle):
status = CR.CPXXsetbranchcallbackfunc(env, cbhandle)
check_status(env, status)
[docs]
def setbranchnosolncallbackfunc(env, cbhandle):
status = CR.CPXXsetbranchnosolncallbackfunc(env, cbhandle)
check_status(env, status)
[docs]
def setsolvecallbackfunc(env, cbhandle):
status = CR.CPXXsetsolvecallbackfunc(env, cbhandle)
check_status(env, status)
[docs]
def setinfocallbackfunc(env, cbhandle):
status = CR.CPXXsetinfocallbackfunc(env, cbhandle)
check_status(env, status)
[docs]
def setmipcallbackfunc(env, cbhandle):
status = CR.CPXXsetmipcallbackfunc(env, cbhandle)
check_status(env, status)
# Parameters
[docs]
def setdefaults(env):
status = CR.CPXXsetdefaults(env)
check_status(env, status)
[docs]
def setintparam(env, whichparam, newvalue):
status = CR.CPXXsetintparam(env, whichparam, newvalue)
check_status(env, status)
[docs]
def setlongparam(env, whichparam, newvalue):
status = CR.CPXXsetlongparam(env, whichparam, newvalue)
check_status(env, status)
[docs]
def setdblparam(env, whichparam, newvalue):
status = CR.CPXXsetdblparam(env, whichparam, newvalue)
check_status(env, status)
[docs]
def setstrparam(env, whichparam, newvalue):
status = CR.CPXXsetstrparam(env, whichparam, newvalue)
check_status(env, status)
[docs]
def getintparam(env, whichparam):
curval = CR.intPtr()
status = CR.CPXXgetintparam(env, whichparam, curval)
check_status(env, status)
return curval.value()
[docs]
def getlongparam(env, whichparam):
curval = CR.cpxlongPtr()
status = CR.CPXXgetlongparam(env, whichparam, curval)
check_status(env, status)
return curval.value()
[docs]
def getdblparam(env, whichparam):
curval = CR.doublePtr()
status = CR.CPXXgetdblparam(env, whichparam, curval)
check_status(env, status)
return curval.value()
[docs]
def getstrparam(env, whichparam):
output = []
status = CR.CPXXgetstrparam(env, whichparam, output)
check_status(env, status)
return output[0]
[docs]
def infointparam(env, whichparam):
default = CR.intPtr()
minimum = CR.intPtr()
maximum = CR.intPtr()
status = CR.CPXXinfointparam(env, whichparam, default, minimum, maximum)
check_status(env, status)
return (default.value(), minimum.value(), maximum.value())
[docs]
def infolongparam(env, whichparam):
default = CR.cpxlongPtr()
minimum = CR.cpxlongPtr()
maximum = CR.cpxlongPtr()
status = CR.CPXXinfolongparam(env, whichparam, default, minimum, maximum)
check_status(env, status)
return (default.value(), minimum.value(), maximum.value())
[docs]
def infodblparam(env, whichparam):
default = CR.doublePtr()
minimum = CR.doublePtr()
maximum = CR.doublePtr()
status = CR.CPXXinfodblparam(env, whichparam, default, minimum, maximum)
check_status(env, status)
return (default.value(), minimum.value(), maximum.value())
[docs]
def infostrparam(env, whichparam):
output = []
status = CR.CPXXinfostrparam(env, whichparam, output)
check_status(env, status)
return output[0]
[docs]
def getparamtype(env, param_name):
output = CR.intPtr()
status = CR.CPXXgetparamtype(env, param_name, output)
check_status(env, status)
return output.value()
[docs]
def readcopyparam(env, filename):
status = CR.CPXXreadcopyparam(env, filename)
check_status(env, status)
[docs]
def writeparam(env, filename):
status = CR.CPXXwriteparam(env, filename)
check_status(env, status)
[docs]
def tuneparam(env, lp, int_param_values, dbl_param_values, str_param_values):
tuning_status = CR.intPtr()
intcnt = len(int_param_values)
dblcnt = len(dbl_param_values)
strcnt = len(str_param_values)
intnum = [int_param_values[i][0] for i in range(intcnt)]
intval = [int_param_values[i][1] for i in range(intcnt)]
dblnum = [dbl_param_values[i][0] for i in range(dblcnt)]
dblval = [dbl_param_values[i][1] for i in range(dblcnt)]
strnum = [str_param_values[i][0] for i in range(strcnt)]
strval = [str_param_values[i][1] for i in range(strcnt)]
with SigIntHandler():
status = CR.CPXXtuneparam(
env, lp, intcnt,
LAU.int_list_to_array(intnum),
LAU.int_list_to_array_trunc_int32(intval),
dblcnt,
LAU.int_list_to_array(dblnum),
LAU.double_list_to_array(dblval),
strcnt,
LAU.int_list_to_array(strnum),
strval,
tuning_status)
check_status(env, status)
return tuning_status.value()
[docs]
def tuneparamprobset(env, filenames, filetypes, int_param_values,
dbl_param_values, str_param_values):
tuning_status = CR.intPtr()
intcnt = len(int_param_values)
dblcnt = len(dbl_param_values)
strcnt = len(str_param_values)
intnum = [int_param_values[i][0] for i in range(intcnt)]
intval = [int_param_values[i][1] for i in range(intcnt)]
dblnum = [dbl_param_values[i][0] for i in range(dblcnt)]
dblval = [dbl_param_values[i][1] for i in range(dblcnt)]
strnum = [str_param_values[i][0] for i in range(strcnt)]
strval = [str_param_values[i][1] for i in range(strcnt)]
with SigIntHandler():
status = CR.CPXXtuneparamprobset(
env, len(filenames),
filenames,
filetypes,
intcnt, LAU.int_list_to_array(intnum),
LAU.int_list_to_array_trunc_int32(intval),
dblcnt, LAU.int_list_to_array(dblnum),
LAU.double_list_to_array(dblval),
strcnt, LAU.int_list_to_array(strnum),
strval,
tuning_status)
check_status(env, status)
return tuning_status.value()
[docs]
def fixparam(env, paramnum):
status = CR.CPXXEfixparam(env, paramnum)
check_status(env, status)
########################################################################
# Parameter Set API
########################################################################
[docs]
def paramsetadd(env, ps, whichparam, newvalue, paramtype=None):
if paramtype is None:
paramtype = getparamtype(env, whichparam)
if paramtype == _const.CPX_PARAMTYPE_INT:
if isinstance(newvalue, float):
newvalue = int(newvalue) # will upconvert to long, if necc.
paramsetaddint(env, ps, whichparam, newvalue)
elif paramtype == _const.CPX_PARAMTYPE_DOUBLE:
if isinstance(newvalue, int):
newvalue = float(newvalue)
paramsetadddbl(env, ps, whichparam, newvalue)
elif paramtype == _const.CPX_PARAMTYPE_STRING:
paramsetaddstr(env, ps, whichparam, newvalue)
else:
assert paramtype == _const.CPX_PARAMTYPE_LONG
if isinstance(newvalue, float):
newvalue = int(newvalue) # will upconvert to long, if necc.
paramsetaddlong(env, ps, whichparam, newvalue)
[docs]
def paramsetadddbl(env, ps, whichparam, newvalue):
status = CR.CPXXparamsetadddbl(env, ps, whichparam, newvalue)
check_status(env, status)
[docs]
def paramsetaddint(env, ps, whichparam, newvalue):
status = CR.CPXXparamsetaddint(env, ps, whichparam, newvalue)
check_status(env, status)
[docs]
def paramsetaddlong(env, ps, whichparam, newvalue):
status = CR.CPXXparamsetaddlong(env, ps, whichparam, newvalue)
check_status(env, status)
[docs]
def paramsetaddstr(env, ps, whichparam, newvalue):
status = CR.CPXXparamsetaddstr(env, ps, whichparam, newvalue)
check_status(env, status)
[docs]
def paramsetapply(env, ps):
status = CR.CPXXparamsetapply(env, ps)
check_status(env, status)
[docs]
def paramsetcopy(env, targetps, sourceps):
status = CR.CPXXparamsetcopy(env, targetps, sourceps)
check_status(env, status)
[docs]
def paramsetcreate(env):
status = CR.intPtr()
ps = CR.CPXXparamsetcreate(env, status)
check_status(env, status.value())
return ps
[docs]
def paramsetdel(env, ps, whichparam):
status = CR.CPXXparamsetdel(env, ps, whichparam)
check_status(env, status)
[docs]
def paramsetfree(env, ps):
ps_p = CR.CPXPARAMSETptrPtr()
ps_p.assign(ps)
status = CR.CPXXparamsetfree(env, ps_p)
check_status(env, status)
[docs]
def paramsetget(env, ps, whichparam, paramtype=None):
if paramtype is None:
paramtype = getparamtype(env, whichparam)
switcher = {
_const.CPX_PARAMTYPE_INT: paramsetgetint,
_const.CPX_PARAMTYPE_DOUBLE: paramsetgetdbl,
_const.CPX_PARAMTYPE_STRING: paramsetgetstr,
_const.CPX_PARAMTYPE_LONG: paramsetgetlong
}
func = switcher[paramtype]
return func(env, ps, whichparam)
[docs]
def paramsetgetdbl(env, ps, whichparam):
value = CR.doublePtr()
status = CR.CPXXparamsetgetdbl(env, ps, whichparam, value)
check_status(env, status)
return value.value()
[docs]
def paramsetgetint(env, ps, whichparam):
value = CR.intPtr()
status = CR.CPXXparamsetgetint(env, ps, whichparam, value)
check_status(env, status)
return value.value()
[docs]
def paramsetgetlong(env, ps, whichparam):
value = CR.cpxlongPtr()
status = CR.CPXXparamsetgetlong(env, ps, whichparam, value)
check_status(env, status)
return value.value()
[docs]
def paramsetgetstr(env, ps, whichparam):
output = []
status = CR.CPXXparamsetgetstr(env, ps, whichparam, output)
check_status(env, status)
return output[0]
[docs]
def paramsetgetids(env, ps):
cnt = paramsetgetnum(env, ps)
if cnt == 0:
return []
inout_list = [cnt]
status = CR.CPXXparamsetgetids(env, ps, inout_list)
check_status(env, status)
# We expect to get [whichparams]
assert len(inout_list) == 1
return inout_list[0]
[docs]
def paramsetreadcopy(env, ps, filename):
status = CR.CPXXparamsetreadcopy(env, ps, filename)
check_status(env, status)
[docs]
def paramsetwrite(env, ps, filename):
status = CR.CPXXparamsetwrite(env, ps, filename)
check_status(env, status)
[docs]
def paramsetgetnum(env, ps):
inout_list = [0]
status = CR.CPXXparamsetgetids(env, ps, inout_list)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
return inout_list[0]
########################################################################
# Runseeds
########################################################################
[docs]
def runseeds(env, lp, cnt):
with SigIntHandler():
status = CR.CPXErunseeds(env, lp, cnt)
check_status(env, status)
# Cplex
[docs]
def createprob(env, probname):
status = CR.intPtr()
lp = CR.CPXXcreateprob(env, status, probname)
check_status(env, status.value())
return lp
[docs]
def readcopyprob(env, lp, filename, filetype=""):
if filetype == "":
status = CR.CPXXreadcopyprob(env, lp, filename)
else:
status = CR.CPXXreadcopyprob(env, lp, filename, filetype)
check_status(env, status)
[docs]
def cloneprob(env, lp):
status = CR.intPtr()
lp = CR.CPXXcloneprob(env, lp, status)
check_status(env, status.value())
return lp
[docs]
def freeprob(env, lp):
lpp = CR.CPXLPptrPtr()
lpp.assign(lp)
status = CR.CPXXfreeprob(env, lpp)
check_status(env, status)
[docs]
def mipopt(env, lp):
with SigIntHandler():
status = CR.CPXXmipopt(env, lp)
check_status(env, status)
[docs]
def qpopt(env, lp):
with SigIntHandler():
status = CR.CPXXqpopt(env, lp)
check_status(env, status)
[docs]
def baropt(env, lp):
with SigIntHandler():
status = CR.CPXXbaropt(env, lp)
check_status(env, status)
[docs]
def hybbaropt(env, lp, method):
with SigIntHandler():
status = CR.CPXXhybbaropt(env, lp, method)
check_status(env, status)
[docs]
def hybnetopt(env, lp, method):
with SigIntHandler():
status = CR.CPXXhybnetopt(env, lp, method)
check_status(env, status)
[docs]
def lpopt(env, lp):
with SigIntHandler():
status = CR.CPXXlpopt(env, lp)
check_status(env, status)
[docs]
def primopt(env, lp):
status = CR.CPXXprimopt(env, lp)
check_status(env, status)
[docs]
def dualopt(env, lp):
status = CR.CPXXdualopt(env, lp)
check_status(env, status)
[docs]
def siftopt(env, lp):
status = CR.CPXXsiftopt(env, lp)
check_status(env, status)
[docs]
def feasoptext(env, lp, grppref, grpbeg, grpind, grptype):
grpcnt = len(grppref)
concnt = len(grpind)
with SigIntHandler(), \
LAU.double_c_array(grppref) as c_grppref, \
LAU.long_c_array(grpbeg) as c_grpbeg, \
LAU.int_c_array(grpind) as c_grpind:
status = CR.CPXXfeasoptext(env, lp, grpcnt, concnt,
c_grppref, c_grpbeg,
c_grpind, grptype)
check_status(env, status)
[docs]
def delnames(env, lp):
status = CR.CPXXdelnames(env, lp)
check_status(env, status)
[docs]
def writeprob(env, lp, filename, filetype=""):
if filetype == "":
status = CR.CPXXwriteprob(env, lp, filename)
else:
status = CR.CPXXwriteprob(env, lp, filename, filetype)
check_status(env, status)
[docs]
def writeprobdev(env, lp, stream, filename, filetype):
arg_list = [stream, filename, filetype]
status = CR.CPXEwriteprobdev(env, lp, arg_list)
check_status(env, status)
[docs]
def embwrite(env, lp, filename):
status = CR.CPXXembwrite(env, lp, filename)
check_status(env, status)
[docs]
def dperwrite(env, lp, filename, epsilon):
status = CR.CPXXdperwrite(env, lp, filename, epsilon)
check_status(env, status)
[docs]
def pperwrite(env, lp, filename, epsilon):
status = CR.CPXXpperwrite(env, lp, filename, epsilon)
check_status(env, status)
[docs]
def preslvwrite(env, lp, filename):
objoff = CR.doublePtr()
status = CR.CPXXpreslvwrite(env, lp, filename, objoff)
check_status(env, status)
return objoff.value()
[docs]
def dualwrite(env, lp, filename):
objshift = CR.doublePtr()
status = CR.CPXXdualwrite(env, lp, filename, objshift)
check_status(env, status)
return objshift.value()
[docs]
def chgprobtype(env, lp, probtype):
status = CR.CPXXchgprobtype(env, lp, probtype)
check_status(env, status)
[docs]
def chgprobtypesolnpool(env, lp, probtype, soln):
status = CR.CPXXchgprobtypesolnpool(env, lp, probtype, soln)
check_status(env, status)
[docs]
def getprobtype(env, lp):
return CR.CPXXgetprobtype(env, lp)
[docs]
def chgprobname(env, lp, probname):
status = CR.CPXXchgprobname(env, lp, probname)
check_status(env, status)
[docs]
def getprobname(env, lp):
namefn = CR.CPXXgetprobname
return _getnamesingle(env, lp, namefn)
[docs]
def getnumcols(env, lp):
return CR.CPXXgetnumcols(env, lp)
[docs]
def getnumint(env, lp):
return CR.CPXXgetnumint(env, lp)
[docs]
def getnumbin(env, lp):
return CR.CPXXgetnumbin(env, lp)
[docs]
def getnumsemicont(env, lp):
return CR.CPXXgetnumsemicont(env, lp)
[docs]
def getnumsemiint(env, lp):
return CR.CPXXgetnumsemiint(env, lp)
[docs]
def getnumrows(env, lp):
return CR.CPXXgetnumrows(env, lp)
[docs]
def populate(env, lp):
with SigIntHandler():
status = CR.CPXXpopulate(env, lp)
check_status(env, status)
def _getnumusercuts(env, lp):
return CR.CPXXgetnumusercuts(env, lp)
def _getnumlazyconstraints(env, lp):
return CR.CPXXgetnumlazyconstraints(env, lp)
[docs]
def getnumqconstrs(env, lp):
return CR.CPXXgetnumqconstrs(env, lp)
[docs]
def getnumindconstrs(env, lp):
return CR.CPXXgetnumindconstrs(env, lp)
[docs]
def getnumsos(env, lp):
return CR.CPXXgetnumsos(env, lp)
[docs]
def cleanup(env, lp, eps):
status = CR.CPXXcleanup(env, lp, eps)
check_status(env, status)
[docs]
def basicpresolve(env, lp):
numcols = CR.CPXXgetnumcols(env, lp)
numrows = CR.CPXXgetnumrows(env, lp)
redlb = _safeDoubleArray(numcols)
redub = _safeDoubleArray(numcols)
rstat = _safeIntArray(numrows)
status = CR.CPXXbasicpresolve(env, lp, redlb, redub, rstat)
check_status(env, status)
return (LAU.array_to_list(redlb, numcols),
LAU.array_to_list(redub, numcols),
LAU.array_to_list(rstat, numrows))
[docs]
def pivotin(env, lp, rlist):
status = CR.CPXXpivotin(env, lp,
LAU.int_list_to_array(rlist),
len(rlist))
check_status(env, status)
[docs]
def pivotout(env, lp, clist):
status = CR.CPXXpivotout(env, lp,
LAU.int_list_to_array(clist),
len(clist))
check_status(env, status)
[docs]
def pivot(env, lp, jenter, jleave, leavestat):
status = CR.CPXXpivot(env, lp, jenter, jleave, leavestat)
check_status(env, status)
[docs]
def strongbranch(env, lp, goodlist, itlim):
goodlen = len(goodlist)
downpen = _safeDoubleArray(goodlen)
uppen = _safeDoubleArray(goodlen)
with SigIntHandler():
status = CR.CPXXstrongbranch(
env, lp, LAU.int_list_to_array(goodlist), goodlen,
downpen, uppen, itlim)
check_status(env, status)
return (LAU.array_to_list(downpen, goodlen),
LAU.array_to_list(uppen, goodlen))
[docs]
def completelp(env, lp):
status = CR.CPXXcompletelp(env, lp)
check_status(env, status)
# Variables
[docs]
@contextmanager
def fast_getrows(env, lp):
env_lp_ptr = pack_env_lp_ptr(env, lp)
rows = CR.CPXX_fast_get_rows(env_lp_ptr)
try:
yield rows
finally:
CR.CPXX_free_rows(rows)
[docs]
@contextmanager
def fast_getcolname(env, lp, begin, end):
env_lp_ptr = pack_env_lp_ptr(env, lp)
names = CR.CPXX_fast_getcolname(env_lp_ptr, begin, end)
try:
yield names
finally:
CR.CPXX_free_getname(names)
[docs]
@contextmanager
def fast_getrowname(env, lp, begin, end):
env_lp_ptr = pack_env_lp_ptr(env, lp)
names = CR.CPXX_fast_getrowname(env_lp_ptr, begin, end)
try:
yield names
finally:
CR.CPXX_free_getname(names)
[docs]
@contextmanager
def fast_getsosname(env, lp, begin, end):
env_lp_ptr = pack_env_lp_ptr(env, lp)
names = CR.CPXX_fast_getsosname(env_lp_ptr, begin, end)
try:
yield names
finally:
CR.CPXX_free_getname(names)
[docs]
@contextmanager
def fast_getmipstartname(env, lp, begin, end):
env_lp_ptr = pack_env_lp_ptr(env, lp)
names = CR.CPXX_fast_getmipstartname(env_lp_ptr, begin, end)
try:
yield names
finally:
CR.CPXX_free_getname(names)
[docs]
@contextmanager
def fast_getobj(env, lp, begin, end):
env_lp_ptr = pack_env_lp_ptr(env, lp)
coefs = CR.CPXX_fast_getobj(env_lp_ptr, begin, end)
try:
yield coefs
finally:
CR.CPXX_free_getobj(coefs)
[docs]
@contextmanager
def fast_multiobjgetobj(env, lp, objidx, begin, end):
env_lp_ptr = pack_env_lp_ptr(env, lp)
coefs = CR.CPXX_fast_multiobjgetobj(env_lp_ptr, objidx, begin, end)
try:
yield coefs
finally:
CR.CPXX_free_getobj(coefs)
[docs]
def fast_multiobjgetoffset(env, lp, objidx):
env_lp_ptr = pack_env_lp_ptr(env, lp)
return CR.CPXX_fast_multiobjgetoffset(env_lp_ptr, objidx)
[docs]
def fast_multiobjgetweight(env, lp, objidx):
env_lp_ptr = pack_env_lp_ptr(env, lp)
return CR.CPXX_fast_multiobjgetweight(env_lp_ptr, objidx)
[docs]
def fast_multiobjgetpriority(env, lp, objidx):
env_lp_ptr = pack_env_lp_ptr(env, lp)
return CR.CPXX_fast_multiobjgetpriority(env_lp_ptr, objidx)
[docs]
def fast_multiobjgetabstol(env, lp, objidx):
env_lp_ptr = pack_env_lp_ptr(env, lp)
return CR.CPXX_fast_multiobjgetabstol(env_lp_ptr, objidx)
[docs]
def fast_multiobjgetreltol(env, lp, objidx):
env_lp_ptr = pack_env_lp_ptr(env, lp)
return CR.CPXX_fast_multiobjgetreltol(env_lp_ptr, objidx)
[docs]
def fast_newcols(env, lp, nb, lb, ub, xctype):
env_lp_ptr = pack_env_lp_ptr(env, lp)
CR.CPXX_fast_newcols(env_lp_ptr, nb, lb, ub, xctype)
[docs]
def has_name(env, lp, start, end):
env_lp_ptr = pack_env_lp_ptr(env, lp)
return True if CR.CPXX_has_name(env_lp_ptr, start, end) != 0 else False
[docs]
def has_non_default_lb(env, lp, start, end):
env_lp_ptr = pack_env_lp_ptr(env, lp)
return True if CR.CPXX_has_non_default_lb(env_lp_ptr, start, end) != 0 else False
[docs]
def has_non_default_ub(env, lp, start, end):
env_lp_ptr = pack_env_lp_ptr(env, lp)
return True if CR.CPXX_has_non_default_ub(env_lp_ptr, start, end) != 0 else False
[docs]
def newcols(env, lp, obj, lb, ub, xctype, colname):
ccnt = max(len(obj), len(lb), len(ub), len(xctype), len(colname))
with LAU.double_c_array(obj) as c_obj, \
LAU.double_c_array(lb) as c_lb, \
LAU.double_c_array(ub) as c_ub:
status = CR.CPXXnewcols(
env, lp, ccnt, c_obj, c_lb, c_ub,
xctype, colname)
check_status(env, status)
[docs]
def addcols(env, lp, ccnt, nzcnt, obj, cmat, lb, ub, colname):
with LAU.double_c_array(obj) as c_obj, \
LAU.double_c_array(lb) as c_lb, \
LAU.double_c_array(ub) as c_ub:
status = CR.CPXXaddcols(
env, lp, ccnt, nzcnt,
c_obj, cmat, c_lb, c_ub, colname)
check_status(env, status)
[docs]
def delcols(env, lp, begin, end):
delfn = CR.CPXXdelcols
_delbyrange(delfn, env, lp, begin, end)
[docs]
def chgbds(env, lp, indices, lu, bd):
with LAU.int_c_array(indices) as c_ind, \
LAU.double_c_array(bd) as c_bd:
status = CR.CPXXchgbds(env, lp, len(indices),
c_ind, lu, c_bd)
check_status(env, status)
[docs]
def chgcolname(env, lp, indices, newnames):
with LAU.int_c_array(indices) as c_indices:
status = CR.CPXXchgcolname(env, lp, len(indices),
c_indices, newnames)
check_status(env, status)
[docs]
def chgctype(env, lp, indices, xctype):
with LAU.int_c_array(indices) as c_indices:
status = CR.CPXXchgctype(env, lp, len(indices),
c_indices, xctype)
check_status(env, status)
[docs]
def getcolindex(env, lp, colname):
index = CR.intPtr()
status = CR.CPXXgetcolindex(env, lp, colname, index)
check_status(env, status)
return index.value()
[docs]
def getcolname(env, lp, begin, end):
namefn = CR.CPXXgetcolname
return _getnamebyrange(env, lp, begin, end, namefn)
[docs]
def getctype(env, lp, begin, end):
inout_list = [begin, end]
status = CR.CPXXgetctype(env, lp, inout_list)
check_status(env, status)
# We expect to get [sense]
assert len(inout_list) == 1
return inout_list[0]
[docs]
def getlb(env, lp, begin, end):
lblen = _rangelen(begin, end)
lb = _safeDoubleArray(lblen)
status = CR.CPXXgetlb(env, lp, lb, begin, end)
check_status(env, status)
return LAU.array_to_list(lb, lblen)
[docs]
def getub(env, lp, begin, end):
ublen = _rangelen(begin, end)
ub = _safeDoubleArray(ublen)
status = CR.CPXXgetub(env, lp, ub, begin, end)
check_status(env, status)
return LAU.array_to_list(ub, ublen)
[docs]
def getcols(env, lp, begin, end):
inout_list = [0, begin, end]
status = CR.CPXXgetcols(env, lp, inout_list)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
if inout_list == [0]:
return ([0] * _rangelen(begin, end), [], [])
inout_list.extend([begin, end])
status = CR.CPXXgetcols(env, lp, inout_list)
check_status(env, status)
return tuple(inout_list)
[docs]
def copyprotected(env, lp, indices):
status = CR.CPXXcopyprotected(env, lp, len(indices),
LAU.int_list_to_array(indices))
check_status(env, status)
[docs]
def getprotected(env, lp):
count = CR.intPtr()
surplus = CR.intPtr()
indices = LAU.int_list_to_array([])
pspace = 0
status = CR.CPXXgetprotected(env, lp, count, indices, pspace, surplus)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
if surplus.value() == 0:
return []
pspace = -surplus.value()
indices = _safeIntArray(pspace)
status = CR.CPXXgetprotected(env, lp, count, indices, pspace, surplus)
check_status(env, status)
return LAU.array_to_list(indices, pspace)
[docs]
def tightenbds(env, lp, indices, lu, bd):
status = CR.CPXXtightenbds(env, lp, len(indices),
LAU.int_list_to_array(indices),
lu, LAU.double_list_to_array(bd))
check_status(env, status)
# Linear Constraints
[docs]
def newrows(env, lp, rhs, sense, rngval, rowname):
rcnt = max(len(rhs), len(sense), len(rngval), len(rowname))
with LAU.double_c_array(rhs) as c_rhs, \
LAU.double_c_array(rngval) as c_rng:
status = CR.CPXXnewrows(env, lp, rcnt, c_rhs, sense,
c_rng, rowname)
check_status(env, status)
[docs]
def addrows(env, lp, ccnt, rcnt, nzcnt, rhs, sense, rmat, colname, rowname):
with LAU.double_c_array(rhs) as c_rhs:
status = CR.CPXXaddrows(
env, lp, ccnt, rcnt, nzcnt, c_rhs,
sense, rmat, colname, rowname)
check_status(env, status)
[docs]
def delrows(env, lp, begin, end):
delfn = CR.CPXXdelrows
_delbyrange(delfn, env, lp, begin, end)
[docs]
def chgrowname(env, lp, indices, newnames):
with LAU.int_c_array(indices) as c_indices:
status = CR.CPXXchgrowname(env, lp, len(indices), c_indices,
newnames)
check_status(env, status)
[docs]
def chgcoeflist(env, lp, rowlist, collist, vallist):
with LAU.int_c_array(rowlist) as c_rowlist, \
LAU.int_c_array(collist) as c_collist, \
LAU.double_c_array(vallist) as c_vallist:
status = CR.CPXXchgcoeflist(env, lp, len(rowlist),
c_rowlist, c_collist, c_vallist)
check_status(env, status)
[docs]
def chgrhs(env, lp, indices, values):
with LAU.int_c_array(indices) as c_ind, \
LAU.double_c_array(values) as c_val:
status = CR.CPXXchgrhs(env, lp, len(indices), c_ind, c_val)
check_status(env, status)
[docs]
def chgrngval(env, lp, indices, values):
with LAU.int_c_array(indices) as c_ind, \
LAU.double_c_array(values) as c_val:
status = CR.CPXXchgrngval(env, lp, len(indices), c_ind, c_val)
check_status(env, status)
[docs]
def chgsense(env, lp, indices, senses):
with LAU.int_c_array(indices) as c_indices:
status = CR.CPXXchgsense(env, lp, len(indices), c_indices,
senses)
check_status(env, status)
[docs]
def getrhs(env, lp, begin, end):
rhslen = _rangelen(begin, end)
rhs = _safeDoubleArray(rhslen)
status = CR.CPXXgetrhs(env, lp, rhs, begin, end)
check_status(env, status)
return LAU.array_to_list(rhs, rhslen)
[docs]
def getsense(env, lp, begin, end):
inout_list = [begin, end]
status = CR.CPXXgetsense(env, lp, inout_list)
check_status(env, status)
# We expect to get [sense]
assert len(inout_list) == 1
return inout_list[0]
[docs]
def getrngval(env, lp, begin, end):
rngvallen = _rangelen(begin, end)
rngval = _safeDoubleArray(rngvallen)
status = CR.CPXXgetrngval(env, lp, rngval, begin, end)
check_status(env, status)
return LAU.array_to_list(rngval, rngvallen)
[docs]
def getrowname(env, lp, begin, end):
namefn = CR.CPXXgetrowname
return _getnamebyrange(env, lp, begin, end, namefn)
[docs]
def getcoef(env, lp, i, j):
coef = CR.doublePtr()
status = CR.CPXXgetcoef(env, lp, i, j, coef)
check_status(env, status)
return coef.value()
[docs]
def getrowindex(env, lp, rowname):
index = CR.intPtr()
status = CR.CPXXgetrowindex(env, lp, rowname, index)
check_status(env, status)
return index.value()
[docs]
def getrows(env, lp, begin, end):
inout_list = [0, begin, end]
status = CR.CPXXgetrows(env, lp, inout_list)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
if inout_list == [0]:
return ([0] * _rangelen(begin, end), [], [])
inout_list.extend([begin, end])
status = CR.CPXXgetrows(env, lp, inout_list)
check_status(env, status)
return tuple(inout_list)
[docs]
def getnumnz(env, lp):
return CR.CPXXgetnumnz(env, lp)
[docs]
def addlazyconstraints(env, lp, rhs, sense, lin_expr, names):
env_lp_ptr = pack_env_lp_ptr(env, lp)
with chbmatrix(lin_expr, env_lp_ptr, 0) as (rmat, nnz), \
LAU.double_c_array(rhs) as c_rhs:
rmatbeg, rmatind, rmatval = rmat
status = CR.CPXXaddlazyconstraints(
env, lp, len(rhs), nnz,
c_rhs, sense,
rmatbeg, rmatind, rmatval,
names)
check_status(env, status)
[docs]
def addusercuts(env, lp, rhs, sense, lin_expr, names):
env_lp_ptr = pack_env_lp_ptr(env, lp)
with chbmatrix(lin_expr, env_lp_ptr, 0) as (rmat, nnz), \
LAU.double_c_array(rhs) as c_rhs:
rmatbeg, rmatind, rmatval = rmat
status = CR.CPXXaddusercuts(
env, lp, len(rhs), nnz,
c_rhs, sense,
rmatbeg, rmatind, rmatval,
names)
check_status(env, status)
[docs]
def freelazyconstraints(env, lp):
status = CR.CPXXfreelazyconstraints(env, lp)
check_status(env, status)
[docs]
def freeusercuts(env, lp):
status = CR.CPXXfreeusercuts(env, lp)
check_status(env, status)
# CPXLIBAPI int CPXPUBLIC
# CPXXcopylpwnames (CPXCENVptr env,
# CPXLPptr lp,
# CPXDIM numcols,
# CPXDIM numrows,
# int objsense,
# const double *objective,
# const double *rhs,
# const char *sense,
# CPXNNZ int *matbeg,
# CPXDIM int *matcnt,
# CPXDIM int *matind,
# const double *matval,
# const double *lb,
# const double *ub,
# const double *rngval,
# char const *const *colname,
# char const *const *rowname);
[docs]
def copylpwnames(env, lp, numcols, numrows, objsense, obj, rhs, sense,
matbeg, matcnt, matind, matval, lb, ub, rngval, colname,
rowname):
with LAU.long_c_array(matbeg) as c_matbeg, \
LAU.int_c_array(matcnt) as c_matcnt, \
LAU.int_c_array(matind) as c_matind, \
LAU.double_c_array(matval) as c_matval, \
LAU.double_c_array(obj) as c_obj, \
LAU.double_c_array(rhs) as c_rhs, \
LAU.double_c_array(lb) as c_lb, \
LAU.double_c_array(ub) as c_ub, \
LAU.double_c_array(rngval) as c_rngval: # noqa: E126
status = CR.CPXXcopylpwnames(env, lp, numcols, numrows, objsense,
c_obj, c_rhs, sense,
c_matbeg, c_matcnt, c_matind, c_matval,
c_lb, c_ub, c_rngval,
colname, rowname)
check_status(env, status)
########################################################################
# SOS API
########################################################################
[docs]
def addsos(env, lp, sostype, sosbeg, sosind, soswt, sosnames):
with LAU.long_c_array(sosbeg) as c_sosbeg, \
LAU.int_c_array(sosind) as c_sosind, \
LAU.double_c_array(soswt) as c_soswt:
status = CR.CPXXaddsos(env, lp, len(sosbeg), len(sosind), sostype,
c_sosbeg, c_sosind, c_soswt,
sosnames)
check_status(env, status)
[docs]
def delsos(env, lp, begin, end):
delfn = CR.CPXXdelsos
_delbyrange(delfn, env, lp, begin, end)
[docs]
def getsos_info(env, lp, begin, end):
inout_list = [0, begin, end]
status = CR.CPXXgetsos(env, lp, inout_list)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
# We expect to get [sostype, surplus]
assert len(inout_list) == 2
return tuple(inout_list)
[docs]
def getsos(env, lp, begin, end):
numsos = _rangelen(begin, end)
_, surplus = getsos_info(env, lp, begin, end)
if surplus == 0:
return ([0] * numsos, [], [])
inout_list = [surplus, begin, end]
status = CR.CPXXgetsos(env, lp, inout_list)
check_status(env, status)
# We expect to get [sosbeg, sosind, soswt]
assert len(inout_list) == 3
return tuple(inout_list)
[docs]
def getsosindex(env, lp, name):
indexfn = CR.CPXXgetsosindex
return _getindex(env, lp, name, indexfn)
[docs]
def getsosname(env, lp, begin, end):
namefn = CR.CPXXgetsosname
return _getnamebyrange(env, lp, begin, end, namefn)
########################################################################
# Indicator Constraint API
########################################################################
[docs]
def addindconstr(env, lp, indcnt, indvar, complemented, rhs, sense, linmat,
indtype, name, nzcnt):
with LAU.int_c_array(indtype) as c_indtype, \
LAU.int_c_array(indvar) as c_indvar, \
LAU.int_c_array(complemented) as c_complemented, \
LAU.double_c_array(rhs) as c_rhs:
status = CR.CPXXaddindconstraints(
env, lp, indcnt, c_indtype, c_indvar,
c_complemented, nzcnt, c_rhs,
sense, linmat,
name)
check_status(env, status)
[docs]
def getindconstr(env, lp, begin, end):
_, _, _, _, _, surplus = getindconstr_constant(env, lp, begin, end)
if surplus == 0:
return ([0] * _rangelen(begin, end), [], [])
# inout_list contains the linspace, begin, and end args to
# CPXXgetindconstraints.
inout_list = [surplus, begin, end]
status = CR.CPXXgetindconstraints(env, lp, inout_list)
check_status(env, status)
# We expect to get [linbeg, linind, linval]
assert len(inout_list) == 3
return tuple(inout_list)
[docs]
def getindconstr_constant(env, lp, begin, end):
# inout_list contains the linspace, begin, and end args to
# CPXXgetindconstraints.
inout_list = [0, begin, end]
status = CR.CPXXgetindconstraints(env, lp, inout_list)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
# We expect to get:
# [type, indvar, complemented, rhs, sense, surplus]
assert len(inout_list) == 6
return tuple(inout_list)
[docs]
def getindconstrindex(env, lp, name):
indexfn = CR.CPXXgetindconstrindex
return _getindex(env, lp, name, indexfn)
[docs]
def delindconstrs(env, lp, begin, end):
delfn = CR.CPXXdelindconstrs
_delbyrange(delfn, env, lp, begin, end)
[docs]
def getindconstrslack(env, lp, begin, end):
slacklen = _rangelen(begin, end)
slacks = _safeDoubleArray(slacklen)
status = CR.CPXXgetindconstrslack(env, lp, slacks, begin, end)
check_status(env, status)
return LAU.array_to_list(slacks, slacklen)
[docs]
def getindconstrname(env, lp, which):
namefn = CR.CPXXgetindconstrname
return _getname(env, lp, which, namefn, index_first=False)
########################################################################
# Quadratic Constraints
########################################################################
[docs]
def addqconstr(env, lp, rhs, sense, linind, linval, quadrow, quadcol,
quadval, name):
with LAU.int_c_array(linind) as c_linind, \
LAU.double_c_array(linval) as c_linval, \
LAU.int_c_array(quadrow) as c_quadrow, \
LAU.int_c_array(quadcol) as c_quadcol, \
LAU.double_c_array(quadval) as c_quadval:
status = CR.CPXXaddqconstr(env, lp, len(linind), len(quadrow),
rhs, sense,
c_linind, c_linval,
c_quadrow, c_quadcol, c_quadval,
name)
check_status(env, status)
[docs]
def getqconstr_info(env, lp, which):
inout_list = [0, 0, which]
status = CR.CPXXgetqconstr(env, lp, inout_list)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
# We expect to get [rhs, sense, linsurplus, quadsurplus]
assert len(inout_list) == 4
assert len(inout_list[1]) == 1 # sense string should be one char
return tuple(inout_list)
[docs]
def getqconstr_lin(env, lp, which):
_, _, linsurplus, _ = getqconstr_info(env, lp, which)
if linsurplus == 0:
return ([], [])
inout_list = [linsurplus, 0, which]
status = CR.CPXXgetqconstr(env, lp, inout_list)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
# We expect to get [linind, linval, quadrow, quadcol, quadval]
assert len(inout_list) == 5
return tuple(inout_list[:2]) # slice off the quad info
[docs]
def getqconstr_quad(env, lp, which):
_, _, _, quadsurplus = getqconstr_info(env, lp, which)
if quadsurplus == 0:
return ([], [], [])
inout_list = [0, quadsurplus, which]
status = CR.CPXXgetqconstr(env, lp, inout_list)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
# We expect to get [linind, linval, quadrow, quadcol, quadval]
assert len(inout_list) == 5
return tuple(inout_list[2:]) # slice off the lin info
[docs]
def delqconstrs(env, lp, begin, end):
delfn = CR.CPXXdelqconstrs
_delbyrange(delfn, env, lp, begin, end)
[docs]
def getqconstrindex(env, lp, name):
indexfn = CR.CPXXgetqconstrindex
return _getindex(env, lp, name, indexfn)
[docs]
def getqconstrslack(env, lp, begin, end):
slacklen = _rangelen(begin, end)
slacks = _safeDoubleArray(slacklen)
status = CR.CPXXgetqconstrslack(env, lp, slacks, begin, end)
check_status(env, status)
return LAU.array_to_list(slacks, slacklen)
[docs]
def getqconstrname(env, lp, which):
namefn = CR.CPXXgetqconstrname
return _getname(env, lp, which, namefn, index_first=False)
########################################################################
# Generic helper methods
########################################################################
def _delbyrange(delfn, env, lp, begin, end=None):
if end is None:
end = begin
status = delfn(env, lp, begin, end)
check_status(env, status)
def _getindex(env, lp, name, indexfn):
idx = CR.intPtr()
status = indexfn(env, lp, name, idx)
check_status(env, status)
return idx.value()
def _getname(env, lp, idx, namefn, index_first=True):
# Some name functions have the index argument first and some have it
# last. Thus, we do this little dance, so things are called in the
# right way depending on index_first.
def _namefn(env, lp, idx, inoutlist):
if index_first:
return namefn(env, lp, idx, inoutlist)
return namefn(env, lp, inoutlist, idx)
inoutlist = [0]
# NB: inoutlist will be modified as a side effect
status = _namefn(env, lp, idx, inoutlist)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
if inoutlist == [0]:
return None
status = _namefn(env, lp, idx, inoutlist)
check_status(env, status)
return inoutlist[0]
def _getnamebyrange(env, lp, begin, end, namefn):
inout_list = [0, begin, end]
status = namefn(env, lp, inout_list)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
if inout_list == [0]:
return [None] * _rangelen(begin, end)
inout_list.extend([begin, end])
status = namefn(env, lp, inout_list)
check_status(env, status)
return inout_list
def _getnamesingle(env, lp, namefn):
inoutlist = [0]
status = namefn(env, lp, inoutlist)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
if inoutlist == [0]:
return None
status = namefn(env, lp, inoutlist)
check_status(env, status)
return inoutlist[0]
########################################################################
# Annotation API
########################################################################
def _newanno(env, lp, name, defval, newfn):
status = newfn(env, lp, name, defval)
check_status(env, status)
[docs]
def newlonganno(env, lp, name, defval):
newfn = CR.CPXXnewlongannotation
_newanno(env, lp, name, defval, newfn)
[docs]
def newdblanno(env, lp, name, defval):
newfn = CR.CPXXnewdblannotation
_newanno(env, lp, name, defval, newfn)
[docs]
def dellonganno(env, lp, begin, end):
delfn = CR.CPXXdellongannotations
_delbyrange(delfn, env, lp, begin, end)
[docs]
def deldblanno(env, lp, begin, end):
delfn = CR.CPXXdeldblannotations
_delbyrange(delfn, env, lp, begin, end)
[docs]
def getlongannoindex(env, lp, name):
indexfn = CR.CPXXgetlongannotationindex
return _getindex(env, lp, name, indexfn)
[docs]
def getdblannoindex(env, lp, name):
indexfn = CR.CPXXgetdblannotationindex
return _getindex(env, lp, name, indexfn)
[docs]
def getlongannoname(env, lp, idx):
namefn = CR.CPXXgetlongannotationname
return _getname(env, lp, idx, namefn)
[docs]
def getdblannoname(env, lp, idx):
namefn = CR.CPXXgetdblannotationname
return _getname(env, lp, idx, namefn)
[docs]
def getnumlonganno(env, lp):
return CR.CPXXgetnumlongannotations(env, lp)
[docs]
def getnumdblanno(env, lp):
return CR.CPXXgetnumdblannotations(env, lp)
[docs]
def getlongannodefval(env, lp, idx):
defval = CR.cpxlongPtr()
status = CR.CPXXgetlongannotationdefval(env, lp, idx, defval)
check_status(env, status)
return int(defval.value())
[docs]
def getdblannodefval(env, lp, idx):
defval = CR.doublePtr()
status = CR.CPXXgetdblannotationdefval(env, lp, idx, defval)
check_status(env, status)
return defval.value()
[docs]
def setlonganno(env, lp, idx, objtype, ind, val):
assert len(ind) == len(val)
cnt = len(ind)
status = CR.CPXXsetlongannotations(env, lp, idx, objtype, cnt,
LAU.int_list_to_array(ind),
LAU.long_list_to_array(val))
check_status(env, status)
[docs]
def setdblanno(env, lp, idx, objtype, ind, val):
assert len(ind) == len(val)
cnt = len(ind)
status = CR.CPXXsetdblannotations(env, lp, idx, objtype, cnt,
LAU.int_list_to_array(ind),
LAU.double_list_to_array(val))
check_status(env, status)
[docs]
def getlonganno(env, lp, idx, objtype, begin, end):
annolen = _rangelen(begin, end)
val = _safeLongArray(annolen)
status = CR.CPXXgetlongannotations(env, lp, idx, objtype, val,
begin, end)
check_status(env, status)
return [int(i) for i in LAU.array_to_list(val, annolen)]
[docs]
def getdblanno(env, lp, idx, objtype, begin, end):
annolen = _rangelen(begin, end)
val = _safeDoubleArray(annolen)
status = CR.CPXXgetdblannotations(env, lp, idx, objtype, val,
begin, end)
check_status(env, status)
return LAU.array_to_list(val, annolen)
[docs]
def readcopyanno(env, lp, filename):
status = CR.CPXXreadcopyannotations(env, lp, filename)
check_status(env, status)
[docs]
def writeanno(env, lp, filename):
status = CR.CPXXwriteannotations(env, lp, filename)
check_status(env, status)
[docs]
def writebendersanno(env, lp, filename):
status = CR.CPXXwritebendersannotation(env, lp, filename)
check_status(env, status)
########################################################################
# PWL API
########################################################################
[docs]
def addpwl(env, lp, vary, varx, preslope, postslope, nbreaks,
breakx, breaky, name):
assert len(breakx) == nbreaks
assert len(breaky) == nbreaks
with LAU.double_c_array(breakx) as c_breakx, \
LAU.double_c_array(breaky) as c_breaky:
status = CR.CPXXaddpwl(env, lp, vary, varx, preslope, postslope,
nbreaks, c_breakx, c_breaky, name)
check_status(env, status)
[docs]
def delpwl(env, lp, begin, end):
delfn = CR.CPXXdelpwl
_delbyrange(delfn, env, lp, begin, end)
[docs]
def getnumpwl(env, lp):
return CR.CPXXgetnumpwl(env, lp)
[docs]
def getpwl(env, lp, idx):
# Initially, the inout_list contains the pwlindex and breakspace args
# to CPXXgetpwl. We use zero (0) for breakspace to query the
# surplus.
inout_list = [idx, 0]
status = CR.CPXXgetpwl(env, lp, inout_list)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
# We expect to get [vary, varx, preslope, postslope, surplus]
assert len(inout_list) == 5
vary, varx, preslope, postslope, surplus = inout_list
# FIXME: Should we assert surplus is > 0?
inout_list = [idx, surplus]
status = CR.CPXXgetpwl(env, lp, inout_list)
check_status(env, status)
# We expect to get [breakx, breaky]
assert len(inout_list) == 2
breakx, breaky = inout_list
return [vary, varx, preslope, postslope, breakx, breaky]
[docs]
def getpwlindex(env, lp, name):
indexfn = CR.CPXXgetpwlindex
return _getindex(env, lp, name, indexfn)
[docs]
def getpwlname(env, lp, idx):
namefn = CR.CPXXgetpwlname
return _getname(env, lp, idx, namefn, index_first=False)
########################################################################
# Objective API
########################################################################
[docs]
def copyobjname(env, lp, objname):
status = CR.CPXXcopyobjname(env, lp, objname)
check_status(env, status)
[docs]
def chgobj(env, lp, indices, values):
with LAU.int_c_array(indices) as c_ind, \
LAU.double_c_array(values) as c_val:
status = CR.CPXXchgobj(env, lp, len(indices), c_ind, c_val)
check_status(env, status)
[docs]
def chgobjsen(env, lp, maxormin):
status = CR.CPXXchgobjsen(env, lp, maxormin)
check_status(env, status)
[docs]
def getobjsen(env, lp):
return CR.CPXXgetobjsen(env, lp)
[docs]
def getobjoffset(env, lp):
objoffset = CR.doublePtr()
status = CR.CPXXgetobjoffset(env, lp, objoffset)
check_status(env, status)
return objoffset.value()
[docs]
def chgobjoffset(env, lp, offset):
status = CR.CPXXchgobjoffset(env, lp, offset)
check_status(env, status)
[docs]
def getobj(env, lp, begin, end):
objlen = _rangelen(begin, end)
obj = _safeDoubleArray(objlen)
status = CR.CPXXgetobj(env, lp, obj, begin, end)
check_status(env, status)
return LAU.array_to_list(obj, objlen)
[docs]
def getobjname(env, lp):
namefn = CR.CPXXgetobjname
return _getnamesingle(env, lp, namefn)
[docs]
def copyquad(env, lp, qmatbeg, qmatind, qmatval):
nqmatbeg = len(qmatbeg)
if nqmatbeg > 0:
qmatcnt = [qmatbeg[i + 1] - qmatbeg[i]
for i in range(nqmatbeg - 1)]
qmatcnt.append(len(qmatind) - qmatbeg[-1])
else:
qmatcnt = []
with LAU.long_c_array(qmatbeg) as c_qmatbeg, \
LAU.int_c_array(qmatcnt) as c_qmatcnt, \
LAU.int_c_array(qmatind) as c_qmatind, \
LAU.double_c_array(qmatval) as c_qmatval:
status = CR.CPXXcopyquad(env, lp, c_qmatbeg, c_qmatcnt,
c_qmatind, c_qmatval)
check_status(env, status)
[docs]
def copyqpsep(env, lp, qsepvec):
with LAU.double_c_array(qsepvec) as c_qsepvec:
status = CR.CPXXcopyqpsep(env, lp, c_qsepvec)
check_status(env, status)
[docs]
def chgqpcoef(env, lp, row, col, value):
status = CR.CPXXchgqpcoef(env, lp, row, col, value)
check_status(env, status)
[docs]
def getquad(env, lp, begin, end):
nzcnt = CR.cpxlongPtr()
ncols = _rangelen(begin, end)
qmatbeg = _safeLongArray(ncols)
qmatind = LAU.int_list_to_array([])
qmatval = LAU.double_list_to_array([])
space = 0
surplus = CR.cpxlongPtr()
status = CR.CPXXgetquad(env, lp, nzcnt, qmatbeg, qmatind, qmatval,
space, surplus, begin, end)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
if surplus.value() == 0:
return ([], [], [])
space = -surplus.value()
qmatind = _safeIntArray(space)
qmatval = _safeDoubleArray(space)
status = CR.CPXXgetquad(env, lp, nzcnt, qmatbeg, qmatind, qmatval,
space, surplus, begin, end)
check_status(env, status)
return (LAU.array_to_list(qmatbeg, ncols),
LAU.array_to_list(qmatind, space),
LAU.array_to_list(qmatval, space))
[docs]
def getqpcoef(env, lp, row, col):
val = CR.doublePtr()
status = CR.CPXXgetqpcoef(env, lp, row, col, val)
check_status(env, status)
return val.value()
[docs]
def getnumquad(env, lp):
return CR.CPXXgetnumquad(env, lp)
[docs]
def getnumqpnz(env, lp):
return CR.CPXXgetnumqpnz(env, lp)
########################################################################
# Multi-Objective API
########################################################################
[docs]
def getnumobjs(env, lp):
return CR.CPXXgetnumobjs(env, lp)
[docs]
def multiobjchgattribs(env, lp, objidx,
offset=_const.CPX_NO_OFFSET_CHANGE,
weight=_const.CPX_NO_WEIGHT_CHANGE,
priority=_const.CPX_NO_PRIORITY_CHANGE,
abstol=_const.CPX_NO_ABSTOL_CHANGE,
reltol=_const.CPX_NO_RELTOL_CHANGE,
name=None):
status = CR.CPXXmultiobjchgattribs(env, lp, objidx, offset, weight,
priority, abstol, reltol,
name)
check_status(env, status)
[docs]
def multiobjgetindex(env, lp, name):
indexfn = CR.CPXXmultiobjgetindex
return _getindex(env, lp, name, indexfn)
[docs]
def multiobjgetname(env, lp, objidx):
namefn = CR.CPXXmultiobjgetname
return _getname(env, lp, objidx, namefn, index_first=True)
[docs]
def multiobjgetobj(env, lp, objidx, begin, end):
coeffslen = _rangelen(begin, end)
coeffs = _safeDoubleArray(coeffslen)
offset = CR.doublePtr()
weight = CR.doublePtr()
priority = CR.intPtr()
abstol = CR.doublePtr()
reltol = CR.doublePtr()
status = CR.CPXXmultiobjgetobj(env, lp, objidx, coeffs, begin, end,
offset, weight, priority, abstol, reltol)
check_status(env, status)
return [LAU.array_to_list(coeffs, coeffslen), offset.value(),
weight.value(), priority.value(), abstol.value(),
reltol.value()]
[docs]
def multiobjsetobj(env, lp, objidx, objind, objval,
offset=_const.CPX_NO_OFFSET_CHANGE,
weight=_const.CPX_NO_WEIGHT_CHANGE,
priority=_const.CPX_NO_PRIORITY_CHANGE,
abstol=_const.CPX_NO_ABSTOL_CHANGE,
reltol=_const.CPX_NO_RELTOL_CHANGE,
objname=None):
objnz = len(objind)
assert len(objval) == objnz
with LAU.int_c_array(objind) as c_objind, \
LAU.double_c_array(objval) as c_objval: # noqa: E127
status = CR.CPXXmultiobjsetobj(env, lp, objidx, objnz, c_objind,
c_objval, offset, weight,
priority, abstol, reltol,
objname)
check_status(env, status)
[docs]
def setnumobjs(env, lp, n):
status = CR.CPXXsetnumobjs(env, lp, n)
check_status(env, status)
[docs]
def multiobjopt(env, lp, paramsets):
with SigIntHandler():
status = CR.CPXXmultiobjopt(env, lp, paramsets)
check_status(env, status)
[docs]
def multiobjgetobjval(env, lp, objidx):
objval_p = CR.doublePtr()
status = CR.CPXXmultiobjgetobjval(env, lp, objidx, objval_p)
check_status(env, status)
return objval_p.value()
[docs]
def multiobjgetobjvalbypriority(env, lp, priority):
objval_p = CR.doublePtr()
status = CR.CPXXmultiobjgetobjvalbypriority(env, lp, priority, objval_p)
check_status(env, status)
return objval_p.value()
def _multiobjgetinfo(fn, env, lp, subprob, info_p, what):
status = fn(env, lp, subprob, info_p, what)
check_status(env, status)
return info_p.value()
[docs]
def multiobjgetdblinfo(env, lp, subprob, what):
info_p = CR.doublePtr()
return _multiobjgetinfo(CR.CPXXmultiobjgetdblinfo, env, lp, subprob,
info_p, what)
[docs]
def multiobjgetintinfo(env, lp, subprob, what):
info_p = CR.intPtr()
return _multiobjgetinfo(CR.CPXXmultiobjgetintinfo, env, lp, subprob,
info_p, what)
[docs]
def multiobjgetlonginfo(env, lp, subprob, what):
info_p = CR.cpxlongPtr()
return _multiobjgetinfo(CR.CPXXmultiobjgetlonginfo, env, lp, subprob,
info_p, what)
[docs]
def multiobjgetnumsolves(env, lp):
return CR.CPXXmultiobjgetnumsolves(env, lp)
[docs]
def getnumprios(env, lp):
return CR.CPXEgetnumprios(env, lp)
[docs]
def ismultiobj(env, lp):
return CR.CPXEismultiobj(env, lp) != 0
# Optimizing Problems
# Accessing LP results
[docs]
def solninfo(env, lp):
lpstat = CR.intPtr()
stype = CR.intPtr()
pfeas = CR.intPtr()
dfeas = CR.intPtr()
status = CR.CPXXsolninfo(env, lp, lpstat, stype, pfeas, dfeas)
check_status(env, status)
return (lpstat.value(), stype.value(), pfeas.value(), dfeas.value())
[docs]
def getstat(env, lp):
return CR.CPXXgetstat(env, lp)
[docs]
def getmethod(env, lp):
return CR.CPXXgetmethod(env, lp)
[docs]
def getobjval(env, lp):
objval = CR.doublePtr()
status = CR.CPXXgetobjval(env, lp, objval)
check_status(env, status)
return objval.value()
[docs]
def getx(env, lp, begin, end):
xlen = _rangelen(begin, end)
x = _safeDoubleArray(xlen)
status = CR.CPXXgetx(env, lp, x, begin, end)
check_status(env, status)
return LAU.array_to_list(x, xlen)
[docs]
def getnumcores(env):
numcores = CR.intPtr()
status = CR.CPXXgetnumcores(env, numcores)
check_status(env, status)
return numcores.value()
[docs]
def getax(env, lp, begin, end):
axlen = _rangelen(begin, end)
ax = _safeDoubleArray(axlen)
status = CR.CPXXgetax(env, lp, ax, begin, end)
check_status(env, status)
return LAU.array_to_list(ax, axlen)
[docs]
def getxqxax(env, lp, begin, end):
qaxlen = _rangelen(begin, end)
qax = _safeDoubleArray(qaxlen)
status = CR.CPXXgetxqxax(env, lp, qax, begin, end)
check_status(env, status)
return LAU.array_to_list(qax, qaxlen)
[docs]
def getpi(env, lp, begin, end):
pilen = _rangelen(begin, end)
pi = _safeDoubleArray(pilen)
status = CR.CPXXgetpi(env, lp, pi, begin, end)
check_status(env, status)
return LAU.array_to_list(pi, pilen)
[docs]
def getslack(env, lp, begin, end):
slacklen = _rangelen(begin, end)
slack = _safeDoubleArray(slacklen)
status = CR.CPXXgetslack(env, lp, slack, begin, end)
check_status(env, status)
return LAU.array_to_list(slack, slacklen)
[docs]
def getdj(env, lp, begin, end):
djlen = _rangelen(begin, end)
dj = _safeDoubleArray(djlen)
status = CR.CPXXgetdj(env, lp, dj, begin, end)
check_status(env, status)
return LAU.array_to_list(dj, djlen)
[docs]
def getqconstrdslack(env, lp, qind):
inout_list = [0, qind]
status = CR.CPXXgetqconstrdslack(env, lp, inout_list)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
if inout_list == [0]:
return ([], [])
inout_list.extend([qind])
status = CR.CPXXgetqconstrdslack(env, lp, inout_list)
check_status(env, status)
return tuple(inout_list)
# Infeasibility
[docs]
def getrowinfeas(env, lp, x, begin, end):
infeasoutlen = _rangelen(begin, end)
infeasout = _safeDoubleArray(infeasoutlen)
status = CR.CPXXgetrowinfeas(env, lp, LAU.double_list_to_array(x),
infeasout, begin, end)
check_status(env, status)
return LAU.array_to_list(infeasout, infeasoutlen)
[docs]
def getcolinfeas(env, lp, x, begin, end):
infeasoutlen = _rangelen(begin, end)
infeasout = _safeDoubleArray(infeasoutlen)
status = CR.CPXXgetcolinfeas(env, lp, LAU.double_list_to_array(x),
infeasout, begin, end)
check_status(env, status)
return LAU.array_to_list(infeasout, infeasoutlen)
[docs]
def getqconstrinfeas(env, lp, x, begin, end):
infeasoutlen = _rangelen(begin, end)
infeasout = _safeDoubleArray(infeasoutlen)
status = CR.CPXXgetqconstrinfeas(env, lp, LAU.double_list_to_array(x),
infeasout, begin, end)
check_status(env, status)
return LAU.array_to_list(infeasout, infeasoutlen)
[docs]
def getindconstrinfeas(env, lp, x, begin, end):
infeasoutlen = _rangelen(begin, end)
infeasout = _safeDoubleArray(infeasoutlen)
status = CR.CPXXgetindconstrinfeas(env, lp, LAU.double_list_to_array(x),
infeasout, begin, end)
check_status(env, status)
return LAU.array_to_list(infeasout, infeasoutlen)
[docs]
def getsosinfeas(env, lp, x, begin, end):
infeasoutlen = _rangelen(begin, end)
infeasout = _safeDoubleArray(infeasoutlen)
status = CR.CPXXgetsosinfeas(env, lp, LAU.double_list_to_array(x),
infeasout, begin, end)
check_status(env, status)
return LAU.array_to_list(infeasout, infeasoutlen)
# Basis
[docs]
def getbase(env, lp):
numcols = CR.CPXXgetnumcols(env, lp)
numrows = CR.CPXXgetnumrows(env, lp)
cstat = _safeIntArray(numcols)
rstat = _safeIntArray(numrows)
status = CR.CPXXgetbase(env, lp, cstat, rstat)
check_status(env, status)
return (LAU.array_to_list(cstat, numcols),
LAU.array_to_list(rstat, numrows))
[docs]
def getbhead(env, lp):
headlen = CR.CPXXgetnumrows(env, lp)
head = _safeIntArray(headlen)
x = _safeDoubleArray(headlen)
status = CR.CPXXgetbhead(env, lp, head, x)
check_status(env, status)
return (LAU.array_to_list(head, headlen),
LAU.array_to_list(x, headlen))
[docs]
def mbasewrite(env, lp, filename):
status = CR.CPXXmbasewrite(env, lp, filename)
check_status(env, status)
[docs]
def getijrow(env, lp, idx, is_row_index):
row = CR.intPtr()
if is_row_index:
i, j = (idx, -1) # Seek a basic row.
else:
i, j = (-1, idx) # Seek a basic column.
status = CR.CPXXgetijrow(env, lp, i, j, row)
if status == CR.CPXERR_INDEX_NOT_BASIC:
return -1
check_status(env, status)
return row.value()
[docs]
def getpnorms(env, lp):
numcols = CR.CPXXgetnumcols(env, lp)
numrows = CR.CPXXgetnumrows(env, lp)
cnorm = _safeDoubleArray(numcols)
rnorm = _safeDoubleArray(numrows)
length = CR.intPtr()
status = CR.CPXXgetpnorms(env, lp, cnorm, rnorm, length)
check_status(env, status)
return (LAU.array_to_list(cnorm, length.value()),
LAU.array_to_list(rnorm, numrows))
[docs]
def getdnorms(env, lp):
numrows = CR.CPXXgetnumrows(env, lp)
norm = _safeDoubleArray(numrows)
head = _safeIntArray(numrows)
length = CR.intPtr()
status = CR.CPXXgetdnorms(env, lp, norm, head, length)
check_status(env, status)
return (LAU.array_to_list(norm, length.value()),
LAU.array_to_list(head, length.value()))
[docs]
def getbasednorms(env, lp):
numcols = CR.CPXXgetnumcols(env, lp)
numrows = CR.CPXXgetnumrows(env, lp)
cstat = _safeIntArray(numcols)
rstat = _safeIntArray(numrows)
dnorm = _safeDoubleArray(numrows)
status = CR.CPXXgetbasednorms(env, lp, cstat, rstat, dnorm)
check_status(env, status)
return (LAU.array_to_list(cstat, numcols),
LAU.array_to_list(rstat, numrows),
LAU.array_to_list(dnorm, numrows))
[docs]
def getpsbcnt(env, lp):
return CR.CPXXgetpsbcnt(env, lp)
[docs]
def getdsbcnt(env, lp):
return CR.CPXXgetdsbcnt(env, lp)
[docs]
def getdblquality(env, lp, what):
quality = CR.doublePtr()
status = CR.CPXXgetdblquality(env, lp, quality, what)
check_status(env, status)
return quality.value()
[docs]
def getintquality(env, lp, what):
quality = CR.intPtr()
status = CR.CPXXgetintquality(env, lp, quality, what)
check_status(env, status)
return quality.value()
# Sensitivity Analysis Results
[docs]
def boundsa_lower(env, lp, begin, end):
listlen = _rangelen(begin, end)
lblower = _safeDoubleArray(listlen)
lbupper = _safeDoubleArray(listlen)
ublower = LAU.double_list_to_array([])
ubupper = LAU.double_list_to_array([])
status = CR.CPXXboundsa(env, lp, begin, end, lblower, lbupper,
ublower, ubupper)
check_status(env, status)
return (LAU.array_to_list(lblower, listlen),
LAU.array_to_list(lbupper, listlen))
[docs]
def boundsa_upper(env, lp, begin, end):
listlen = _rangelen(begin, end)
lblower = LAU.double_list_to_array([])
lbupper = LAU.double_list_to_array([])
ublower = _safeDoubleArray(listlen)
ubupper = _safeDoubleArray(listlen)
status = CR.CPXXboundsa(env, lp, begin, end, lblower, lbupper,
ublower, ubupper)
check_status(env, status)
return (LAU.array_to_list(ublower, listlen),
LAU.array_to_list(ubupper, listlen))
[docs]
def boundsa(env, lp, begin, end):
listlen = _rangelen(begin, end)
lblower = _safeDoubleArray(listlen)
lbupper = _safeDoubleArray(listlen)
ublower = _safeDoubleArray(listlen)
ubupper = _safeDoubleArray(listlen)
status = CR.CPXXboundsa(env, lp, begin, end, lblower, lbupper,
ublower, ubupper)
check_status(env, status)
return (LAU.array_to_list(lblower, listlen),
LAU.array_to_list(lbupper, listlen),
LAU.array_to_list(ublower, listlen),
LAU.array_to_list(ubupper, listlen))
[docs]
def objsa(env, lp, begin, end):
listlen = _rangelen(begin, end)
lower = _safeDoubleArray(listlen)
upper = _safeDoubleArray(listlen)
status = CR.CPXXobjsa(env, lp, begin, end, lower, upper)
check_status(env, status)
return (LAU.array_to_list(lower, listlen),
LAU.array_to_list(upper, listlen))
[docs]
def rhssa(env, lp, begin, end):
listlen = _rangelen(begin, end)
lower = _safeDoubleArray(listlen)
upper = _safeDoubleArray(listlen)
status = CR.CPXXrhssa(env, lp, begin, end, lower, upper)
check_status(env, status)
return (LAU.array_to_list(lower, listlen),
LAU.array_to_list(upper, listlen))
# Conflicts
[docs]
def refinemipstartconflictext(env, lp, mipstartindex, grppref, grpbeg,
grpind, grptype):
grpcnt = _arraylen(grppref)
concnt = _arraylen(grpind)
with SigIntHandler(), \
LAU.double_c_array_or_none(grppref) as c_grppref, \
LAU.long_c_array_or_none(grpbeg) as c_grpbeg, \
LAU.int_c_array_or_none(grpind) as c_grpind:
status = CR.CPXXrefinemipstartconflictext(
env, lp, mipstartindex, grpcnt, concnt,
c_grppref, c_grpbeg, c_grpind, grptype)
check_status(env, status)
[docs]
def refineconflictext(env, lp, grppref, grpbeg, grpind, grptype):
grpcnt = _arraylen(grppref)
concnt = _arraylen(grpind)
with SigIntHandler(), \
LAU.double_c_array_or_none(grppref) as c_grppref, \
LAU.long_c_array_or_none(grpbeg) as c_grpbeg, \
LAU.int_c_array_or_none(grpind) as c_grpind:
status = CR.CPXXrefineconflictext(
env, lp, grpcnt, concnt,
c_grppref, c_grpbeg, c_grpind, grptype)
check_status(env, status)
[docs]
def getconflictext(env, lp, begin, end):
grpstatlen = _rangelen(begin, end)
grpstat = _safeIntArray(grpstatlen)
status = CR.CPXXgetconflictext(env, lp, grpstat, begin, end)
check_status(env, status)
return LAU.array_to_list(grpstat, grpstatlen)
[docs]
def getconflictnumgroups(env, lp):
return CR.CPXXgetconflictnumgroups(env, lp)
[docs]
def getconflictgroups(env, lp, begin, end):
inout_list = [0, begin, end]
status = CR.CPXXgetconflictgroups(env, lp, inout_list)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
if inout_list == [0]:
return ([], [0] * _rangelen(begin, end), [], [])
inout_list.extend([begin, end])
status = CR.CPXXgetconflictgroups(env, lp, inout_list)
check_status(env, status)
# We expect to get [grppref, grpbeg, grpind, grptype].
assert len(inout_list) == 4, str(inout_list)
return tuple(inout_list)
[docs]
def getconflictnumpasses(env, lp):
return CR.CPXXgetconflictnumpasses(env, lp)
[docs]
def clpwrite(env, lp, filename):
status = CR.CPXXclpwrite(env, lp, filename)
check_status(env, status)
# Problem Modification Routines
# File Reading Routines
# File Writing Routines
[docs]
def solwrite(env, lp, filename):
status = CR.CPXXsolwrite(env, lp, filename)
check_status(env, status)
# Message Handling Routines
# Advanced LP Routines
[docs]
def binvcol(env, lp, j):
xlen = CR.CPXXgetnumrows(env, lp)
x = _safeDoubleArray(xlen)
status = CR.CPXXbinvcol(env, lp, j, x)
check_status(env, status)
return LAU.array_to_list(x, xlen)
[docs]
def binvrow(env, lp, i):
ylen = CR.CPXXgetnumrows(env, lp)
y = _safeDoubleArray(ylen)
status = CR.CPXXbinvrow(env, lp, i, y)
check_status(env, status)
return LAU.array_to_list(y, ylen)
[docs]
def binvacol(env, lp, j):
xlen = CR.CPXXgetnumrows(env, lp)
x = _safeDoubleArray(xlen)
status = CR.CPXXbinvacol(env, lp, j, x)
check_status(env, status)
return LAU.array_to_list(x, xlen)
[docs]
def binvarow(env, lp, i):
zlen = CR.CPXXgetnumcols(env, lp)
z = _safeDoubleArray(zlen)
status = CR.CPXXbinvarow(env, lp, i, z)
check_status(env, status)
return LAU.array_to_list(z, zlen)
[docs]
def ftran(env, lp, x):
x_array = LAU.double_list_to_array(x)
status = CR.CPXXftran(env, lp, x_array)
check_status(env, status)
return LAU.array_to_list(x_array, len(x))
[docs]
def btran(env, lp, y):
y_array = LAU.double_list_to_array(y)
status = CR.CPXXbtran(env, lp, y_array)
check_status(env, status)
return LAU.array_to_list(y_array, len(y))
# Advanced Solution functions
[docs]
def getgrad(env, lp, j):
numrows = CR.CPXXgetnumrows(env, lp)
head = _safeIntArray(numrows)
y = _safeDoubleArray(numrows)
status = CR.CPXXgetgrad(env, lp, j, head, y)
check_status(env, status)
return (LAU.array_to_list(head, numrows),
LAU.array_to_list(y, numrows))
[docs]
def slackfromx(env, lp, x):
numrows = CR.CPXXgetnumrows(env, lp)
slack = _safeDoubleArray(numrows)
status = CR.CPXXslackfromx(env, lp, LAU.double_list_to_array(x), slack)
check_status(env, status)
return LAU.array_to_list(slack, numrows)
[docs]
def qconstrslackfromx(env, lp, x):
numqcon = CR.CPXXgetnumqconstrs(env, lp)
slack = _safeDoubleArray(numqcon)
status = CR.CPXXqconstrslackfromx(env, lp,
LAU.double_list_to_array(x), slack)
check_status(env, status)
return LAU.array_to_list(slack, numqcon)
[docs]
def djfrompi(env, lp, pi):
numcols = CR.CPXXgetnumcols(env, lp)
dj = _safeDoubleArray(numcols)
status = CR.CPXXdjfrompi(env, lp, LAU.double_list_to_array(pi), dj)
check_status(env, status)
return LAU.array_to_list(dj, numcols)
[docs]
def qpdjfrompi(env, lp, pi, x):
numcols = CR.CPXXgetnumcols(env, lp)
dj = _safeDoubleArray(numcols)
status = CR.CPXXqpdjfrompi(env, lp, LAU.double_list_to_array(pi),
LAU.double_list_to_array(x), dj)
check_status(env, status)
return LAU.array_to_list(dj, numcols)
[docs]
def mdleave(env, lp, goodlist):
goodlen = len(goodlist)
downratio = _safeDoubleArray(goodlen)
upratio = _safeDoubleArray(goodlen)
status = CR.CPXXmdleave(env, lp, LAU.int_list_to_array(goodlist),
goodlen, downratio, upratio)
check_status(env, status)
return (LAU.array_to_list(downratio, goodlen),
LAU.array_to_list(upratio, goodlen))
[docs]
def qpindefcertificate(env, lp):
certlen = CR.CPXXgetnumquad(env, lp)
cert = _safeDoubleArray(certlen)
status = CR.CPXXqpindefcertificate(env, lp, cert)
check_status(env, status)
return LAU.array_to_list(cert, certlen)
[docs]
def dualfarkas(env, lp):
ylen = CR.CPXXgetnumrows(env, lp)
y = _safeDoubleArray(ylen)
proof = CR.doublePtr()
status = CR.CPXXdualfarkas(env, lp, y, proof)
check_status(env, status)
return (LAU.array_to_list(y, ylen), proof.value())
[docs]
def getijdiv(env, lp):
idiv = CR.intPtr()
jdiv = CR.intPtr()
status = CR.CPXXgetijdiv(env, lp, idiv, jdiv)
check_status(env, status)
if idiv.value() != -1:
return idiv.value() + getnumcols(env, lp)
if jdiv.value() != -1:
return jdiv.value()
# problem is not diverging
return -1
[docs]
def getray(env, lp):
zlen = CR.CPXXgetnumcols(env, lp)
z = _safeDoubleArray(zlen)
status = CR.CPXXgetray(env, lp, z)
check_status(env, status)
return LAU.array_to_list(z, zlen)
# Advanced Presolve Routines
[docs]
def presolve(env, lp, method):
status = CR.CPXXpresolve(env, lp, method)
check_status(env, status)
[docs]
def freepresolve(env, lp):
status = CR.CPXXfreepresolve(env, lp)
check_status(env, status)
[docs]
def crushx(env, lp, x):
redlp = CR.CPXLPptrPtr()
status = CR.CPXXgetredlp(env, lp, redlp)
check_status(env, status)
if redlp.value() is None:
raise CplexError("No presolved problem found")
numcols = CR.CPXXgetnumcols(env, redlp.value())
prex = _safeDoubleArray(numcols)
status = CR.CPXXcrushx(env, lp, LAU.double_list_to_array(x), prex)
check_status(env, status)
return LAU.array_to_list(prex, numcols)
[docs]
def uncrushx(env, lp, prex):
numcols = CR.CPXXgetnumcols(env, lp)
x = _safeDoubleArray(numcols)
status = CR.CPXXuncrushx(env, lp, x, LAU.double_list_to_array(prex))
check_status(env, status)
return LAU.array_to_list(x, numcols)
[docs]
def crushpi(env, lp, pi):
redlp = CR.CPXLPptrPtr()
status = CR.CPXXgetredlp(env, lp, redlp)
check_status(env, status)
if redlp.value() is None:
raise CplexError("No presolved problem found")
numrows = CR.CPXXgetnumrows(env, redlp.value())
prepi = _safeDoubleArray(numrows)
status = CR.CPXXcrushpi(env, lp, LAU.double_list_to_array(pi), prepi)
check_status(env, status)
return LAU.array_to_list(prepi, numrows)
[docs]
def uncrushpi(env, lp, prepi):
numrows = CR.CPXXgetnumrows(env, lp)
pi = _safeDoubleArray(numrows)
status = CR.CPXXuncrushpi(env, lp, pi, LAU.double_list_to_array(prepi))
check_status(env, status)
return LAU.array_to_list(pi, numrows)
[docs]
def getprestat_status(env, lp):
redlp = CR.CPXLPptrPtr()
status = CR.CPXXgetredlp(env, lp, redlp)
check_status(env, status)
if redlp.value() is None:
raise CplexError("No presolved problem found")
prestat = CR.intPtr()
pcstat = LAU.int_list_to_array([])
prstat = LAU.int_list_to_array([])
ocstat = LAU.int_list_to_array([])
orstat = LAU.int_list_to_array([])
status = CR.CPXXgetprestat(env, lp, prestat, pcstat, prstat,
ocstat, orstat)
check_status(env, status)
return prestat.value()
[docs]
def getprestat_r(env, lp):
redlp = CR.CPXLPptrPtr()
status = CR.CPXXgetredlp(env, lp, redlp)
check_status(env, status)
if redlp.value() is None:
raise CplexError("No presolved problem found")
nrows = CR.CPXXgetnumrows(env, lp)
prestat = CR.intPtr()
pcstat = LAU.int_list_to_array([])
prstat = _safeIntArray(nrows)
ocstat = LAU.int_list_to_array([])
orstat = LAU.int_list_to_array([])
status = CR.CPXXgetprestat(env, lp, prestat, pcstat, prstat,
ocstat, orstat)
check_status(env, status)
return LAU.array_to_list(prstat, nrows)
[docs]
def getprestat_c(env, lp):
redlp = CR.CPXLPptrPtr()
status = CR.CPXXgetredlp(env, lp, redlp)
check_status(env, status)
if redlp.value() is None:
raise CplexError("No presolved problem found")
ncols = CR.CPXXgetnumcols(env, lp)
prestat = CR.intPtr()
pcstat = _safeIntArray(ncols)
prstat = LAU.int_list_to_array([])
ocstat = LAU.int_list_to_array([])
orstat = LAU.int_list_to_array([])
status = CR.CPXXgetprestat(env, lp, prestat, pcstat, prstat,
ocstat, orstat)
check_status(env, status)
return LAU.array_to_list(pcstat, ncols)
[docs]
def getprestat_or(env, lp):
redlp = CR.CPXLPptrPtr()
status = CR.CPXXgetredlp(env, lp, redlp)
check_status(env, status)
if redlp.value() is None:
raise CplexError("No presolved problem found")
nprows = CR.CPXXgetnumrows(env, redlp.value())
prestat = CR.intPtr()
pcstat = LAU.int_list_to_array([])
prstat = LAU.int_list_to_array([])
ocstat = LAU.int_list_to_array([])
orstat = _safeIntArray(nprows)
status = CR.CPXXgetprestat(env, lp, prestat, pcstat, prstat,
ocstat, orstat)
check_status(env, status)
return LAU.array_to_list(orstat, nprows)
[docs]
def getprestat_oc(env, lp):
redlp = CR.CPXLPptrPtr()
status = CR.CPXXgetredlp(env, lp, redlp)
check_status(env, status)
if redlp.value() is None:
raise CplexError("No presolved problem found")
npcols = CR.CPXXgetnumcols(env, redlp.value())
prestat = CR.intPtr()
pcstat = LAU.int_list_to_array([])
prstat = LAU.int_list_to_array([])
ocstat = _safeIntArray(npcols)
orstat = LAU.int_list_to_array([])
status = CR.CPXXgetprestat(env, lp, prestat, pcstat, prstat,
ocstat, orstat)
check_status(env, status)
return LAU.array_to_list(ocstat, npcols)
[docs]
def prechgobj(env, lp, ind, val):
status = CR.CPXXprechgobj(env, lp, len(ind),
LAU.int_list_to_array(ind),
LAU.double_list_to_array(val))
check_status(env, status)
[docs]
def preaddrows(env, lp, rhs, sense, rmatbeg, rmatind, rmatval, names):
with LAU.double_c_array(rhs) as c_rhs, \
LAU.long_c_array(rmatbeg) as c_rmatbeg, \
LAU.int_c_array(rmatind) as c_rmatind, \
LAU.double_c_array(rmatval) as c_rmatval: # noqa: E126
status = CR.CPXXpreaddrows(env, lp, len(rmatbeg), len(rmatind),
c_rhs,
sense,
c_rmatbeg,
c_rmatind,
c_rmatval,
names)
check_status(env, status)
########################################################################
# MIP Starts API
########################################################################
[docs]
def getnummipstarts(env, lp):
return CR.CPXXgetnummipstarts(env, lp)
[docs]
def chgmipstarts(env, lp, mipstartindices, beg, varindices, values,
effortlevel):
with LAU.int_c_array(mipstartindices) as c_mipstartindices, \
LAU.long_c_array(beg) as c_beg, \
LAU.int_c_array(varindices) as c_varindices, \
LAU.double_c_array(values) as c_values, \
LAU.int_c_array(effortlevel) as c_effortlevel:
status = CR.CPXXchgmipstarts(env, lp,
len(mipstartindices),
c_mipstartindices,
len(varindices),
c_beg,
c_varindices,
c_values,
c_effortlevel)
check_status(env, status)
[docs]
def addmipstarts(env, lp, beg, varindices, values, effortlevel,
mipstartname):
with LAU.long_c_array(beg) as c_beg, \
LAU.int_c_array(varindices) as c_varindices, \
LAU.double_c_array(values) as c_values, \
LAU.int_c_array(effortlevel) as c_effortlevel:
status = CR.CPXXaddmipstarts(
env, lp, len(beg), len(varindices),
c_beg, c_varindices, c_values, c_effortlevel,
mipstartname)
check_status(env, status)
[docs]
def delmipstarts(env, lp, begin, end):
delfn = CR.CPXXdelmipstarts
_delbyrange(delfn, env, lp, begin, end)
[docs]
def getmipstarts_size(env, lp, begin, end):
beglen = _rangelen(begin, end)
beg = LAU.long_list_to_array([])
effortlevel = _safeIntArray(beglen)
nzcnt = CR.cpxlongPtr()
surplus = CR.cpxlongPtr()
varindices = LAU.int_list_to_array([])
values = LAU.double_list_to_array([])
startspace = 0
status = CR.CPXXgetmipstarts(env, lp, nzcnt, beg, varindices, values,
effortlevel, startspace, surplus, begin,
end)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
return -surplus.value()
[docs]
def getmipstarts_effort(env, lp, begin, end):
beglen = _rangelen(begin, end)
beg = LAU.long_list_to_array([])
effortlevel = _safeIntArray(beglen)
nzcnt = CR.cpxlongPtr()
surplus = CR.cpxlongPtr()
varindices = LAU.int_list_to_array([])
values = LAU.double_list_to_array([])
startspace = 0
status = CR.CPXXgetmipstarts(env, lp, nzcnt, beg, varindices, values,
effortlevel, startspace, surplus, begin,
end)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
if surplus.value() == 0:
return ([0] * _rangelen(begin, end), [], [],
[0] * _rangelen(begin, end))
startspace = -surplus.value()
beg = _safeLongArray(beglen)
varindices = _safeIntArray(startspace)
values = _safeDoubleArray(startspace)
status = CR.CPXXgetmipstarts(env, lp, nzcnt, beg, varindices, values,
effortlevel, startspace, surplus, begin,
end)
check_status(env, status)
return LAU.array_to_list(effortlevel, beglen)
[docs]
def getmipstarts(env, lp, begin, end):
beglen = _rangelen(begin, end)
beg = LAU.long_list_to_array([])
effortlevel = _safeIntArray(beglen)
nzcnt = CR.cpxlongPtr()
surplus = CR.cpxlongPtr()
varindices = LAU.int_list_to_array([])
values = LAU.double_list_to_array([])
startspace = 0
status = CR.CPXXgetmipstarts(env, lp, nzcnt, beg, varindices, values,
effortlevel, startspace, surplus, begin,
end)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
if surplus.value() == 0:
return ([0] * _rangelen(begin, end), [], [],
[0] * _rangelen(begin, end))
beg = _safeLongArray(beglen)
startspace = -surplus.value()
varindices = _safeIntArray(startspace)
values = _safeDoubleArray(startspace)
status = CR.CPXXgetmipstarts(env, lp, nzcnt, beg, varindices, values,
effortlevel, startspace, surplus, begin,
end)
check_status(env, status)
return (LAU.array_to_list(beg, beglen),
LAU.array_to_list(varindices, startspace),
LAU.array_to_list(values, startspace),
LAU.array_to_list(effortlevel, beglen))
[docs]
def getmipstartname(env, lp, begin, end):
namefn = CR.CPXXgetmipstartname
return _getnamebyrange(env, lp, begin, end, namefn)
[docs]
def getmipstartindex(env, lp, mipstartname):
index = CR.intPtr()
status = CR.CPXXgetmipstartindex(env, lp, mipstartname, index)
check_status(env, status)
return index.value()
[docs]
def readcopymipstarts(env, lp, filename):
status = CR.CPXXreadcopymipstarts(env, lp,
filename)
check_status(env, status)
[docs]
def writemipstarts(env, lp, filename, begin, end):
status = CR.CPXXwritemipstarts(env, lp, filename, begin, end)
check_status(env, status)
# Optimizing Problems
# Progress
[docs]
def getitcnt(env, lp):
return CR.CPXXgetitcnt(env, lp)
[docs]
def getphase1cnt(env, lp):
return CR.CPXXgetphase1cnt(env, lp)
[docs]
def getsiftitcnt(env, lp):
return CR.CPXXgetsiftitcnt(env, lp)
[docs]
def getsiftphase1cnt(env, lp):
return CR.CPXXgetsiftphase1cnt(env, lp)
[docs]
def getbaritcnt(env, lp):
return CR.CPXXgetbaritcnt(env, lp)
[docs]
def getcrossppushcnt(env, lp):
return CR.CPXXgetcrossppushcnt(env, lp)
[docs]
def getcrosspexchcnt(env, lp):
return CR.CPXXgetcrosspexchcnt(env, lp)
[docs]
def getcrossdpushcnt(env, lp):
return CR.CPXXgetcrossdpushcnt(env, lp)
[docs]
def getcrossdexchcnt(env, lp):
return CR.CPXXgetcrossdexchcnt(env, lp)
[docs]
def getmipitcnt(env, lp):
return CR.CPXXgetmipitcnt(env, lp)
[docs]
def getnodecnt(env, lp):
return CR.CPXXgetnodecnt(env, lp)
[docs]
def getnodeleftcnt(env, lp):
return CR.CPXXgetnodeleftcnt(env, lp)
# MIP Only solution interface
[docs]
def getbestobjval(env, lp):
objval = CR.doublePtr()
status = CR.CPXXgetbestobjval(env, lp, objval)
check_status(env, status)
return objval.value()
[docs]
def getcutoff(env, lp):
cutoff = CR.doublePtr()
status = CR.CPXXgetcutoff(env, lp, cutoff)
check_status(env, status)
return cutoff.value()
[docs]
def getmiprelgap(env, lp):
relgap = CR.doublePtr()
status = CR.CPXXgetmiprelgap(env, lp, relgap)
check_status(env, status)
return relgap.value()
[docs]
def getnumcuts(env, lp, cuttype):
num = CR.intPtr()
status = CR.CPXXgetnumcuts(env, lp, cuttype, num)
check_status(env, status)
return num.value()
[docs]
def getnodeint(env, lp):
return CR.CPXXgetnodeint(env, lp)
[docs]
def getsubstat(env, lp):
return CR.CPXXgetsubstat(env, lp)
# for callback query methods
[docs]
def get_wherefrom(cbstruct):
return CR.get_wherefrom(cbstruct)
cpxlong_callback_node_info = [
_const.CPX_CALLBACK_INFO_NODE_SEQNUM_LONG,
_const.CPX_CALLBACK_INFO_NODE_NODENUM_LONG,
_const.CPX_CALLBACK_INFO_NODE_DEPTH_LONG,
]
int_callback_node_info = [
_const.CPX_CALLBACK_INFO_NODE_NIINF,
_const.CPX_CALLBACK_INFO_NODE_VAR,
_const.CPX_CALLBACK_INFO_NODE_SOS,
_const.CPX_CALLBACK_INFO_LAZY_SOURCE,
]
double_callback_node_info = [
_const.CPX_CALLBACK_INFO_NODE_SIINF,
_const.CPX_CALLBACK_INFO_NODE_ESTIMATE,
_const.CPX_CALLBACK_INFO_NODE_OBJVAL,
]
# NB: CPX_CALLBACK_INFO_NODE_TYPE not used in the Python API.
user_handle_callback_node_info = [
_const.CPX_CALLBACK_INFO_NODE_USERHANDLE
]
[docs]
def gettime(env):
time = CR.doublePtr()
status = CR.CPXXgettime(env, time)
check_status(env, status)
return time.value()
[docs]
def getdettime(env):
time = CR.doublePtr()
status = CR.CPXXgetdettime(env, time)
check_status(env, status)
return time.value()
[docs]
def getcallbackincumbent(cbstruct, begin, end):
xlen = _rangelen(begin, end)
x = _safeDoubleArray(xlen)
status = CR.CPXXgetcallbackincumbent(cbstruct, x, begin, end)
check_status(None, status)
return LAU.array_to_list(x, xlen)
[docs]
def getcallbackpseudocosts(cbstruct, begin, end):
pclen = _rangelen(begin, end)
uppc = _safeDoubleArray(pclen)
dnpc = _safeDoubleArray(pclen)
status = CR.CPXXgetcallbackpseudocosts(cbstruct, uppc, dnpc, begin, end)
check_status(None, status)
return (LAU.array_to_list(uppc, pclen),
LAU.array_to_list(dnpc, pclen))
[docs]
def getcallbacknodeintfeas(cbstruct, begin, end):
feaslen = _rangelen(begin, end)
feas = _safeIntArray(feaslen)
status = CR.CPXXgetcallbacknodeintfeas(cbstruct, feas, begin, end)
check_status(None, status)
return LAU.array_to_list(feas, feaslen)
[docs]
def getcallbacknodelb(cbstruct, begin, end):
lblen = _rangelen(begin, end)
lb = _safeDoubleArray(lblen)
status = CR.CPXXgetcallbacknodelb(cbstruct, lb, begin, end)
check_status(None, status)
return LAU.array_to_list(lb, lblen)
[docs]
def getcallbacknodeub(cbstruct, begin, end):
ublen = _rangelen(begin, end)
ub = _safeDoubleArray(ublen)
status = CR.CPXXgetcallbacknodeub(cbstruct, ub, begin, end)
check_status(None, status)
return LAU.array_to_list(ub, ublen)
[docs]
def getcallbacknodeobjval(cbstruct):
x = CR.doublePtr()
status = CR.CPXXgetcallbacknodeobjval(cbstruct, x)
check_status(None, status)
return x.value()
[docs]
def getcallbacknodex(cbstruct, begin, end):
xlen = _rangelen(begin, end)
x = _safeDoubleArray(xlen)
status = CR.CPXXgetcallbacknodex(cbstruct, x, begin, end)
check_status(None, status)
return LAU.array_to_list(x, xlen)
[docs]
def getcallbacknodeinfo(cbstruct, node, which):
if which in int_callback_node_info:
data = CR.intPtr()
elif which in cpxlong_callback_node_info:
data = CR.cpxlongPtr()
elif which in double_callback_node_info:
data = CR.doublePtr()
elif which in user_handle_callback_node_info:
data = []
else:
raise CplexError(
"invalid value for which in _internal._procedural.getcallbacknodeinfo")
status = CR.CPXXgetcallbacknodeinfo(cbstruct, [node, which, data])
check_status(None, status)
if (which in int_callback_node_info or
which in double_callback_node_info or
which in cpxlong_callback_node_info):
return data.value()
assert which in user_handle_callback_node_info
return data[0]
[docs]
def callbacksetuserhandle(cbstruct, userhandle):
data = []
status = CR.CPXXcallbacksetuserhandle(cbstruct, [userhandle, data])
check_status(None, status)
return data[0]
[docs]
def callbacksetnodeuserhandle(cbstruct, nodeindex, userhandle):
data = []
status = CR.CPXXcallbacksetnodeuserhandle(
cbstruct, [nodeindex, userhandle, data])
check_status(None, status)
return data[0]
[docs]
def getcallbackseqinfo(cbstruct, node, which):
if which in int_callback_node_info:
data = CR.intPtr()
elif which in cpxlong_callback_node_info:
data = CR.cpxlongPtr()
elif which in double_callback_node_info:
data = CR.doublePtr()
elif which in user_handle_callback_node_info:
data = []
else:
raise CplexError(
"invalid value for which in _internal._procedural.getcallbackseqinfo")
status = CR.CPXXgetcallbackseqinfo(cbstruct, [node, which, data])
check_status(None, status)
if (which in int_callback_node_info or
which in double_callback_node_info or
which in cpxlong_callback_node_info):
return data.value()
assert which in user_handle_callback_node_info
return data[0]
int_sos_info = [
_const.CPX_CALLBACK_INFO_SOS_NUM,
_const.CPX_CALLBACK_INFO_SOS_SIZE,
_const.CPX_CALLBACK_INFO_SOS_IS_FEASIBLE,
_const.CPX_CALLBACK_INFO_SOS_MEMBER_INDEX,
]
double_sos_info = [
_const.CPX_CALLBACK_INFO_SOS_MEMBER_REFVAL,
]
# NB: CPX_CALLBACK_INFO_SOS_TYPE not used in the Python API.
[docs]
def getcallbacksosinfo(cbstruct, sosindex, member, which):
if which in int_sos_info:
data = CR.intPtr()
elif which in double_sos_info:
data = CR.doublePtr()
else:
raise CplexError(
"invalid value for which in _internal._procedural.getcallbacksosinfo")
status = CR.CPXXgetcallbacksosinfo(cbstruct, sosindex, member, which, data)
check_status(None, status)
return data.value()
[docs]
def cutcallbackadd(cbstruct, rhs, sense, ind, val, purgeable):
status = CR.CPXXcutcallbackadd(cbstruct, len(ind), rhs,
sense,
LAU.int_list_to_array(ind),
LAU.double_list_to_array(val),
purgeable)
check_status(None, status)
[docs]
def cutcallbackaddlocal(cbstruct, rhs, sense, ind, val):
status = CR.CPXXcutcallbackaddlocal(cbstruct, len(ind), rhs,
sense,
LAU.int_list_to_array(ind),
LAU.double_list_to_array(val))
check_status(None, status)
[docs]
def branchcallbackbranchgeneral(cbstruct, ind, lu, bd, rhs, sense, matbeg,
matind, matval, nodeest, userhandle):
seqnum = CR.cpxlongPtr()
status = CR.CPXXbranchcallbackbranchgeneral(
cbstruct, len(ind),
LAU.int_list_to_array(ind),
lu,
LAU.double_list_to_array(bd),
len(matbeg), len(matind),
LAU.double_list_to_array(rhs),
sense,
LAU.long_list_to_array(matbeg),
LAU.int_list_to_array(matind),
LAU.double_list_to_array(matval),
nodeest, userhandle, seqnum)
check_status(None, status)
return seqnum.value()
[docs]
def branchcallbackbranchasCPLEX(cbstruct, n, userhandle):
seqnum = CR.cpxlongPtr()
status = CR.CPXXbranchcallbackbranchasCPLEX(
cbstruct, n, userhandle, seqnum)
check_status(None, status)
return seqnum.value()
[docs]
def setpydel(env):
status = CR.setpydel(env)
check_status(env, status)
[docs]
def delpydel(env):
status = CR.delpydel(env)
check_status(env, status)
# Solution pool
[docs]
def addsolnpooldivfilter(env, lp, lb, ub, ind, wts, ref, name):
status = CR.CPXXaddsolnpooldivfilter(env, lp, lb, ub, len(ind),
LAU.int_list_to_array(ind),
LAU.double_list_to_array(wts),
LAU.double_list_to_array(ref),
name)
check_status(env, status)
[docs]
def addsolnpoolrngfilter(env, lp, lb, ub, ind, val, name):
status = CR.CPXXaddsolnpoolrngfilter(env, lp, lb, ub, len(ind),
LAU.int_list_to_array(ind),
LAU.double_list_to_array(val),
name)
check_status(env, status)
[docs]
def getsolnpooldivfilter_constant(env, lp, which):
lb = CR.doublePtr()
ub = CR.doublePtr()
nzcnt = CR.intPtr()
space = 0
surplus = CR.intPtr()
ind = LAU.int_list_to_array([])
wts = LAU.double_list_to_array([])
ref = LAU.double_list_to_array([])
status = CR.CPXXgetsolnpooldivfilter(env, lp, lb, ub, nzcnt, ind,
wts, ref, space, surplus, which)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
return (lb.value(), ub.value(), -surplus.value())
[docs]
def getsolnpooldivfilter(env, lp, which):
lb = CR.doublePtr()
ub = CR.doublePtr()
nzcnt = CR.intPtr()
space = 0
surplus = CR.intPtr()
ind = LAU.int_list_to_array([])
wts = LAU.double_list_to_array([])
ref = LAU.double_list_to_array([])
status = CR.CPXXgetsolnpooldivfilter(env, lp, lb, ub, nzcnt, ind,
wts, ref, space, surplus, which)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
space = -surplus.value()
ind = _safeIntArray(space)
wts = _safeDoubleArray(space)
ref = _safeDoubleArray(space)
status = CR.CPXXgetsolnpooldivfilter(env, lp, lb, ub, nzcnt, ind,
wts, ref, space, surplus, which)
check_status(env, status)
return (lb.value(),
ub.value(),
LAU.array_to_list(ind, space),
LAU.array_to_list(wts, space),
LAU.array_to_list(ref, space))
[docs]
def getsolnpoolrngfilter_constant(env, lp, which):
lb = CR.doublePtr()
ub = CR.doublePtr()
nzcnt = CR.intPtr()
space = 0
surplus = CR.intPtr()
ind = LAU.int_list_to_array([])
val = LAU.double_list_to_array([])
status = CR.CPXXgetsolnpoolrngfilter(env, lp, lb, ub, nzcnt, ind, val,
space, surplus, which)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
return (lb.value(), ub.value(), -surplus.value())
[docs]
def getsolnpoolrngfilter(env, lp, which):
lb = CR.doublePtr()
ub = CR.doublePtr()
nzcnt = CR.intPtr()
space = 0
surplus = CR.intPtr()
ind = LAU.int_list_to_array([])
val = LAU.double_list_to_array([])
status = CR.CPXXgetsolnpoolrngfilter(env, lp, lb, ub, nzcnt, ind, val,
space, surplus, which)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
space = -surplus.value()
ind = _safeIntArray(space)
val = _safeDoubleArray(space)
status = CR.CPXXgetsolnpoolrngfilter(env, lp, lb, ub, nzcnt, ind, val,
space, surplus, which)
check_status(env, status)
return (lb.value(), ub.value(), LAU.array_to_list(ind, space),
LAU.array_to_list(val, space))
[docs]
def delsolnpoolfilters(env, lp, begin, end):
delfn = CR.CPXXdelsolnpoolfilters
_delbyrange(delfn, env, lp, begin, end)
[docs]
def getsolnpoolfiltername(env, lp, which):
namefn = CR.CPXXgetsolnpoolfiltername
return _getname(env, lp, which, namefn, index_first=False)
[docs]
def getsolnpoolnumfilters(env, lp):
return CR.CPXXgetsolnpoolnumfilters(env, lp)
[docs]
def fltwrite(env, lp, filename):
status = CR.CPXXfltwrite(env, lp, filename)
check_status(env, status)
[docs]
def readcopysolnpoolfilters(env, lp, filename):
status = CR.CPXXreadcopysolnpoolfilters(env, lp,
filename)
check_status(env, status)
[docs]
def getsolnpoolfilterindex(env, lp, colname):
index = CR.intPtr()
status = CR.CPXXgetsolnpoolfilterindex(env, lp, colname, index)
check_status(env, status)
return index.value()
[docs]
def getsolnpoolfiltertype(env, lp, index):
type_ = CR.intPtr()
status = CR.CPXXgetsolnpoolfiltertype(env, lp, type_, index)
check_status(env, status)
return type_.value()
[docs]
def delsolnpoolsolns(env, lp, begin, end):
delfn = CR.CPXXdelsolnpoolsolns
_delbyrange(delfn, env, lp, begin, end)
[docs]
def getsolnpoolnumsolns(env, lp):
return CR.CPXXgetsolnpoolnumsolns(env, lp)
[docs]
def getsolnpoolnumreplaced(env, lp):
return CR.CPXXgetsolnpoolnumreplaced(env, lp)
[docs]
def getsolnpoolsolnindex(env, lp, colname):
index = CR.intPtr()
status = CR.CPXXgetsolnpoolsolnindex(env, lp, colname, index)
check_status(env, status)
return index.value()
[docs]
def getsolnpoolmeanobjval(env, lp):
objval = CR.doublePtr()
status = CR.CPXXgetsolnpoolmeanobjval(env, lp, objval)
check_status(env, status)
return objval.value()
[docs]
def getsolnpoolsolnname(env, lp, which):
namefn = CR.CPXXgetsolnpoolsolnname
return _getname(env, lp, which, namefn, index_first=False)
[docs]
def solwritesolnpool(env, lp, soln, filename):
status = CR.CPXXsolwritesolnpool(env, lp, soln, filename)
check_status(env, status)
[docs]
def solwritesolnpoolall(env, lp, filename):
status = CR.CPXXsolwritesolnpoolall(env, lp, filename)
check_status(env, status)
[docs]
def getsolnpoolobjval(env, lp, soln):
obj = CR.doublePtr()
status = CR.CPXXgetsolnpoolobjval(env, lp, soln, obj)
check_status(env, status)
return obj.value()
[docs]
def getsolnpoolx(env, lp, soln, begin, end):
xlen = _rangelen(begin, end)
x = _safeDoubleArray(xlen)
status = CR.CPXXgetsolnpoolx(env, lp, soln, x, begin, end)
check_status(env, status)
return LAU.array_to_list(x, xlen)
[docs]
def getsolnpoolslack(env, lp, soln, begin, end):
slacklen = _rangelen(begin, end)
slack = _safeDoubleArray(slacklen)
status = CR.CPXXgetsolnpoolslack(env, lp, soln, slack, begin, end)
check_status(env, status)
return LAU.array_to_list(slack, slacklen)
[docs]
def getsolnpoolqconstrslack(env, lp, soln, begin, end):
qlen = _rangelen(begin, end)
q = _safeDoubleArray(qlen)
status = CR.CPXXgetsolnpoolqconstrslack(env, lp, soln, q, begin, end)
check_status(env, status)
return LAU.array_to_list(q, qlen)
[docs]
def getsolnpoolintquality(env, lp, soln, what):
quality = CR.intPtr()
status = CR.CPXXgetsolnpoolintquality(env, lp, soln, quality, what)
check_status(env, status)
return quality.value()
[docs]
def getsolnpooldblquality(env, lp, soln, what):
quality = CR.doublePtr()
status = CR.CPXXgetsolnpooldblquality(env, lp, soln, quality, what)
check_status(env, status)
return quality.value()
# Initial data
[docs]
def copystart(env, lp, cstat, rstat, cprim, rprim, cdual, rdual):
status = CR.CPXXcopystart(env, lp,
LAU.int_list_to_array(cstat),
LAU.int_list_to_array(rstat),
LAU.double_list_to_array(cprim),
LAU.double_list_to_array(rprim),
LAU.double_list_to_array(cdual),
LAU.double_list_to_array(rdual))
check_status(env, status)
[docs]
def readcopybase(env, lp, filename):
status = CR.CPXXreadcopybase(env, lp, filename)
check_status(env, status)
[docs]
def getorder(env, lp):
count = CR.intPtr()
surplus = CR.intPtr()
space = 0
ind = LAU.int_list_to_array([])
pri = LAU.int_list_to_array([])
dir_ = LAU.int_list_to_array([])
status = CR.CPXXgetorder(env, lp, count, ind, pri, dir_, space, surplus)
if status != CR.CPXERR_NEGATIVE_SURPLUS:
check_status(env, status)
space = -surplus.value()
ind = _safeIntArray(space)
pri = _safeIntArray(space)
dir_ = _safeIntArray(space)
status = CR.CPXXgetorder(env, lp, count, ind, pri, dir_, space, surplus)
check_status(env, status)
return (LAU.array_to_list(ind, space), LAU.array_to_list(pri, space),
LAU.array_to_list(dir_, space))
[docs]
def copyorder(env, lp, indices, priority, direction):
status = CR.CPXXcopyorder(env, lp, len(indices),
LAU.int_list_to_array(indices),
LAU.int_list_to_array(priority),
LAU.int_list_to_array(direction))
check_status(env, status)
[docs]
def readcopyorder(env, lp, filename):
status = CR.CPXXreadcopyorder(env, lp, filename)
check_status(env, status)
[docs]
def ordwrite(env, lp, filename):
status = CR.CPXXordwrite(env, lp, filename)
check_status(env, status)
[docs]
def readcopystartinfo(env, lp, filename):
status = CR.CPXXreadcopystartinfo(env, lp, filename)
check_status(env, status)
# handle the lock for parallel callbacks
[docs]
def initlock():
return CR.init_callback_lock()
[docs]
def finitlock(lock):
CR.finit_callback_lock(lock)
# get problem statistics
[docs]
def getprobstats(env, lp):
ProbStats = namedtuple(
'ProbStats',
['objs', # 0
'rows', # 1
'cols', # 2
'objcnt', # 3
'rhscnt', # 4
'nzcnt', # 5
'ecnt', # 6
'gcnt', # 7
'lcnt', # 8
'rngcnt', # 9
'ncnt', # 10
'fcnt', # 11
'xcnt', # 12
'bcnt', # 13
'ocnt', # 14
'bicnt', # 15
'icnt', # 16
'scnt', # 17
'sicnt', # 18
'qpcnt', # 19
'qpnzcnt', # 20
'nqconstr', # 21
'qrhscnt', # 22
'qlcnt', # 23
'qgcnt', # 24
'quadnzcnt', # 25
'linnzcnt', # 26
'nindconstr', # 27
'indrhscnt', # 28
'indnzcnt', # 29
'indcompcnt', # 30
'indlcnt', # 31
'indecnt', # 32
'indgcnt', # 33
'maxcoef', # 34
'mincoef', # 35
'minrhs', # 36
'maxrhs', # 37
'minrng', # 38
'maxrng', # 39
'minobj', # 40
'maxobj', # 41
'minlb', # 42
'maxub', # 43
'minqcoef', # 44
'maxqcoef', # 45
'minqcq', # 46
'maxqcq', # 47
'minqcl', # 48
'maxqcl', # 49
'minqcr', # 50
'maxqcr', # 51
'minind', # 52
'maxind', # 53
'minindrhs', # 54
'maxindrhs', # 55
'minlazy', # 56
'maxlazy', # 57
'minlazyrhs', # 58
'maxlazyrhs', # 59
'minucut', # 60
'maxucut', # 61
'minucutrhs', # 62
'maxucutrhs', # 63
'nsos', # 64
'nsos1', # 65
'sos1nmem', # 66
'sos1type', # 67
'nsos2', # 68
'sos2nmem', # 69
'sos2type', # 70
'lazyrhscnt', # 71
'lazygcnt', # 72
'lazylcnt', # 73
'lazyecnt', # 74
'lazycnt', # 75
'lazynzcnt', # 76
'ucutrhscnt', # 77
'ucutgcnt', # 78
'ucutlcnt', # 79
'ucutecnt', # 80
'ucutcnt', # 81
'ucutnzcnt', # 82
'npwl', # 83
'npwlbreaks']) # 84
objs_p = CR.intPtr()
rows_p = CR.intPtr()
cols_p = CR.intPtr()
objcnt_p = CR.intPtr()
rhscnt_p = CR.intPtr()
nzcnt_p = CR.intPtr()
ecnt_p = CR.intPtr()
gcnt_p = CR.intPtr()
lcnt_p = CR.intPtr()
rngcnt_p = CR.intPtr()
ncnt_p = CR.intPtr()
fcnt_p = CR.intPtr()
xcnt_p = CR.intPtr()
bcnt_p = CR.intPtr()
ocnt_p = CR.intPtr()
bicnt_p = CR.intPtr()
icnt_p = CR.intPtr()
scnt_p = CR.intPtr()
sicnt_p = CR.intPtr()
qpcnt_p = CR.intPtr()
qpnzcnt_p = CR.intPtr()
nqconstr_p = CR.intPtr()
qrhscnt_p = CR.intPtr()
qlcnt_p = CR.intPtr()
qgcnt_p = CR.intPtr()
quadnzcnt_p = CR.intPtr()
linnzcnt_p = CR.intPtr()
nindconstr_p = CR.intPtr()
indrhscnt_p = CR.intPtr()
indnzcnt_p = CR.intPtr()
indcompcnt_p = CR.intPtr()
indlcnt_p = CR.intPtr()
indecnt_p = CR.intPtr()
indgcnt_p = CR.intPtr()
maxcoef_p = CR.doublePtr()
mincoef_p = CR.doublePtr()
minrhs_p = CR.doublePtr()
maxrhs_p = CR.doublePtr()
minrng_p = CR.doublePtr()
maxrng_p = CR.doublePtr()
minobj_p = CR.doublePtr()
maxobj_p = CR.doublePtr()
minlb_p = CR.doublePtr()
maxub_p = CR.doublePtr()
minqcoef_p = CR.doublePtr()
maxqcoef_p = CR.doublePtr()
minqcq_p = CR.doublePtr()
maxqcq_p = CR.doublePtr()
minqcl_p = CR.doublePtr()
maxqcl_p = CR.doublePtr()
minqcr_p = CR.doublePtr()
maxqcr_p = CR.doublePtr()
minind_p = CR.doublePtr()
maxind_p = CR.doublePtr()
minindrhs_p = CR.doublePtr()
maxindrhs_p = CR.doublePtr()
minlazy_p = CR.doublePtr()
maxlazy_p = CR.doublePtr()
minlazyrhs_p = CR.doublePtr()
maxlazyrhs_p = CR.doublePtr()
minucut_p = CR.doublePtr()
maxucut_p = CR.doublePtr()
minucutrhs_p = CR.doublePtr()
maxucutrhs_p = CR.doublePtr()
nsos_p = CR.intPtr()
nsos1_p = CR.intPtr()
sos1nmem_p = CR.intPtr()
sos1type_p = CR.intPtr()
nsos2_p = CR.intPtr()
sos2nmem_p = CR.intPtr()
sos2type_p = CR.intPtr()
lazyrhscnt_p = CR.intPtr()
lazygcnt_p = CR.intPtr()
lazylcnt_p = CR.intPtr()
lazyecnt_p = CR.intPtr()
lazycnt_p = CR.intPtr()
lazynzcnt_p = CR.intPtr()
ucutrhscnt_p = CR.intPtr()
ucutgcnt_p = CR.intPtr()
ucutlcnt_p = CR.intPtr()
ucutecnt_p = CR.intPtr()
ucutcnt_p = CR.intPtr()
ucutnzcnt_p = CR.intPtr()
npwl_p = CR.intPtr()
npwlbreaks_p = CR.intPtr()
status = CR.CPXEgetprobstats(env, lp,
objs_p,
rows_p,
cols_p,
objcnt_p,
rhscnt_p,
nzcnt_p,
ecnt_p,
gcnt_p,
lcnt_p,
rngcnt_p,
ncnt_p,
fcnt_p,
xcnt_p,
bcnt_p,
ocnt_p,
bicnt_p,
icnt_p,
scnt_p,
sicnt_p,
qpcnt_p,
qpnzcnt_p,
nqconstr_p,
qrhscnt_p,
qlcnt_p,
qgcnt_p,
quadnzcnt_p,
linnzcnt_p,
nindconstr_p,
indrhscnt_p,
indnzcnt_p,
indcompcnt_p,
indlcnt_p,
indecnt_p,
indgcnt_p,
maxcoef_p,
mincoef_p,
minrhs_p,
maxrhs_p,
minrng_p,
maxrng_p,
minobj_p,
maxobj_p,
minlb_p,
maxub_p,
minqcoef_p,
maxqcoef_p,
minqcq_p,
maxqcq_p,
minqcl_p,
maxqcl_p,
minqcr_p,
maxqcr_p,
minind_p,
maxind_p,
minindrhs_p,
maxindrhs_p,
minlazy_p,
maxlazy_p,
minlazyrhs_p,
maxlazyrhs_p,
minucut_p,
maxucut_p,
minucutrhs_p,
maxucutrhs_p,
nsos_p,
nsos1_p,
sos1nmem_p,
sos1type_p,
nsos2_p,
sos2nmem_p,
sos2type_p,
lazyrhscnt_p,
lazygcnt_p,
lazylcnt_p,
lazyecnt_p,
lazycnt_p,
lazynzcnt_p,
ucutrhscnt_p,
ucutgcnt_p,
ucutlcnt_p,
ucutecnt_p,
ucutcnt_p,
ucutnzcnt_p,
npwl_p,
npwlbreaks_p)
check_status(env, status)
return ProbStats(
objs_p.value(),
rows_p.value(),
cols_p.value(),
objcnt_p.value(),
rhscnt_p.value(),
nzcnt_p.value(),
ecnt_p.value(),
gcnt_p.value(),
lcnt_p.value(),
rngcnt_p.value(),
ncnt_p.value(),
fcnt_p.value(),
xcnt_p.value(),
bcnt_p.value(),
ocnt_p.value(),
bicnt_p.value(),
icnt_p.value(),
scnt_p.value(),
sicnt_p.value(),
qpcnt_p.value(),
qpnzcnt_p.value(),
nqconstr_p.value(),
qrhscnt_p.value(),
qlcnt_p.value(),
qgcnt_p.value(),
quadnzcnt_p.value(),
linnzcnt_p.value(),
nindconstr_p.value(),
indrhscnt_p.value(),
indnzcnt_p.value(),
indcompcnt_p.value(),
indlcnt_p.value(),
indecnt_p.value(),
indgcnt_p.value(),
maxcoef_p.value(),
mincoef_p.value(),
minrhs_p.value(),
maxrhs_p.value(),
minrng_p.value(),
maxrng_p.value(),
minobj_p.value(),
maxobj_p.value(),
minlb_p.value(),
maxub_p.value(),
minqcoef_p.value(),
maxqcoef_p.value(),
minqcq_p.value(),
maxqcq_p.value(),
minqcl_p.value(),
maxqcl_p.value(),
minqcr_p.value(),
maxqcr_p.value(),
minind_p.value(),
maxind_p.value(),
minindrhs_p.value(),
maxindrhs_p.value(),
minlazy_p.value(),
maxlazy_p.value(),
minlazyrhs_p.value(),
maxlazyrhs_p.value(),
minucut_p.value(),
maxucut_p.value(),
minucutrhs_p.value(),
maxucutrhs_p.value(),
nsos_p.value(),
nsos1_p.value(),
sos1nmem_p.value(),
sos1type_p.value(),
nsos2_p.value(),
sos2nmem_p.value(),
sos2type_p.value(),
lazyrhscnt_p.value(),
lazygcnt_p.value(),
lazylcnt_p.value(),
lazyecnt_p.value(),
lazycnt_p.value(),
lazynzcnt_p.value(),
ucutrhscnt_p.value(),
ucutgcnt_p.value(),
ucutlcnt_p.value(),
ucutecnt_p.value(),
ucutcnt_p.value(),
ucutnzcnt_p.value(),
npwl_p.value(),
npwlbreaks_p.value())
# get histogram of non-zero row/column counts
[docs]
def gethist(env, lp, key):
if key == 'r':
space = CR.CPXXgetnumcols(env, lp) + 1
else:
key = 'c'
space = CR.CPXXgetnumrows(env, lp) + 1
hist = _safeIntArray(space)
status = CR.CPXEgethist(env, lp, key, hist)
check_status(env, status)
return LAU.array_to_list(hist, space)
# get solution quality metrics
[docs]
def getqualitymetrics(env, lp, soln):
space = 26
data = _safeDoubleArray(space)
ispace = 10
idata = _safeIntArray(ispace)
status = CR.CPXEgetqualitymetrics(env, lp, soln, data, idata)
check_status(env, status)
return [LAU.array_to_list(idata, ispace),
LAU.array_to_list(data, space)]
[docs]
def showquality(env, lp, soln):
status = CR.CPXEshowquality(env, lp, soln)
check_status(env, status)
# ########## Expert Callback BEGIN ########################################
[docs]
def setgenericcallbackfunc(env, lp, contextmask, cbhandle):
# NOTE: The cbhandle that is passed in here, is the Cplex instance that
# installs the callback. We do not increment the reference count
# for this on purpose: First of all, it is not necessary since the
# lifetime of env/lp is controled by the lifetime of this instance.
# Hence any reference the callable library stores is valid as long
# as it may be used.
# Second, in the destructor of the Cplex class we attempt to set
# the callback to (0, None). This may fail with
# CPXERR_NOT_ONE_PROBLEM. If we had incremented the reference count
# we would have to figure out whether the attempt to unset got as
# far as decrementing the reference count or failed earlier.
status = CR.CPXXcallbacksetfunc(env, lp, contextmask, cbhandle)
check_status(env, status)
[docs]
def callbackgetinfoint(contextptr, which):
data = CR.intPtr()
status = CR.CPXXcallbackgetinfoint(contextptr, [which, data])
check_status(None, status)
return data.value()
[docs]
def callbackgetinfolong(contextptr, which):
data = CR.cpxlongPtr()
status = CR.CPXXcallbackgetinfolong(contextptr, [which, data])
check_status(None, status)
return data.value()
[docs]
def callbackgetinfodbl(contextptr, which):
data = CR.doublePtr()
status = CR.CPXXcallbackgetinfodbl(contextptr, [which, data])
check_status(None, status)
return data.value()
[docs]
def callbackabort(contextptr):
CR.CPXXcallbackabort(contextptr)
[docs]
def callbackcandidateispoint(contextptr):
bounded = CR.intPtr()
status = CR.CPXXcallbackcandidateispoint(contextptr, bounded)
check_status(None, status)
return bounded.value() != 0
[docs]
def callbackgetcandidatepoint(contextptr, begin, end):
xlen = _rangelen(begin, end)
x = _safeDoubleArray(xlen)
status = CR.CPXXcallbackgetcandidatepoint(contextptr, x, begin, end, None)
check_status(None, status)
return LAU.array_to_list(x, xlen)
[docs]
def callbackcandidateisray(contextptr):
ray = CR.intPtr()
status = CR.CPXXcallbackcandidateisray(contextptr, ray)
check_status(None, status)
return ray.value() != 0
[docs]
def callbackgetcandidateray(contextptr, begin, end):
raylen = _rangelen(begin, end)
ray = _safeDoubleArray(raylen)
status = CR.CPXXcallbackgetcandidateray(contextptr, ray, begin, end)
check_status(None, status)
return LAU.array_to_list(ray, raylen)
[docs]
def callbackgetcandidateobj(contextptr):
obj_p = CR.doublePtr()
status = CR.CPXXcallbackgetcandidatepoint(contextptr, None, 0, -1, obj_p)
check_status(None, status)
return obj_p.value()
[docs]
def callbackgetrelaxationpoint(contextptr, begin, end):
xlen = _rangelen(begin, end)
x = _safeDoubleArray(xlen)
status = CR.CPXXcallbackgetrelaxationpoint(contextptr, x, begin, end, None)
check_status(None, status)
return LAU.array_to_list(x, xlen)
[docs]
def callbackgetrelaxationpointobj(contextptr):
obj_p = CR.doublePtr()
status = CR.CPXXcallbackgetrelaxationpoint(contextptr, None, 0, -1, obj_p)
check_status(None, status)
return obj_p.value()
[docs]
def callbackgetrelaxationstatus(contextptr, flags):
nodelpstat = CR.intPtr()
status = CR.CPXXcallbackgetrelaxationstatus(contextptr, nodelpstat, flags)
check_status(None, status)
return nodelpstat.value()
[docs]
def callbackmakebranch(contextptr, ind, lu, bd, rhs, sense, matbeg,
matind, matval, nodeest):
seqnum = CR.cpxlongPtr()
with LAU.int_c_array(ind) as c_ind,\
LAU.double_c_array(bd) as c_bd, \
LAU.double_c_array(rhs) as c_rhs, \
LAU.long_c_array(matbeg) as c_matbeg, \
LAU.int_c_array(matind) as c_matind, \
LAU.double_c_array(matval) as c_matval:
status = CR.CPXXcallbackmakebranch(contextptr, len(ind),
c_ind, lu, c_bd,
len(matbeg), len(matind),
c_rhs, sense,
c_matbeg, c_matind, c_matval,
nodeest, seqnum)
check_status(None, status)
return seqnum.value()
[docs]
def callbackprunenode(contextptr):
status = CR.CPXXcallbackprunenode(contextptr)
check_status(None, status)
[docs]
def callbackexitcutloop(contextptr):
status = CR.CPXXcallbackexitcutloop(contextptr)
check_status(None, status)
[docs]
def callbackgetincumbent(contextptr, begin, end):
xlen = _rangelen(begin, end)
x = _safeDoubleArray(xlen)
status = CR.CPXXcallbackgetincumbent(contextptr, x, begin, end, None)
check_status(None, status)
return LAU.array_to_list(x, xlen)
[docs]
def callbackgetincumbentobj(contextptr):
obj_p = CR.doublePtr()
status = CR.CPXXcallbackgetincumbent(contextptr, None, 0, -1, obj_p)
check_status(None, status)
return obj_p.value()
[docs]
def callbackgetlocallb(contextptr, begin, end):
xlen = _rangelen(begin, end)
x = _safeDoubleArray(xlen)
status = CR.CPXXcallbackgetlocallb(contextptr, x, begin, end)
check_status(None, status)
return LAU.array_to_list(x, xlen)
[docs]
def callbackgetlocalub(contextptr, begin, end):
xlen = _rangelen(begin, end)
x = _safeDoubleArray(xlen)
status = CR.CPXXcallbackgetlocalub(contextptr, x, begin, end)
check_status(None, status)
return LAU.array_to_list(x, xlen)
[docs]
def callbackgetgloballb(contextptr, begin, end):
xlen = _rangelen(begin, end)
x = _safeDoubleArray(xlen)
status = CR.CPXXcallbackgetgloballb(contextptr, x, begin, end)
check_status(None, status)
return LAU.array_to_list(x, xlen)
[docs]
def callbackgetglobalub(contextptr, begin, end):
xlen = _rangelen(begin, end)
x = _safeDoubleArray(xlen)
status = CR.CPXXcallbackgetglobalub(contextptr, x, begin, end)
check_status(None, status)
return LAU.array_to_list(x, xlen)
[docs]
def callbackpostheursoln(contextptr, cnt, ind, val, obj, strategy):
status = CR.CPXXcallbackpostheursoln(contextptr, cnt,
LAU.int_list_to_array(ind),
LAU.double_list_to_array(val),
obj, strategy)
check_status(None, status)
[docs]
def callbackaddusercuts(contextptr, rcnt, nzcnt, rhs, sense, rmat,
cutmanagement, local):
with LAU.double_c_array(rhs) as c_rhs, \
LAU.int_c_array(cutmanagement) as c_cutmanagement, \
LAU.int_c_array(local) as c_local:
status = CR.CPXXcallbackaddusercuts(contextptr, rcnt, nzcnt, c_rhs,
sense, rmat,
c_cutmanagement, c_local)
check_status(None, status)
[docs]
def callbackrejectcandidate(contextptr, rcnt, nzcnt, rhs, sense, rmat):
with LAU.double_c_array(rhs) as c_rhs:
status = CR.CPXXcallbackrejectcandidate(contextptr, rcnt, nzcnt, c_rhs,
sense, rmat)
check_status(None, status)
[docs]
def callbackrejectcandidatelocal(contextptr, rcnt, nzcnt, rhs, sense, rmat):
with LAU.double_c_array(rhs) as c_rhs:
status = CR.CPXXcallbackrejectcandidatelocal(contextptr, rcnt, nzcnt,
c_rhs, sense, rmat)
check_status(None, status)
# ########## Expert Callback END ##########################################
# ########## Modeling Assistance Callback BEGIN ###########################
[docs]
def modelasstcallbacksetfunc(env, lp, cbhandle):
# See note in setgenericcallbackfunc (the same applies here).
status = CR.CPXXmodelasstcallbacksetfunc(env, lp, cbhandle)
check_status(env, status)
# ########## Modeling Assistance Callback END #############################