Path: blob/master/sage/numerical/backends/cplex_backend.pyx
4057 views
"""1CPLEX Backend23AUTHORS:45- Nathann Cohen (2010-10): initial implementation67"""89##############################################################################10# Copyright (C) 2010 Nathann Cohen <[email protected]>11# Distributed under the terms of the GNU General Public License (GPL)12# The full text of the GPL is available at:13# http://www.gnu.org/licenses/14##############################################################################151617from sage.numerical.mip import MIPSolverException1819cdef class CPLEXBackend(GenericBackend):2021def __cinit__(self, maximization = True):22"""23Constructor2425EXAMPLE::2627sage: p = MixedIntegerLinearProgram(solver="CPLEX") # optional - CPLEX28"""2930cdef int status31self.env = CPXopenCPLEX (&status)32check(status)3334cdef char * tmp = ""35self.lp = CPXcreateprob (self.env, &status, tmp);36check(status)3738if maximization:39self.set_sense(+1)40else:41self.set_sense(-1)4243self.obj_constant_term = 0.04445cpdef int add_variable(self, lower_bound=0.0, upper_bound=None, binary=False, continuous=False, integer=False, obj=0.0, name=None) except -1:46"""47Add a variable.4849This amounts to adding a new column to the matrix. By default,50the variable is both positive and real.5152INPUT:5354- ``lower_bound`` - the lower bound of the variable (default: 0)5556- ``upper_bound`` - the upper bound of the variable (default: ``None``)5758- ``binary`` - ``True`` if the variable is binary (default: ``False``).5960- ``continuous`` - ``True`` if the variable is binary (default: ``True``).6162- ``integer`` - ``True`` if the variable is binary (default: ``False``).6364- ``obj`` - (optional) coefficient of this variable in the objective function (default: 0.0)6566- ``name`` - an optional name for the newly added variable (default: ``None``).6768OUTPUT: The index of the newly created variable6970EXAMPLE::7172sage: from sage.numerical.backends.generic_backend import get_solver73sage: p = get_solver(solver = "CPLEX") # optional - CPLEX74sage: p.ncols() # optional - CPLEX75076sage: p.add_variable() # optional - CPLEX77078sage: p.ncols() # optional - CPLEX79180sage: p.add_variable(binary=True) # optional - CPLEX81182sage: p.add_variable(lower_bound=-2.0, integer=True) # optional - CPLEX83284sage: p.add_variable(continuous=True, integer=True) # optional - CPLEX85Traceback (most recent call last):86...87ValueError: ...88sage: p.add_variable(name='x',obj=1.0) # optional - CPLEX89390sage: p.col_name(3) # optional - CPLEX91'x'92sage: p.objective_coefficient(3) # optional - CPLEX931.09495"""96cdef char * c_name97cdef double c_coeff = obj98cdef int vtype = int(bool(binary)) + int(bool(continuous)) + int(bool(integer))99if vtype == 0:100continuous = True101elif vtype != 1:102raise ValueError("Exactly one parameter of 'binary', 'integer' and 'continuous' must be 'True'.")103104cdef int status105status = CPXnewcols(self.env, self.lp, 1, NULL, NULL, NULL, NULL, NULL)106check(status)107108cdef int n109n = CPXgetnumcols(self.env, self.lp) - 1110111if lower_bound != 0.0:112self.variable_lower_bound(n, lower_bound)113if upper_bound is not None:114self.variable_upper_bound(n, upper_bound)115116if binary:117self.set_variable_type(n,0)118elif integer:119self.set_variable_type(n,1)120121if name is not None:122c_name = name123status = CPXchgcolname(self.env, self.lp, 1, &n, &c_name)124check(status)125126if c_coeff:127status = CPXchgobj(self.env, self.lp, 1, &n, &c_coeff)128check(status)129130return n131132cpdef int add_variables(self, int number, lower_bound=0.0, upper_bound=None, binary=False, continuous=False, integer=False, obj=0.0, names=None) except -1:133"""134Add ``number`` new variables.135136This amounts to adding new columns to the matrix. By default,137the variables are both positive and real.138139INPUT:140141- ``n`` - the number of new variables (must be > 0)142143- ``lower_bound`` - the lower bound of the variable (default: 0)144145- ``upper_bound`` - the upper bound of the variable (default: ``None``)146147- ``binary`` - ``True`` if the variable is binary (default: ``False``).148149- ``continuous`` - ``True`` if the variable is binary (default: ``True``).150151- ``integer`` - ``True`` if the variable is binary (default: ``False``).152153- ``obj`` - (optional) coefficient of all variables in the objective function (default: 0.0)154155- ``names`` - optional list of names (default: ``None``)156157OUTPUT: The index of the variable created last.158159EXAMPLE::160161sage: from sage.numerical.backends.generic_backend import get_solver162sage: p = get_solver(solver = "CPLEX") # optional - CPLEX163sage: p.ncols() # optional - CPLEX1640165sage: p.add_variables(5) # optional - CPLEX1664167sage: p.ncols() # optional - CPLEX1685169sage: p.add_variables(2, lower_bound=-2.0, integer=True, names=['a','b']) # optional - CPLEX1706171"""172cdef char * c_name173cdef double c_coeff = obj174cdef int vtype = int(bool(binary)) + int(bool(continuous)) + int(bool(integer))175if vtype == 0:176continuous = True177elif vtype != 1:178raise ValueError("Exactly one parameter of 'binary', 'integer' and 'continuous' must be 'True'.")179180cdef int status181status = CPXnewcols(self.env, self.lp, number, NULL, NULL, NULL, NULL, NULL)182check(status)183184cdef int n185n = CPXgetnumcols(self.env, self.lp) - 1186187cdef int i, j188189for 0<= i < number:190if lower_bound != 0.0:191self.variable_lower_bound(n - i, lower_bound)192if upper_bound is not None:193self.variable_upper_bound(n - i, upper_bound)194195if binary:196self.set_variable_type(n - i,0)197elif integer:198self.set_variable_type(n - i,1)199200if names:201j = n - i202c_name = names[i]203status = CPXchgcolname(self.env, self.lp, 1, &j, &c_name)204check(status)205206if c_coeff:207j = n - i208status = CPXchgobj(self.env, self.lp, 1, &j, &c_coeff)209check(status)210211return n212213cpdef set_variable_type(self, int variable, int vtype):214r"""215Sets the type of a variable216217INPUT:218219- ``variable`` (integer) -- the variable's id220221- ``vtype`` (integer) :222223* 1 Integer224* 0 Binary225* -1 Real226227EXAMPLE::228229sage: from sage.numerical.backends.generic_backend import get_solver230sage: p = get_solver(solver = "CPLEX") # optional - CPLEX231sage: p.ncols() # optional - CPLEX2320233sage: p.add_variable() # optional - CPLEX2340235sage: p.set_variable_type(0,1) # optional - CPLEX236sage: p.is_variable_integer(0) # optional - CPLEX237True238"""239240cdef int status241242cdef char type243if vtype == 1:244type = 'I'245elif vtype == 0:246type = 'B'247else:248type = 'C'249250status = CPXchgctype(self.env, self.lp, 1, &variable, &type)251check(status)252253cpdef set_sense(self, int sense):254r"""255Sets the direction (maximization/minimization).256257INPUT:258259- ``sense`` (integer) :260261* +1 => Maximization262* -1 => Minimization263264EXAMPLE::265266sage: from sage.numerical.backends.generic_backend import get_solver267sage: p = get_solver(solver = "CPLEX") # optional - CPLEX268sage: p.is_maximization() # optional - CPLEX269True270sage: p.set_sense(-1) # optional - CPLEX271sage: p.is_maximization() # optional - CPLEX272False273"""274275CPXchgobjsen(self.env, self.lp, -sense)276277cpdef objective_coefficient(self, int variable, coeff=None):278"""279Set or get the coefficient of a variable in the objective function280281INPUT:282283- ``variable`` (integer) -- the variable's id284285- ``coeff`` (double) -- its coefficient or ``None`` for286reading (default: ``None``)287288EXAMPLE::289290sage: from sage.numerical.backends.generic_backend import get_solver291sage: p = get_solver(solver = "CPLEX") # optional -- CPLEX292sage: p.add_variable() # optional -- CPLEX2930294sage: p.objective_coefficient(0) # optional -- CPLEX2950.0296sage: p.objective_coefficient(0,2) # optional -- CPLEX297sage: p.objective_coefficient(0) # optional -- CPLEX2982.0299"""300301cdef int status302cdef double value303304if coeff is None:305status = CPXgetobj(self.env, self.lp, &value, variable, variable)306check(status)307return value308309else:310value = coeff311status = CPXchgobj(self.env, self.lp, 1, &variable, &value)312check(status)313314cpdef problem_name(self, char * name = NULL):315r"""316Returns or defines the problem's name317318INPUT:319320- ``name`` (``char *``) -- the problem's name. When set to321``NULL`` (default), the method returns the problem's name.322323EXAMPLE::324325sage: from sage.numerical.backends.generic_backend import get_solver326sage: p = get_solver(solver = "CPLEX") # optional - CPLEX327sage: p.problem_name("There once was a french fry") # optional - CPLEX328sage: print p.problem_name() # optional - CPLEX329There once was a french fry330"""331332cdef int status333cdef int zero334cdef char * n335if name == NULL:336337n = <char*> sage_malloc(500*sizeof(char))338status = CPXgetprobname(self.env, self.lp, n, 500, &zero)339check(status)340s = str(n)341sage_free(n)342return s343344345else:346status = CPXchgprobname(self.env, self.lp, name)347check(status)348349350cpdef set_objective(self, list coeff, double d = 0.0):351r"""352Sets the objective function.353354INPUT:355356- ``coeff`` -- a list of real values, whose ith element is the357coefficient of the ith variable in the objective function.358359- ``d`` (double) -- the constant term in the linear function (set to `0` by default)360361EXAMPLE::362363sage: from sage.numerical.backends.generic_backend import get_solver364sage: p = get_solver(solver = "CPLEX") # optional - CPLEX365sage: p.add_variables(5) # optional - CPLEX3664367sage: p.set_objective([1, 1, 2, 1, 3]) # optional - CPLEX368sage: map(lambda x :p.objective_coefficient(x), range(5)) # optional - CPLEX369[1.0, 1.0, 2.0, 1.0, 3.0]370371Constants in the objective function are respected::372373sage: p = MixedIntegerLinearProgram(solver='CPLEX') # optional - CPLEX374sage: x,y = p[0], p[1] # optional - CPLEX375sage: p.add_constraint(2*x + 3*y, max = 6) # optional - CPLEX376sage: p.add_constraint(3*x + 2*y, max = 6) # optional - CPLEX377sage: p.set_objective(x + y + 7) # optional - CPLEX378sage: p.set_integer(x); p.set_integer(y) # optional - CPLEX379sage: p.solve() # optional - CPLEX3809.0381"""382383cdef int status384cdef int n = self.ncols()385cdef double * c_coeff = <double *> sage_malloc(n * sizeof(double))386cdef int * c_indices = <int *> sage_malloc(n * sizeof(int))387388for i,v in enumerate(coeff):389c_coeff[i] = v390c_indices[i] = i391392status = CPXchgobj(self.env, self.lp, n, c_indices, c_coeff)393check(status)394395sage_free(c_coeff)396sage_free(c_indices)397398self.obj_constant_term = d399400401cpdef set_verbosity(self, int level):402r"""403Sets the log (verbosity) level404405INPUT:406407- ``level`` (integer) -- From 0 (no verbosity) to 3.408409EXAMPLE::410411sage: from sage.numerical.backends.generic_backend import get_solver412sage: p = get_solver(solver = "CPLEX") # optional - CPLEX413sage: p.set_verbosity(2) # optional - CPLEX414415"""416417cdef int status418if level == 0:419status = CPXsetintparam (self.env, CPX_PARAM_SCRIND, 0)420check(status)421else:422status = CPXsetintparam (self.env, CPX_PARAM_SCRIND, CPX_ON)423check(status)424425cpdef remove_constraint(self, int i):426r"""427Remove a constraint from self.428429INPUT:430431- ``i`` -- index of the constraint to remove432433EXAMPLE::434435sage: p = MixedIntegerLinearProgram(solver='CPLEX')# optional - CPLEX436sage: x,y = p[0], p[1] # optional - CPLEX437sage: p.add_constraint(2*x + 3*y, max = 6) # optional - CPLEX438sage: p.add_constraint(3*x + 2*y, max = 6) # optional - CPLEX439sage: p.set_objective(x + y + 7) # optional - CPLEX440sage: p.set_integer(x); p.set_integer(y) # optional - CPLEX441sage: p.solve() # optional - CPLEX4429.0443sage: p.remove_constraint(0) # optional - CPLEX444sage: p.solve() # optional - CPLEX44510.0446sage: p.get_values([x,y]) # optional - CPLEX447[0.0, 3.0]448"""449cdef int status450status = CPXdelrows(self.env, self.lp, i, i)451check(status)452453cpdef add_linear_constraints(self, int number, lower_bound, upper_bound, names = None):454"""455Add ``'number`` linear constraints.456457INPUT:458459- ``number`` (integer) -- the number of constraints to add.460461- ``lower_bound`` - a lower bound, either a real value or ``None``462463- ``upper_bound`` - an upper bound, either a real value or ``None``464465- ``names`` - an optional list of names (default: ``None``)466467EXAMPLE::468469sage: from sage.numerical.backends.generic_backend import get_solver470sage: p = get_solver(solver = "CPLEX") # optional - CPLEX471sage: p.add_variables(5) # optional - CPLEX4724473sage: p.add_linear_constraints(5, None, 2) # optional - CPLEX474sage: p.row(4) # optional - CPLEX475([], [])476sage: p.row_bounds(4) # optional - CPLEX477(None, 2.0)478sage: p.add_linear_constraints(2, None, 2, names=['foo','bar']) # optional - Coin479"""480if lower_bound is None and upper_bound is None:481raise ValueError("At least one of 'upper_bound' or 'lower_bound' must be set.")482483cdef int status484cdef char * sense = <char *> sage_malloc(number * sizeof(char))485cdef double * bound = <double *> sage_malloc(number * sizeof(double))486cdef double * rng = NULL487cdef int i488cdef char ** c_names = <char **> sage_malloc(number * sizeof(char *))489490if upper_bound == lower_bound:491sense[0] = 'E'492bound[0] = lower_bound493494elif upper_bound is not None and lower_bound is not None:495if upper_bound < lower_bound:496raise ValueError("The upper bound must be at least equal to the lower bound !")497498rng = <double *> sage_malloc(number * sizeof(double))499500sense[0] = 'R'501bound[0] = lower_bound502rng[0] = upper_bound - lower_bound503504elif upper_bound is not None:505sense[0] = 'L'506bound[0] = upper_bound507508elif lower_bound is not None:509sense[0] = 'G'510bound[0] = lower_bound511512if names:513c_names[0] = names[0]514515for 1<= i <number:516sense[i] = sense[0]517bound[i] = bound[0]518if rng != NULL:519rng[i] = rng[0]520if names:521c_names[i] = names[i]522523status = CPXnewrows(self.env, self.lp, number, bound, sense, rng, c_names if names else NULL)524525sage_free(sense)526sage_free(bound)527sage_free(c_names)528check(status)529530cpdef add_linear_constraint(self, coefficients, lower_bound, upper_bound, name = None):531"""532Add a linear constraint.533534INPUT:535536- ``coefficients`` an iterable with ``(c,v)`` pairs where ``c``537is a variable index (integer) and ``v`` is a value (real538value).539540- ``lower_bound`` - a lower bound, either a real value or ``None``541542- ``upper_bound`` - an upper bound, either a real value or ``None``543544- ``name`` - an optional name for this row (default: ``None``)545546EXAMPLE::547548sage: from sage.numerical.backends.generic_backend import get_solver549sage: p = get_solver(solver = "CPLEX") # optional - CPLEX550sage: p.add_variables(5) # optional - CPLEX5514552sage: p.add_linear_constraint( zip(range(5), range(5)), 2.0, 2.0) # optional - CPLEX553sage: p.row(0) # optional - CPLEX554([1, 2, 3, 4], [1.0, 2.0, 3.0, 4.0])555sage: p.row_bounds(0) # optional - CPLEX556(2.0, 2.0)557sage: p.add_linear_constraint( zip(range(5), range(5)), 1.0, 1.0, name='foo') # optional - CPLEX558sage: p.row_name(1) # optional - CPLEX559'foo'560561"""562if lower_bound is None and upper_bound is None:563raise ValueError("At least one of 'upper_bound' or 'lower_bound' must be set.")564565cdef int status566cdef int i, j567cdef int n = len(coefficients)568cdef int nrows = self.nrows()569cdef char sense570571cdef char * c_name572573cdef double * c_coeff574cdef int * c_indices575cdef int * c_row576cdef double bound577cdef double rng578cdef double c579580c_coeff = <double *> sage_malloc(n * sizeof(double))581c_indices = <int *> sage_malloc(n * sizeof(int))582c_row = <int *> sage_malloc(n * sizeof(int))583584for i, (j, c) in enumerate(coefficients):585c_coeff[i] = c586c_indices[i] = j587c_row[i] = nrows588589if upper_bound is None and lower_bound is None:590pass591592elif upper_bound == lower_bound:593sense = 'E'594bound = lower_bound595596elif upper_bound is not None and lower_bound is not None:597if upper_bound < lower_bound:598raise ValueError("The upper bound must be at least equal to the lower bound !")599600sense = 'R'601bound = lower_bound602rng = upper_bound - lower_bound603604elif upper_bound is not None:605sense = 'L'606bound = upper_bound607608elif lower_bound is not None:609sense = 'G'610bound = lower_bound611612if name:613c_name = name614615status = CPXnewrows(self.env, self.lp, 1, &bound, &sense, &rng, NULL if (name is None) else &c_name)616617check(status)618status = CPXchgcoeflist(self.env, self.lp, n, c_row, c_indices, c_coeff)619check(status)620621# Free memory622sage_free(c_coeff)623sage_free(c_indices)624sage_free(c_row)625626cpdef row(self, int index):627r"""628Returns a row629630INPUT:631632- ``index`` (integer) -- the constraint's id.633634OUTPUT:635636A pair ``(indices, coeffs)`` where ``indices`` lists the637entries whose coefficient is nonzero, and to which ``coeffs``638associates their coefficient on the model of the639``add_linear_constraint`` method.640641EXAMPLE::642643sage: from sage.numerical.backends.generic_backend import get_solver644sage: p = get_solver(solver = "CPLEX") # optional - CPLEX645sage: p.add_variables(5) # optional - CPLEX6464647sage: p.add_linear_constraint(zip(range(5), range(5)), 2, 2) # optional - CPLEX648sage: p.row(0) # optional - CPLEX649([1, 2, 3, 4], [1.0, 2.0, 3.0, 4.0])650sage: p.row_bounds(0) # optional - CPLEX651(2.0, 2.0)652"""653654cdef int status655cdef int n,i656cdef int zero657cdef list indices = []658cdef list values = []659660cdef double * c_coeff = <double *> sage_malloc((self.ncols()+10) * sizeof(double))661cdef int * c_indices = <int *> sage_malloc((self.ncols()+10) * sizeof(int))662663status = CPXgetrows(self.env, self.lp, &n, &zero, c_indices, c_coeff, self.ncols()+3, &zero, index, index)664665check(status)666667for 0<= i<n:668indices.append(c_indices[i])669values.append(c_coeff[i])670671sage_free(c_coeff)672sage_free(c_indices)673674return (indices, values)675676cpdef row_bounds(self, int index):677r"""678Returns the bounds of a specific constraint.679680INPUT:681682- ``index`` (integer) -- the constraint's id.683684OUTPUT:685686A pair ``(lower_bound, upper_bound)``. Each of them can be set687to ``None`` if the constraint is not bounded in the688corresponding direction, and is a real value otherwise.689690EXAMPLE::691692sage: from sage.numerical.backends.generic_backend import get_solver693sage: p = get_solver(solver = "CPLEX") # optional - CPLEX694sage: p.add_variables(5) # optional - CPLEX6954696sage: p.add_linear_constraint(zip(range(5), range(5)), 2, 2) # optional - CPLEX697sage: p.row(0) # optional - CPLEX698([1, 2, 3, 4], [1.0, 2.0, 3.0, 4.0])699sage: p.row_bounds(0) # optional - CPLEX700(2.0, 2.0)701"""702703cdef int status704cdef double rng705cdef double value706status = CPXgetrhs(self.env, self.lp, &value, index, index)707check(status)708709cdef char direction710status = CPXgetsense(self.env, self.lp, &direction, index, index)711check(status)712713if direction == 'L':714return (None, value)715elif direction == 'G':716return (value, None)717elif direction == 'E':718return (value, value)719elif direction == 'R':720status = CPXgetrngval(self.env, self.lp, &rng, index, index)721check(status)722return (value, value + rng)723724cpdef col_bounds(self, int index):725r"""726Returns the bounds of a specific variable.727728INPUT:729730- ``index`` (integer) -- the variable's id.731732OUTPUT:733734A pair ``(lower_bound, upper_bound)``. Each of them can be set735to ``None`` if the variable is not bounded in the736corresponding direction, and is a real value otherwise.737738EXAMPLE::739740sage: from sage.numerical.backends.generic_backend import get_solver741sage: p = get_solver(solver = "CPLEX") # optional - CPLEX742sage: p.add_variable() # optional - CPLEX7430744sage: p.col_bounds(0) # optional - CPLEX745(0.0, None)746sage: p.variable_upper_bound(0, 5) # optional - CPLEX747sage: p.col_bounds(0) # optional - CPLEX748(0.0, 5.0)749"""750751cdef int status752cdef double ub753cdef double lb754755status = CPXgetub(self.env, self.lp, &ub, index, index)756check(status)757758status = CPXgetlb(self.env, self.lp, &lb, index, index)759check(status)760761return (None if lb <= -int(CPX_INFBOUND) else lb,762None if ub >= +int(CPX_INFBOUND) else ub)763764cpdef add_col(self, list indices, list coeffs):765r"""766Adds a column.767768INPUT:769770- ``indices`` (list of integers) -- this list constains the771indices of the constraints in which the variable's772coefficient is nonzero773774- ``coeffs`` (list of real values) -- associates a coefficient775to the variable in each of the constraints in which it776appears. Namely, the ith entry of ``coeffs`` corresponds to777the coefficient of the variable in the constraint778represented by the ith entry in ``indices``.779780.. NOTE::781782``indices`` and ``coeffs`` are expected to be of the same783length.784785EXAMPLE::786787sage: from sage.numerical.backends.generic_backend import get_solver788sage: p = get_solver(solver = "CPLEX") # optional - CPLEX789sage: p.ncols() # optional - CPLEX7900791sage: p.nrows() # optional - CPLEX7920793sage: p.add_linear_constraints(5, 0, None) # optional - CPLEX794sage: p.add_col(range(5), range(5)) # optional - CPLEX795sage: p.nrows() # optional - CPLEX7965797"""798799cdef int status800cdef int i801cdef int n = len(indices)802cdef int ncols = self.ncols()803804status = CPXnewcols(self.env, self.lp, 1, NULL, NULL, NULL, NULL, NULL)805806807check(status)808809cdef double * c_coeff = <double *> sage_malloc(n * sizeof(double))810cdef int * c_indices = <int *> sage_malloc(n * sizeof(int))811cdef int * c_col = <int *> sage_malloc(n * sizeof(int))812813for 0<= i < n:814c_coeff[i] = coeffs[i]815c_indices[i] = indices[i]816c_col[i] = ncols817818819status = CPXchgcoeflist(self.env, self.lp, n, c_indices, c_col, c_coeff)820check(status)821822sage_free(c_coeff)823sage_free(c_indices)824sage_free(c_col)825826827cpdef int solve(self) except -1:828r"""829Solves the problem.830831.. NOTE::832833This method raises ``MIPSolverException`` exceptions when834the solution can not be computed for any reason (none835exists, or the LP solver was not able to find it, etc...)836837EXAMPLE::838839sage: from sage.numerical.backends.generic_backend import get_solver840sage: p = get_solver(solver = "CPLEX") # optional - CPLEX841sage: p.add_linear_constraints(5, 0, None) # optional - CPLEX842sage: p.add_col(range(5), range(5)) # optional - CPLEX843sage: p.solve() # optional - CPLEX8440845sage: p.objective_coefficient(0,1) # optional - CPLEX846sage: p.solve() # optional - CPLEX847Traceback (most recent call last):848...849MIPSolverException: ...850"""851852cdef int status853cdef int ptype854cdef int solnmethod_p, solntype_p, pfeasind_p, dfeasind_p855856ptype = CPXgetprobtype(self.env, self.lp)857858if ptype == 1:859status = CPXmipopt(self.env, self.lp)860elif ptype == 0:861status = CPXlpopt(self.env, self.lp)862else:863raise MIPSolverException("CPLEX: Unknown problem type")864865check(status)866867status = CPXsolninfo(self.env, self.lp, &solnmethod_p, &solntype_p, &pfeasind_p, &dfeasind_p)868check(status)869870if not pfeasind_p:871raise MIPSolverException("CPLEX: The primal has no feasible solution")872if not dfeasind_p:873raise MIPSolverException("CPLEX: The problem is unbounded")874875876return 0877878879cpdef double get_objective_value(self):880r"""881Returns the value of the objective function.882883.. NOTE::884885Has no meaning unless ``solve`` has been called before.886887EXAMPLE::888889sage: from sage.numerical.backends.generic_backend import get_solver890sage: p = get_solver(solver = "CPLEX") # optional - CPLEX891sage: p.add_variables(2) # optional - CPLEX8921893sage: p.add_linear_constraint([(0,1), (1,2)], None, 3) # optional - CPLEX894sage: p.set_objective([2, 5]) # optional - CPLEX895sage: p.solve() # optional - CPLEX8960897sage: p.get_objective_value() # optional - CPLEX8987.5899sage: p.get_variable_value(0) # optional - CPLEX9000.0901sage: p.get_variable_value(1) # optional - CPLEX9021.5903"""904905cdef int status906cdef double value907status = CPXgetobjval (self.env, self.lp, &value)908check(status)909910return value + self.obj_constant_term911912913cpdef double get_variable_value(self, int variable):914r"""915Returns the value of a variable given by the solver.916917.. NOTE::918919Has no meaning unless ``solve`` has been called before.920921EXAMPLE::922923sage: from sage.numerical.backends.generic_backend import get_solver924sage: p = get_solver(solver = "CPLEX") # optional - CPLEX925sage: p.add_variables(2) # optional - CPLEX9261927sage: p.add_linear_constraint([(0,1), (1,2)], None, 3) # optional - CPLEX928sage: p.set_objective([2, 5]) # optional - CPLEX929sage: p.solve() # optional - CPLEX9300931sage: p.get_objective_value() # optional - CPLEX9327.5933sage: p.get_variable_value(0) # optional - CPLEX9340.0935sage: p.get_variable_value(1) # optional - CPLEX9361.5937"""938939cdef int status940cdef int zero941cdef char ctype942cdef double value943status = CPXgetx(self.env, self.lp, &value, variable, variable)944check(status)945946status = CPXgetctype(self.env, self.lp, &ctype, variable, variable)947948return value if (status == 3003 or ctype=='C') else round(value)949950cpdef int ncols(self):951r"""952Returns the number of columns/variables.953954EXAMPLE::955956sage: from sage.numerical.backends.generic_backend import get_solver957sage: p = get_solver(solver = "CPLEX") # optional - CPLEX958sage: p.ncols() # optional - CPLEX9590960sage: p.add_variables(2) # optional - CPLEX9611962sage: p.ncols() # optional - CPLEX9632964"""965966return CPXgetnumcols(self.env, self.lp)967968cpdef int nrows(self):969r"""970Returns the number of rows/constraints.971972EXAMPLE::973974sage: from sage.numerical.backends.generic_backend import get_solver975sage: p = get_solver(solver = "CPLEX") # optional - CPLEX976sage: p.nrows() # optional - CPLEX9770978sage: p.add_linear_constraints(2, 2, None) # optional - CPLEX979sage: p.nrows() # optional - CPLEX9802981"""982983return CPXgetnumrows(self.env, self.lp)984985cpdef row_name(self, int index):986r"""987Return the ``index`` th row name988989INPUT:990991- ``index`` (integer) -- the row's id992993EXAMPLE::994995sage: from sage.numerical.backends.generic_backend import get_solver996sage: p = get_solver(solver = "CPLEX") # optional - CPLEX997sage: p.add_linear_constraints(1, 2, None, names=['Empty constraint 1']) # optional - CPLEX998sage: p.row_name(0) # optional - CPLEX999'Empty constraint 1'1000"""10011002cdef int status1003cdef int zero1004cdef char * n10051006n = <char *>sage_malloc(500*sizeof(char))1007status = CPXgetrowname(self.env, self.lp, &n, n, 500, &zero, index, index)1008if status == 1219:1009sage_free(n)1010return ""1011check(status)10121013s = str(n)1014sage_free(n)10151016return s10171018cpdef col_name(self, int index):1019r"""1020Returns the ``index`` th col name.10211022INPUT:10231024- ``index`` (integer) -- the col's id10251026EXAMPLE::10271028sage: from sage.numerical.backends.generic_backend import get_solver1029sage: p = get_solver(solver = "CPLEX") # optional - CPLEX1030sage: p.add_variable(name='I am a variable') # optional - CPLEX103101032sage: p.col_name(0) # optional - CPLEX1033'I am a variable'1034"""10351036cdef int status1037cdef char * n1038cdef int zero10391040n = <char *>sage_malloc(500*sizeof(char))1041status = CPXgetcolname(self.env, self.lp, &n, n, 500, &zero, index, index)1042if status == 1219:1043sage_free(n)1044return ""1045check(status)10461047s = str(n)1048sage_free(n)1049return s10501051cpdef bint is_variable_binary(self, int index):1052r"""1053Tests whether the given variable is of binary type.10541055INPUT:10561057- ``index`` (integer) -- the variable's id10581059EXAMPLE::10601061sage: from sage.numerical.backends.generic_backend import get_solver1062sage: p = get_solver(solver = "CPLEX") # optional - CPLEX1063sage: p.ncols() # optional - CPLEX106401065sage: p.add_variable() # optional - CPLEX106601067sage: p.set_variable_type(0,0) # optional - CPLEX1068sage: p.is_variable_binary(0) # optional - CPLEX1069True10701071"""10721073cdef int status1074cdef char ctype10751076status = CPXgetctype(self.env, self.lp, &ctype, index, index)10771078# status = 3003 when the problem is a LP and not a MILP1079if status == 3003:1080return False10811082check(status)10831084return ctype == 'B'108510861087cpdef bint is_variable_integer(self, int index):1088r"""1089Tests whether the given variable is of integer type.10901091INPUT:10921093- ``index`` (integer) -- the variable's id10941095EXAMPLE::10961097sage: from sage.numerical.backends.generic_backend import get_solver1098sage: p = get_solver(solver = "CPLEX") # optional - CPLEX1099sage: p.ncols() # optional - CPLEX110001101sage: p.add_variable() # optional - CPLEX110201103sage: p.set_variable_type(0,1) # optional - CPLEX1104sage: p.is_variable_integer(0) # optional - CPLEX1105True1106"""11071108cdef int status1109cdef char ctype11101111status = CPXgetctype(self.env, self.lp, &ctype, index, index)11121113# status = 3003 when the problem is a LP and not a MILP1114if status == 3003:1115return False11161117check(status)11181119return ctype == 'I'112011211122cpdef bint is_variable_continuous(self, int index):1123r"""1124Tests whether the given variable is of continuous/real type.11251126INPUT:11271128- ``index`` (integer) -- the variable's id11291130EXAMPLE::11311132sage: from sage.numerical.backends.generic_backend import get_solver1133sage: p = get_solver(solver = "CPLEX") # optional - CPLEX1134sage: p.ncols() # optional - CPLEX113501136sage: p.add_variable() # optional - CPLEX113701138sage: p.is_variable_continuous(0) # optional - CPLEX1139True1140sage: p.set_variable_type(0,1) # optional - CPLEX1141sage: p.is_variable_continuous(0) # optional - CPLEX1142False11431144"""11451146cdef int status1147cdef char ctype11481149status = CPXgetctype(self.env, self.lp, &ctype, index, index)11501151# status = 3003 when the problem is a LP and not a MILP1152if status == 3003:1153return True11541155check(status)11561157return ctype == 'C'115811591160cpdef bint is_maximization(self):1161r"""1162Tests whether the problem is a maximization11631164EXAMPLE::11651166sage: from sage.numerical.backends.generic_backend import get_solver1167sage: p = get_solver(solver = "CPLEX") # optional - CPLEX1168sage: p.is_maximization() # optional - CPLEX1169True1170sage: p.set_sense(-1) # optional - CPLEX1171sage: p.is_maximization() # optional - CPLEX1172False1173"""11741175return -1 == CPXgetobjsen(self.env, self.lp)11761177cpdef variable_upper_bound(self, int index, value = False):1178r"""1179Returns or defines the upper bound on a variable11801181INPUT:11821183- ``index`` (integer) -- the variable's id11841185- ``value`` -- real value, or ``None`` to mean that the1186variable has not upper bound. When set to ``False``1187(default), the method returns the current value.11881189EXAMPLE::11901191sage: from sage.numerical.backends.generic_backend import get_solver1192sage: p = get_solver(solver = "CPLEX") # optional - CPLEX1193sage: p.add_variable() # optional - CPLEX119401195sage: p.col_bounds(0) # optional - CPLEX1196(0.0, None)1197sage: p.variable_upper_bound(0, 5) # optional - CPLEX1198sage: p.col_bounds(0) # optional - CPLEX1199(0.0, 5.0)1200"""1201cdef int status1202cdef double ub1203cdef char x1204cdef double c_value12051206if value == False:12071208status = CPXgetub(self.env, self.lp, &ub, index, index)1209check(status)12101211return ub if ub < int(CPX_INFBOUND) else None12121213else:12141215x = 'U'1216c_value = value if value is not None else +CPX_INFBOUND1217status = CPXchgbds(self.env, self.lp, 1, &index, &x, &c_value)1218check(status)12191220cpdef variable_lower_bound(self, int index, value = False):1221r"""1222Returns or defines the lower bound on a variable12231224INPUT:12251226- ``index`` (integer) -- the variable's id12271228- ``value`` -- real value, or ``None`` to mean that the1229variable has not lower bound. When set to ``False``1230(default), the method returns the current value.12311232EXAMPLE::12331234sage: from sage.numerical.backends.generic_backend import get_solver1235sage: p = get_solver(solver = "CPLEX") # optional - CPLEX1236sage: p.add_variable() # optional - CPLEX123701238sage: p.col_bounds(0) # optional - CPLEX1239(0.0, None)1240sage: p.variable_lower_bound(0, 5) # optional - CPLEX1241sage: p.col_bounds(0) # optional - CPLEX1242(5.0, None)1243"""1244cdef int status1245cdef double lb1246cdef char x1247cdef double c_value12481249if value == False:1250status = CPXgetlb(self.env, self.lp, &lb, index, index)1251check(status)1252return None if lb <= int(-CPX_INFBOUND) else lb12531254else:1255x = 'L'1256c_value = value if value is not None else -CPX_INFBOUND1257status = CPXchgbds(self.env, self.lp, 1, &index, &x, &c_value)1258check(status)12591260cpdef write_lp(self, char * filename):1261r"""1262Writes the problem to a .lp file12631264INPUT:12651266- ``filename`` (string)12671268EXAMPLE::12691270sage: from sage.numerical.backends.generic_backend import get_solver1271sage: p = get_solver(solver = "CPLEX") # optional - CPLEX1272sage: p.add_variables(2) # optional - CPLEX127311274sage: p.add_linear_constraint([(0, 1), (1, 2)], None, 3) # optional - CPLEX1275sage: p.set_objective([2, 5]) # optional - CPLEX1276sage: p.write_lp(SAGE_TMP+"/lp_problem.lp") # optional - CPLEX1277"""12781279cdef int status1280cdef char * ext = "LP"1281status = CPXwriteprob(self.env, self.lp, filename, ext)1282check(status)12831284cpdef write_mps(self, char * filename, int modern):1285r"""1286Writes the problem to a .mps file12871288INPUT:12891290- ``filename`` (string)12911292EXAMPLE::12931294sage: from sage.numerical.backends.generic_backend import get_solver1295sage: p = get_solver(solver = "CPLEX") # optional - CPLEX1296sage: p.add_variables(2) # optional - CPLEX129711298sage: p.add_linear_constraint([(0, 1), (1, 2)], None, 3) # optional - CPLEX1299sage: p.set_objective([2, 5]) # optional - CPLEX1300sage: p.write_lp(SAGE_TMP+"/lp_problem.lp") # optional - CPLEX1301"""13021303cdef int status1304cdef char * ext = "MPS"1305status = CPXwriteprob(self.env, self.lp, filename, ext)1306check(status)13071308cpdef CPLEXBackend copy(self):1309r"""1310Returns a copy of self.13111312EXAMPLE::13131314sage: from sage.numerical.backends.generic_backend import get_solver1315sage: p = MixedIntegerLinearProgram(solver = "CPLEX") # optional - CPLEX1316sage: b = p.new_variable() # optional - CPLEX1317sage: p.add_constraint(b[1] + b[2] <= 6) # optional - CPLEX1318sage: p.set_objective(b[1] + b[2]) # optional - CPLEX1319sage: copy(p).solve() # optional - CPLEX13206.01321"""1322cdef CPLEXBackend p = CPLEXBackend()13231324p.lp = CPXcloneprob(p.env, self.lp, &status)1325check(status)13261327p._mixed = self._mixed1328p.current_sol = self.current_sol13291330status = CPXchgprobtype(p.env, p.lp, CPXgetprobtype(self.env, self.lp))1331check(status)13321333return p13341335cpdef solver_parameter(self, name, value = None):1336"""1337Return or define a solver parameter13381339INPUT:13401341- ``name`` (string) -- the parameter13421343- ``value`` -- the parameter's value if it is to be defined,1344or ``None`` (default) to obtain its current value.13451346.. NOTE::13471348The list of available parameters is available at1349:meth:`sage.numerical.mip.MixedIntegerlinearProgram.solver_parameter`13501351EXAMPLE::13521353sage: from sage.numerical.backends.generic_backend import get_solver1354sage: p = get_solver(solver = "CPLEX") # optional - CPLEX1355sage: p.solver_parameter("timelimit", 60) # optional - CPLEX1356sage: p.solver_parameter("timelimit") # optional - CPLEX135760.01358"""1359cdef int intv1360cdef double doublev1361cdef char * strv13621363# If the name has to be translated to a CPLEX parameter ID1364if name == "timelimit":1365name = "CPX_PARAM_TILIM"13661367cdef int paramid = parameters.get(name,-1)13681369if paramid == -1:1370raise ValueError("This parameter is not available.")13711372# Type of the parameter. Can be INT (1), Double(2) or String(3)1373cdef int paramtype1374CPXgetparamtype(self.env, paramid, ¶mtype)13751376if value is None:1377if paramtype == 1:1378CPXgetintparam(self.env, paramid, &intv)1379return intv1380elif paramtype == 2:1381CPXgetdblparam(self.env, paramid, &doublev)1382return doublev1383else:1384strv = <char *>sage_malloc(500*sizeof(char))1385CPXgetstrparam(self.env, paramid, strv)1386s = str(strv)1387sage_free(strv)1388return s1389else:1390if paramtype == 1:1391CPXsetintparam(self.env, paramid, value)1392elif paramtype == 2:1393CPXsetdblparam(self.env, paramid, value)1394else:1395CPXsetstrparam(self.env, paramid, value)13961397def __dealloc__(self):1398r"""1399Destructor for the class1400"""1401cdef int status14021403if self.lp != NULL:1404status = CPXfreeprob(self.env, &self.lp)14051406if self.env != NULL:1407status = CPXcloseCPLEX(&self.env)14081409cdef check(number):1410r"""1411Given a number, raises the corresponding exception or does nothing1412if ``number == 0``.14131414- ``number`` (integer) -- number corresponding to the error. If1415this number is unknown, the message contained in the raised1416exception will mention it.1417"""14181419# Below 1000 are 0 (no error), and some quality reports (but the1420# ERR* codes are above 1000)1421if number > 1000:1422from sage.numerical.mip import MIPSolverException1423default = "Error reported by the solver (unknown error number : "+str(number)+")"1424raise MIPSolverException("CPLEX: "+errors.get(number,default))14251426# Error codes1427#1428# Todo : when common error codes are returned, rewrite the message to1429# be more meaningful14301431cdef dict errors14321433errors = {14341001 : "CPXERR_NO_MEMORY",14351002 : "CPXERR_NO_ENVIRONMENT",14361003 : "CPXERR_BAD_ARGUMENT",14371004 : "CPXERR_NULL_POINTER",14381006 : "CPXERR_CALLBACK",14391009 : "CPXERR_NO_PROBLEM",14401012 : "CPXERR_LIMITS_TOO_BIG",14411013 : "CPXERR_BAD_PARAM_NUM",14421014 : "CPXERR_PARAM_TOO_SMALL",14431015 : "CPXERR_PARAM_TOO_BIG",14441016 : "CPXERR_RESTRICTED_VERSION",14451017 : "CPXERR_NOT_FOR_MIP",14461018 : "CPXERR_NOT_FOR_QP",14471019 : "CPXERR_CHILD_OF_CHILD",14481020 : "CPXERR_TOO_MANY_THREADS",14491021 : "CPXERR_CANT_CLOSE_CHILD",14501022 : "CPXERR_BAD_PROB_TYPE",14511023 : "CPXERR_NOT_ONE_PROBLEM",14521024 : "CPXERR_NOT_MILPCLASS",14531026 : "CPXERR_STR_PARAM_TOO_LONG",14541027 : "CPXERR_DECOMPRESSION",14551028 : "CPXERR_BAD_PARAM_NAME",14561029 : "CPXERR_NOT_MIQPCLASS",14571031 : "CPXERR_NOT_FOR_QCP",14581051 : "CPXERR_MSG_NO_CHANNEL",14591052 : "CPXERR_MSG_NO_FILEPTR",14601053 : "CPXERR_MSG_NO_FUNCTION",14611101 : "CPXERR_PRESLV_INForUNBD",14621103 : "CPXERR_PRESLV_NO_PROB",14631106 : "CPXERR_PRESLV_ABORT",14641107 : "CPXERR_PRESLV_BASIS_MEM",14651108 : "CPXERR_PRESLV_COPYSOS",14661109 : "CPXERR_PRESLV_COPYORDER",14671110 : "CPXERR_PRESLV_SOLN_MIP",14681111 : "CPXERR_PRESLV_SOLN_QP",14691112 : "CPXERR_PRESLV_START_LP",14701114 : "CPXERR_PRESLV_FAIL_BASIS",14711115 : "CPXERR_PRESLV_NO_BASIS",14721117 : "CPXERR_PRESLV_INF",14731118 : "CPXERR_PRESLV_UNBD",14741119 : "CPXERR_PRESLV_DUAL",14751120 : "CPXERR_PRESLV_UNCRUSHFORM",14761121 : "CPXERR_PRESLV_CRUSHFORM",14771122 : "CPXERR_PRESLV_BAD_PARAM",14781123 : "CPXERR_PRESLV_TIME_LIM",14791200 : "CPXERR_INDEX_RANGE",14801201 : "CPXERR_COL_INDEX_RANGE",14811203 : "CPXERR_ROW_INDEX_RANGE",14821205 : "CPXERR_INDEX_RANGE_LOW",14831206 : "CPXERR_INDEX_RANGE_HIGH",14841207 : "CPXERR_NEGATIVE_SURPLUS",14851208 : "CPXERR_ARRAY_TOO_LONG",14861209 : "CPXERR_NAME_CREATION",14871210 : "CPXERR_NAME_NOT_FOUND",14881211 : "CPXERR_NO_RHS_IN_OBJ",14891215 : "CPXERR_BAD_SENSE",14901216 : "CPXERR_NO_RNGVAL",14911217 : "CPXERR_NO_SOLN",14921219 : "CPXERR_NO_NAMES",14931221 : "CPXERR_NOT_FIXED",14941222 : "CPXERR_DUP_ENTRY",14951223 : "CPXERR_NO_BARRIER_SOLN",14961224 : "CPXERR_NULL_NAME",14971225 : "CPXERR_NAN",14981226 : "CPXERR_ARRAY_NOT_ASCENDING",14991227 : "CPXERR_COUNT_RANGE",15001228 : "CPXERR_COUNT_OVERLAP",15011229 : "CPXERR_BAD_LUB",15021230 : "CPXERR_NODE_INDEX_RANGE",15031231 : "CPXERR_ARC_INDEX_RANGE",15041232 : "CPXERR_NO_DUAL_SOLN",15051233 : "CPXERR_DBL_MAX",15061234 : "CPXERR_THREAD_FAILED",15071251 : "CPXERR_INDEX_NOT_BASIC",15081252 : "CPXERR_NEED_OPT_SOLN",15091253 : "CPXERR_BAD_STATUS",15101254 : "CPXERR_NOT_UNBOUNDED",15111255 : "CPXERR_SBASE_INCOMPAT",15121256 : "CPXERR_SINGULAR",15131257 : "CPXERR_PRIIND",15141258 : "CPXERR_NO_LU_FACTOR",15151260 : "CPXERR_NO_SENSIT",15161261 : "CPXERR_NO_BASIC_SOLN",15171262 : "CPXERR_NO_BASIS",15181263 : "CPXERR_ABORT_STRONGBRANCH",15191264 : "CPXERR_NO_NORMS",15201265 : "CPXERR_NOT_DUAL_UNBOUNDED",15211266 : "CPXERR_TILIM_STRONGBRANCH",15221267 : "CPXERR_BAD_PIVOT",15231268 : "CPXERR_TILIM_CONDITION_NO",15241292 : "CPXERR_BAD_METHOD",15251421 : "CPXERR_NO_FILENAME",15261422 : "CPXERR_FAIL_OPEN_WRITE",15271423 : "CPXERR_FAIL_OPEN_READ",15281424 : "CPXERR_BAD_FILETYPE",15291425 : "CPXERR_XMLPARSE",15301431 : "CPXERR_TOO_MANY_ROWS",15311432 : "CPXERR_TOO_MANY_COLS",15321433 : "CPXERR_TOO_MANY_COEFFS",15331434 : "CPXERR_BAD_NUMBER",15341435 : "CPXERR_BAD_EXPO_RANGE",15351436 : "CPXERR_NO_OBJ_SENSE",15361437 : "CPXERR_QCP_SENSE_FILE",15371438 : "CPXERR_BAD_LAZY_UCUT",15381439 : "CPXERR_BAD_INDCONSTR",15391441 : "CPXERR_NO_NAME_SECTION",15401442 : "CPXERR_BAD_SOS_TYPE",15411443 : "CPXERR_COL_ROW_REPEATS",15421444 : "CPXERR_RIM_ROW_REPEATS",15431445 : "CPXERR_ROW_REPEATS",15441446 : "CPXERR_COL_REPEATS",15451447 : "CPXERR_RIM_REPEATS",15461448 : "CPXERR_ROW_UNKNOWN",15471449 : "CPXERR_COL_UNKNOWN",15481453 : "CPXERR_NO_ROW_SENSE",15491454 : "CPXERR_EXTRA_FX_BOUND",15501455 : "CPXERR_EXTRA_FR_BOUND",15511456 : "CPXERR_EXTRA_BV_BOUND",15521457 : "CPXERR_BAD_BOUND_TYPE",15531458 : "CPXERR_UP_BOUND_REPEATS",15541459 : "CPXERR_LO_BOUND_REPEATS",15551460 : "CPXERR_NO_BOUND_TYPE",15561461 : "CPXERR_NO_QMATRIX_SECTION",15571462 : "CPXERR_BAD_SECTION_ENDATA",15581463 : "CPXERR_INT_TOO_BIG_INPUT",15591464 : "CPXERR_NAME_TOO_LONG",15601465 : "CPXERR_LINE_TOO_LONG",15611471 : "CPXERR_NO_ROWS_SECTION",15621472 : "CPXERR_NO_COLUMNS_SECTION",15631473 : "CPXERR_BAD_SECTION_BOUNDS",15641474 : "CPXERR_RANGE_SECTION_ORDER",15651475 : "CPXERR_BAD_SECTION_QMATRIX",15661476 : "CPXERR_NO_OBJECTIVE",15671477 : "CPXERR_ROW_REPEAT_PRINT",15681478 : "CPXERR_COL_REPEAT_PRINT",15691479 : "CPXERR_RIMNZ_REPEATS",15701480 : "CPXERR_EXTRA_INTORG",15711481 : "CPXERR_EXTRA_INTEND",15721482 : "CPXERR_EXTRA_SOSORG",15731483 : "CPXERR_EXTRA_SOSEND",15741484 : "CPXERR_TOO_MANY_RIMS",15751485 : "CPXERR_TOO_MANY_RIMNZ",15761486 : "CPXERR_NO_ROW_NAME",15771487 : "CPXERR_BAD_OBJ_SENSE",15781550 : "CPXERR_BAS_FILE_SHORT",15791551 : "CPXERR_BAD_INDICATOR",15801552 : "CPXERR_NO_ENDATA",15811553 : "CPXERR_FILE_ENTRIES",15821554 : "CPXERR_SBASE_ILLEGAL",15831555 : "CPXERR_BAS_FILE_SIZE",15841556 : "CPXERR_NO_VECTOR_SOLN",15851560 : "CPXERR_NOT_SAV_FILE",15861561 : "CPXERR_SAV_FILE_DATA",15871562 : "CPXERR_SAV_FILE_WRITE",15881563 : "CPXERR_FILE_FORMAT",15891602 : "CPXERR_ADJ_SIGNS",15901603 : "CPXERR_RHS_IN_OBJ",15911604 : "CPXERR_ADJ_SIGN_SENSE",15921605 : "CPXERR_QUAD_IN_ROW",15931606 : "CPXERR_ADJ_SIGN_QUAD",15941607 : "CPXERR_NO_OPERATOR",15951608 : "CPXERR_NO_OP_OR_SENSE",15961609 : "CPXERR_NO_ID_FIRST",15971610 : "CPXERR_NO_RHS_COEFF",15981611 : "CPXERR_NO_NUMBER_FIRST",15991612 : "CPXERR_NO_QUAD_EXP",16001613 : "CPXERR_QUAD_EXP_NOT_2",16011614 : "CPXERR_NO_QP_OPERATOR",16021615 : "CPXERR_NO_NUMBER",16031616 : "CPXERR_NO_ID",16041617 : "CPXERR_BAD_ID",16051618 : "CPXERR_BAD_EXPONENT",16061619 : "CPXERR_Q_DIVISOR",16071621 : "CPXERR_NO_BOUND_SENSE",16081622 : "CPXERR_BAD_BOUND_SENSE",16091623 : "CPXERR_NO_NUMBER_BOUND",16101627 : "CPXERR_NO_SOS_SEPARATOR",16111650 : "CPXERR_INVALID_NUMBER",16121660 : "CPXERR_PRM_DATA",16131661 : "CPXERR_PRM_HEADER",16141719 : "CPXERR_NO_CONFLICT",16151720 : "CPXERR_CONFLICT_UNSTABLE",16161801 : "CPXERR_WORK_FILE_OPEN",16171802 : "CPXERR_WORK_FILE_READ",16181803 : "CPXERR_WORK_FILE_WRITE",16191804 : "CPXERR_IN_INFOCALLBACK",16201805 : "CPXERR_MIPSEARCH_WITH_CALLBACKS",16211806 : "CPXERR_LP_NOT_IN_ENVIRONMENT",16221807 : "CPXERR_PARAM_INCOMPATIBLE",162332000 : "CPXERR_LICENSE_MIN",162432201 : "CPXERR_ILOG_LICENSE",162532301 : "CPXERR_NO_MIP_LIC",162632302 : "CPXERR_NO_BARRIER_LIC",162732305 : "CPXERR_NO_MIQP_LIC",162832018 : "CPXERR_BADLDWID",162932023 : "CPXERR_BADPRODUCT",163032024 : "CPXERR_ALGNOTLICENSED",163132999 : "CPXERR_LICENSE_MAX",16321701 : "CPXERR_IIS_NO_INFO",16331702 : "CPXERR_IIS_NO_SOLN",16341703 : "CPXERR_IIS_FEAS",16351704 : "CPXERR_IIS_NOT_INFEAS",16361705 : "CPXERR_IIS_OPT_INFEAS",16371706 : "CPXERR_IIS_DEFAULT",16381707 : "CPXERR_IIS_NO_BASIC",16391709 : "CPXERR_IIS_NO_LOAD",16401710 : "CPXERR_IIS_SUB_OBJ_LIM",16411711 : "CPXERR_IIS_SUB_IT_LIM",16421712 : "CPXERR_IIS_SUB_TIME_LIM",16431713 : "CPXERR_IIS_NUM_BEST",16441714 : "CPXERR_IIS_SUB_ABORT",16453003 : "CPXERR_NOT_MIP",16463006 : "CPXERR_BAD_PRIORITY",16473007 : "CPXERR_ORDER_BAD_DIRECTION",16483009 : "CPXERR_ARRAY_BAD_SOS_TYPE",16493010 : "CPXERR_UNIQUE_WEIGHTS",16503012 : "CPXERR_BAD_DIRECTION",16513015 : "CPXERR_NO_SOS",16523016 : "CPXERR_NO_ORDER",16533018 : "CPXERR_INT_TOO_BIG",16543019 : "CPXERR_SUBPROB_SOLVE",16553020 : "CPXERR_NO_MIPSTART",16563021 : "CPXERR_BAD_CTYPE",16573023 : "CPXERR_NO_INT_X",16583024 : "CPXERR_NO_SOLNPOOL",16593301 : "CPXERR_MISS_SOS_TYPE",16603412 : "CPXERR_NO_TREE",16613413 : "CPXERR_TREE_MEMORY_LIMIT",16623414 : "CPXERR_FILTER_VARIABLE_TYPE",16633504 : "CPXERR_NODE_ON_DISK",16643601 : "CPXERR_PTHREAD_MUTEX_INIT",16653603 : "CPXERR_PTHREAD_CREATE",16661212 : "CPXERR_UNSUPPORTED_CONSTRAINT_TYPE",16671213 : "CPXERR_ILL_DEFINED_PWL",16681530 : "CPXERR_NET_DATA",16691531 : "CPXERR_NOT_MIN_COST_FLOW",16701532 : "CPXERR_BAD_ROW_ID",16711537 : "CPXERR_BAD_CHAR",16721538 : "CPXERR_NET_FILE_SHORT",16735002 : "CPXERR_Q_NOT_POS_DEF",16745004 : "CPXERR_NOT_QP",16755011 : "CPXERR_Q_DUP_ENTRY",16765012 : "CPXERR_Q_NOT_SYMMETRIC",16775014 : "CPXERR_Q_NOT_INDEF",16786002 : "CPXERR_QCP_SENSE"1679}16801681cdef dict parameters1682parameters = {1683"CPX_PARAMTYPE_NONE" : 0,1684"CPX_PARAMTYPE_INT" : 1,1685"CPX_PARAMTYPE_DOUBLE" : 2,1686"CPX_PARAMTYPE_STRING" : 3,1687"CPX_PARAM_ADVIND" : 1001,1688"CPX_PARAM_AGGFILL" : 1002,1689"CPX_PARAM_AGGIND" : 1003,1690"CPX_PARAM_BASINTERVAL" : 1004,1691"CPX_PARAM_CFILEMUL" : 1005,1692"CPX_PARAM_CLOCKTYPE" : 1006,1693"CPX_PARAM_CRAIND" : 1007,1694"CPX_PARAM_DEPIND" : 1008,1695"CPX_PARAM_DPRIIND" : 1009,1696"CPX_PARAM_PRICELIM" : 1010,1697"CPX_PARAM_EPMRK" : 1013,1698"CPX_PARAM_EPOPT" : 1014,1699"CPX_PARAM_EPPER" : 1015,1700"CPX_PARAM_EPRHS" : 1016,1701"CPX_PARAM_FASTMIP" : 1017,1702"CPX_PARAM_SIMDISPLAY" : 1019,1703"CPX_PARAM_ITLIM" : 1020,1704"CPX_PARAM_ROWREADLIM" : 1021,1705"CPX_PARAM_NETFIND" : 1022,1706"CPX_PARAM_COLREADLIM" : 1023,1707"CPX_PARAM_NZREADLIM" : 1024,1708"CPX_PARAM_OBJLLIM" : 1025,1709"CPX_PARAM_OBJULIM" : 1026,1710"CPX_PARAM_PERIND" : 1027,1711"CPX_PARAM_PERLIM" : 1028,1712"CPX_PARAM_PPRIIND" : 1029,1713"CPX_PARAM_PREIND" : 1030,1714"CPX_PARAM_REINV" : 1031,1715"CPX_PARAM_REVERSEIND" : 1032,1716"CPX_PARAM_RFILEMUL" : 1033,1717"CPX_PARAM_SCAIND" : 1034,1718"CPX_PARAM_SCRIND" : 1035,1719"CPX_PARAM_SINGLIM" : 1037,1720"CPX_PARAM_SINGTOL" : 1038,1721"CPX_PARAM_TILIM" : 1039,1722"CPX_PARAM_XXXIND" : 1041,1723"CPX_PARAM_PREDUAL" : 1044,1724"CPX_PARAM_EPOPT_H" : 1049,1725"CPX_PARAM_EPRHS_H" : 1050,1726"CPX_PARAM_PREPASS" : 1052,1727"CPX_PARAM_DATACHECK" : 1056,1728"CPX_PARAM_REDUCE" : 1057,1729"CPX_PARAM_PRELINEAR" : 1058,1730"CPX_PARAM_LPMETHOD" : 1062,1731"CPX_PARAM_QPMETHOD" : 1063,1732"CPX_PARAM_WORKDIR" : 1064,1733"CPX_PARAM_WORKMEM" : 1065,1734"CPX_PARAM_THREADS" : 1067,1735"CPX_PARAM_CONFLICTDISPLAY" : 1074,1736"CPX_PARAM_SIFTDISPLAY" : 1076,1737"CPX_PARAM_SIFTALG" : 1077,1738"CPX_PARAM_SIFTITLIM" : 1078,1739"CPX_PARAM_MPSLONGNUM" : 1081,1740"CPX_PARAM_MEMORYEMPHASIS" : 1082,1741"CPX_PARAM_NUMERICALEMPHASIS" : 1083,1742"CPX_PARAM_FEASOPTMODE" : 1084,1743"CPX_PARAM_PARALLELMODE" : 1109,1744"CPX_PARAM_TUNINGMEASURE" : 1110,1745"CPX_PARAM_TUNINGREPEAT" : 1111,1746"CPX_PARAM_TUNINGTILIM" : 1112,1747"CPX_PARAM_TUNINGDISPLAY" : 1113,1748"CPX_PARAM_WRITELEVEL" : 1114,1749"CPX_PARAM_ALL_MIN" : 1000,1750"CPX_PARAM_ALL_MAX" : 6000,1751"CPX_PARAM_BARDSTART" : 3001,1752"CPX_PARAM_BAREPCOMP" : 3002,1753"CPX_PARAM_BARGROWTH" : 3003,1754"CPX_PARAM_BAROBJRNG" : 3004,1755"CPX_PARAM_BARPSTART" : 3005,1756"CPX_PARAM_BARALG" : 3007,1757"CPX_PARAM_BARCOLNZ" : 3009,1758"CPX_PARAM_BARDISPLAY" : 3010,1759"CPX_PARAM_BARITLIM" : 3012,1760"CPX_PARAM_BARMAXCOR" : 3013,1761"CPX_PARAM_BARORDER" : 3014,1762"CPX_PARAM_BARSTARTALG" : 3017,1763"CPX_PARAM_BARCROSSALG" : 3018,1764"CPX_PARAM_BARQCPEPCOMP" : 3020,1765"CPX_PARAM_BRDIR" : 2001,1766"CPX_PARAM_BTTOL" : 2002,1767"CPX_PARAM_CLIQUES" : 2003,1768"CPX_PARAM_COEREDIND" : 2004,1769"CPX_PARAM_COVERS" : 2005,1770"CPX_PARAM_CUTLO" : 2006,1771"CPX_PARAM_CUTUP" : 2007,1772"CPX_PARAM_EPAGAP" : 2008,1773"CPX_PARAM_EPGAP" : 2009,1774"CPX_PARAM_EPINT" : 2010,1775"CPX_PARAM_MIPDISPLAY" : 2012,1776"CPX_PARAM_MIPINTERVAL" : 2013,1777"CPX_PARAM_INTSOLLIM" : 2015,1778"CPX_PARAM_NODEFILEIND" : 2016,1779"CPX_PARAM_NODELIM" : 2017,1780"CPX_PARAM_NODESEL" : 2018,1781"CPX_PARAM_OBJDIF" : 2019,1782"CPX_PARAM_MIPORDIND" : 2020,1783"CPX_PARAM_RELOBJDIF" : 2022,1784"CPX_PARAM_STARTALG" : 2025,1785"CPX_PARAM_SUBALG" : 2026,1786"CPX_PARAM_TRELIM" : 2027,1787"CPX_PARAM_VARSEL" : 2028,1788"CPX_PARAM_BNDSTRENIND" : 2029,1789"CPX_PARAM_HEURFREQ" : 2031,1790"CPX_PARAM_MIPORDTYPE" : 2032,1791"CPX_PARAM_CUTSFACTOR" : 2033,1792"CPX_PARAM_RELAXPREIND" : 2034,1793"CPX_PARAM_PRESLVND" : 2037,1794"CPX_PARAM_BBINTERVAL" : 2039,1795"CPX_PARAM_FLOWCOVERS" : 2040,1796"CPX_PARAM_IMPLBD" : 2041,1797"CPX_PARAM_PROBE" : 2042,1798"CPX_PARAM_GUBCOVERS" : 2044,1799"CPX_PARAM_STRONGCANDLIM" : 2045,1800"CPX_PARAM_STRONGITLIM" : 2046,1801"CPX_PARAM_FRACCAND" : 2048,1802"CPX_PARAM_FRACCUTS" : 2049,1803"CPX_PARAM_FRACPASS" : 2050,1804"CPX_PARAM_FLOWPATHS" : 2051,1805"CPX_PARAM_MIRCUTS" : 2052,1806"CPX_PARAM_DISJCUTS" : 2053,1807"CPX_PARAM_AGGCUTLIM" : 2054,1808"CPX_PARAM_MIPCBREDLP" : 2055 ,1809"CPX_PARAM_CUTPASS" : 2056,1810"CPX_PARAM_MIPEMPHASIS" : 2058,1811"CPX_PARAM_SYMMETRY" : 2059,1812"CPX_PARAM_DIVETYPE" : 2060,1813"CPX_PARAM_RINSHEUR" : 2061,1814"CPX_PARAM_SUBMIPNODELIM" : 2062,1815"CPX_PARAM_LBHEUR" : 2063,1816"CPX_PARAM_REPEATPRESOLVE" : 2064,1817"CPX_PARAM_PROBETIME" : 2065,1818"CPX_PARAM_POLISHTIME" : 2066,1819"CPX_PARAM_REPAIRTRIES" : 2067,1820"CPX_PARAM_EPLIN" : 2068,1821"CPX_PARAM_EPRELAX" : 2073,1822"CPX_PARAM_FPHEUR" : 2098,1823"CPX_PARAM_EACHCUTLIM" : 2102,1824"CPX_PARAM_SOLNPOOLCAPACITY" : 2103 ,1825"CPX_PARAM_SOLNPOOLREPLACE" : 2104 ,1826"CPX_PARAM_SOLNPOOLGAP" : 2105 ,1827"CPX_PARAM_SOLNPOOLAGAP" : 2106 ,1828"CPX_PARAM_SOLNPOOLINTENSITY" : 2107,1829"CPX_PARAM_POPULATELIM" : 2108,1830"CPX_PARAM_MIPSEARCH" : 2109,1831"CPX_PARAM_MIQCPSTRAT" : 2110,1832"CPX_PARAM_ZEROHALFCUTS" : 2111,1833"CPX_PARAM_POLISHAFTEREPAGAP" : 2126,1834"CPX_PARAM_POLISHAFTEREPGAP" : 2127,1835"CPX_PARAM_POLISHAFTERNODE" : 2128,1836"CPX_PARAM_POLISHAFTERINTSOL" : 2129,1837"CPX_PARAM_POLISHAFTERTIME" : 2130,1838"CPX_PARAM_MCFCUTS" : 2134,1839"CPX_PARAM_NETITLIM" : 5001,1840"CPX_PARAM_NETEPOPT" : 5002,1841"CPX_PARAM_NETEPRHS" : 5003,1842"CPX_PARAM_NETPPRIIND" : 5004,1843"CPX_PARAM_NETDISPLAY" : 5005,1844"CPX_PARAM_QPNZREADLIM" : 4001,1845"CPX_PARAM_QPMAKEPSDIND" : 4010,1846}184718481849