Path: blob/master/src/sage/numerical/backends/cplex_backend.pyx
8817 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, 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 - CPLEX479"""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)825826cpdef int solve(self) except -1:827r"""828Solves the problem.829830.. NOTE::831832This method raises ``MIPSolverException`` exceptions when833the solution can not be computed for any reason (none834exists, or the LP solver was not able to find it, etc...)835836EXAMPLE::837838sage: from sage.numerical.backends.generic_backend import get_solver839sage: p = get_solver(solver = "CPLEX") # optional - CPLEX840sage: p.add_linear_constraints(5, 0, None) # optional - CPLEX841sage: p.add_col(range(5), range(5)) # optional - CPLEX842sage: p.solve() # optional - CPLEX8430844sage: p.objective_coefficient(0,1) # optional - CPLEX845sage: p.solve() # optional - CPLEX846Traceback (most recent call last):847...848MIPSolverException: ...849"""850cdef int status851cdef int ptype852cdef int solnmethod_p, solntype_p, pfeasind_p, dfeasind_p853854ptype = CPXgetprobtype(self.env, self.lp)855856if ptype == 1:857status = CPXmipopt(self.env, self.lp)858elif ptype == 0:859status = CPXlpopt(self.env, self.lp)860else:861raise MIPSolverException("CPLEX: Unknown problem type")862863check(status)864865status = CPXsolninfo(self.env, self.lp, &solnmethod_p, &solntype_p, &pfeasind_p, &dfeasind_p)866check(status)867868if solntype_p == CPX_NO_SOLN:869if not pfeasind_p:870raise MIPSolverException("CPLEX: The primal has no feasible solution")871elif not dfeasind_p:872raise MIPSolverException("CPLEX: The problem is unbounded")873else:874raise MIPSolverException("CPLEX: No solution has been found, but no idea why")875876return 0877878cpdef get_objective_value(self):879r"""880Returns the value of the objective function.881882.. NOTE::883884Has no meaning unless ``solve`` has been called before.885886EXAMPLE::887888sage: from sage.numerical.backends.generic_backend import get_solver889sage: p = get_solver(solver = "CPLEX") # optional - CPLEX890sage: p.add_variables(2) # optional - CPLEX8911892sage: p.add_linear_constraint([(0,1), (1,2)], None, 3) # optional - CPLEX893sage: p.set_objective([2, 5]) # optional - CPLEX894sage: p.solve() # optional - CPLEX8950896sage: p.get_objective_value() # optional - CPLEX8977.5898sage: p.get_variable_value(0) # optional - CPLEX8990.0900sage: p.get_variable_value(1) # optional - CPLEX9011.5902"""903904cdef int status905cdef double value906status = CPXgetobjval (self.env, self.lp, &value)907check(status)908909return value + self.obj_constant_term910911912cpdef get_variable_value(self, int variable):913r"""914Returns the value of a variable given by the solver.915916.. NOTE::917918Has no meaning unless ``solve`` has been called before.919920EXAMPLE::921922sage: from sage.numerical.backends.generic_backend import get_solver923sage: p = get_solver(solver = "CPLEX") # optional - CPLEX924sage: p.add_variables(2) # optional - CPLEX9251926sage: p.add_linear_constraint([(0,1), (1,2)], None, 3) # optional - CPLEX927sage: p.set_objective([2, 5]) # optional - CPLEX928sage: p.solve() # optional - CPLEX9290930sage: p.get_objective_value() # optional - CPLEX9317.5932sage: p.get_variable_value(0) # optional - CPLEX9330.0934sage: p.get_variable_value(1) # optional - CPLEX9351.5936"""937938cdef int status939cdef int zero940cdef char ctype941cdef double value942status = CPXgetx(self.env, self.lp, &value, variable, variable)943check(status)944945status = CPXgetctype(self.env, self.lp, &ctype, variable, variable)946947return value if (status == 3003 or ctype=='C') else round(value)948949cpdef int ncols(self):950r"""951Returns the number of columns/variables.952953EXAMPLE::954955sage: from sage.numerical.backends.generic_backend import get_solver956sage: p = get_solver(solver = "CPLEX") # optional - CPLEX957sage: p.ncols() # optional - CPLEX9580959sage: p.add_variables(2) # optional - CPLEX9601961sage: p.ncols() # optional - CPLEX9622963"""964965return CPXgetnumcols(self.env, self.lp)966967cpdef int nrows(self):968r"""969Returns the number of rows/constraints.970971EXAMPLE::972973sage: from sage.numerical.backends.generic_backend import get_solver974sage: p = get_solver(solver = "CPLEX") # optional - CPLEX975sage: p.nrows() # optional - CPLEX9760977sage: p.add_linear_constraints(2, 2, None) # optional - CPLEX978sage: p.nrows() # optional - CPLEX9792980"""981982return CPXgetnumrows(self.env, self.lp)983984cpdef row_name(self, int index):985r"""986Return the ``index`` th row name987988INPUT:989990- ``index`` (integer) -- the row's id991992EXAMPLE::993994sage: from sage.numerical.backends.generic_backend import get_solver995sage: p = get_solver(solver = "CPLEX") # optional - CPLEX996sage: p.add_linear_constraints(1, 2, None, names=['Empty constraint 1']) # optional - CPLEX997sage: p.row_name(0) # optional - CPLEX998'Empty constraint 1'999"""10001001cdef int status1002cdef int zero1003cdef char * n10041005n = <char *>sage_malloc(500*sizeof(char))1006status = CPXgetrowname(self.env, self.lp, &n, n, 500, &zero, index, index)1007if status == 1219:1008sage_free(n)1009return ""1010check(status)10111012s = str(n)1013sage_free(n)10141015return s10161017cpdef col_name(self, int index):1018r"""1019Returns the ``index`` th col name.10201021INPUT:10221023- ``index`` (integer) -- the col's id10241025EXAMPLE::10261027sage: from sage.numerical.backends.generic_backend import get_solver1028sage: p = get_solver(solver = "CPLEX") # optional - CPLEX1029sage: p.add_variable(name='I am a variable') # optional - CPLEX103001031sage: p.col_name(0) # optional - CPLEX1032'I am a variable'1033"""10341035cdef int status1036cdef char * n1037cdef int zero10381039n = <char *>sage_malloc(500*sizeof(char))1040status = CPXgetcolname(self.env, self.lp, &n, n, 500, &zero, index, index)1041if status == 1219:1042sage_free(n)1043return ""1044check(status)10451046s = str(n)1047sage_free(n)1048return s10491050cpdef bint is_variable_binary(self, int index):1051r"""1052Tests whether the given variable is of binary type.10531054INPUT:10551056- ``index`` (integer) -- the variable's id10571058EXAMPLE::10591060sage: from sage.numerical.backends.generic_backend import get_solver1061sage: p = get_solver(solver = "CPLEX") # optional - CPLEX1062sage: p.ncols() # optional - CPLEX106301064sage: p.add_variable() # optional - CPLEX106501066sage: p.set_variable_type(0,0) # optional - CPLEX1067sage: p.is_variable_binary(0) # optional - CPLEX1068True10691070"""10711072cdef int status1073cdef char ctype10741075status = CPXgetctype(self.env, self.lp, &ctype, index, index)10761077# status = 3003 when the problem is a LP and not a MILP1078if status == 3003:1079return False10801081check(status)10821083return ctype == 'B'108410851086cpdef bint is_variable_integer(self, int index):1087r"""1088Tests whether the given variable is of integer type.10891090INPUT:10911092- ``index`` (integer) -- the variable's id10931094EXAMPLE::10951096sage: from sage.numerical.backends.generic_backend import get_solver1097sage: p = get_solver(solver = "CPLEX") # optional - CPLEX1098sage: p.ncols() # optional - CPLEX109901100sage: p.add_variable() # optional - CPLEX110101102sage: p.set_variable_type(0,1) # optional - CPLEX1103sage: p.is_variable_integer(0) # optional - CPLEX1104True1105"""11061107cdef int status1108cdef char ctype11091110status = CPXgetctype(self.env, self.lp, &ctype, index, index)11111112# status = 3003 when the problem is a LP and not a MILP1113if status == 3003:1114return False11151116check(status)11171118return ctype == 'I'111911201121cpdef bint is_variable_continuous(self, int index):1122r"""1123Tests whether the given variable is of continuous/real type.11241125INPUT:11261127- ``index`` (integer) -- the variable's id11281129EXAMPLE::11301131sage: from sage.numerical.backends.generic_backend import get_solver1132sage: p = get_solver(solver = "CPLEX") # optional - CPLEX1133sage: p.ncols() # optional - CPLEX113401135sage: p.add_variable() # optional - CPLEX113601137sage: p.is_variable_continuous(0) # optional - CPLEX1138True1139sage: p.set_variable_type(0,1) # optional - CPLEX1140sage: p.is_variable_continuous(0) # optional - CPLEX1141False11421143"""11441145cdef int status1146cdef char ctype11471148status = CPXgetctype(self.env, self.lp, &ctype, index, index)11491150# status = 3003 when the problem is a LP and not a MILP1151if status == 3003:1152return True11531154check(status)11551156return ctype == 'C'115711581159cpdef bint is_maximization(self):1160r"""1161Tests whether the problem is a maximization11621163EXAMPLE::11641165sage: from sage.numerical.backends.generic_backend import get_solver1166sage: p = get_solver(solver = "CPLEX") # optional - CPLEX1167sage: p.is_maximization() # optional - CPLEX1168True1169sage: p.set_sense(-1) # optional - CPLEX1170sage: p.is_maximization() # optional - CPLEX1171False1172"""11731174return -1 == CPXgetobjsen(self.env, self.lp)11751176cpdef variable_upper_bound(self, int index, value = False):1177r"""1178Returns or defines the upper bound on a variable11791180INPUT:11811182- ``index`` (integer) -- the variable's id11831184- ``value`` -- real value, or ``None`` to mean that the1185variable has not upper bound. When set to ``False``1186(default), the method returns the current value.11871188EXAMPLE::11891190sage: from sage.numerical.backends.generic_backend import get_solver1191sage: p = get_solver(solver = "CPLEX") # optional - CPLEX1192sage: p.add_variable() # optional - CPLEX119301194sage: p.col_bounds(0) # optional - CPLEX1195(0.0, None)1196sage: p.variable_upper_bound(0, 5) # optional - CPLEX1197sage: p.col_bounds(0) # optional - CPLEX1198(0.0, 5.0)11991200TESTS:12011202:trac:`14581`::12031204sage: P = MixedIntegerLinearProgram(solver="CPLEX") # optional - CPLEX1205sage: x = P["x"] # optional - CPLEX1206sage: P.set_max(x, 0) # optional - CPLEX1207sage: P.get_max(x) # optional - CPLEX12080.01209"""1210cdef int status1211cdef double ub1212cdef char x1213cdef double c_value12141215if value is False:1216status = CPXgetub(self.env, self.lp, &ub, index, index)1217check(status)12181219return ub if ub < int(CPX_INFBOUND) else None12201221else:1222x = 'U'1223c_value = value if value is not None else +CPX_INFBOUND1224status = CPXchgbds(self.env, self.lp, 1, &index, &x, &c_value)1225check(status)12261227cpdef variable_lower_bound(self, int index, value = False):1228r"""1229Returns or defines the lower bound on a variable12301231INPUT:12321233- ``index`` (integer) -- the variable's id12341235- ``value`` -- real value, or ``None`` to mean that the1236variable has not lower bound. When set to ``False``1237(default), the method returns the current value.12381239EXAMPLE::12401241sage: from sage.numerical.backends.generic_backend import get_solver1242sage: p = get_solver(solver = "CPLEX") # optional - CPLEX1243sage: p.add_variable() # optional - CPLEX124401245sage: p.col_bounds(0) # optional - CPLEX1246(0.0, None)1247sage: p.variable_lower_bound(0, 5) # optional - CPLEX1248sage: p.col_bounds(0) # optional - CPLEX1249(5.0, None)12501251TESTS:12521253:trac:`14581`::12541255sage: P = MixedIntegerLinearProgram(solver="CPLEX") # optional - CPLEX1256sage: x = P["x"] # optional - CPLEX1257sage: P.set_min(x, 5) # optional - CPLEX1258sage: P.set_min(x, 0) # optional - CPLEX1259sage: P.get_min(x) # optional - CPLEX12600.01261"""1262cdef int status1263cdef double lb1264cdef char x1265cdef double c_value12661267if value is False:1268status = CPXgetlb(self.env, self.lp, &lb, index, index)1269check(status)1270return None if lb <= int(-CPX_INFBOUND) else lb12711272else:1273x = 'L'1274c_value = value if value is not None else -CPX_INFBOUND1275status = CPXchgbds(self.env, self.lp, 1, &index, &x, &c_value)1276check(status)12771278cpdef write_lp(self, char * filename):1279r"""1280Writes the problem to a .lp file12811282INPUT:12831284- ``filename`` (string)12851286EXAMPLE::12871288sage: from sage.numerical.backends.generic_backend import get_solver1289sage: p = get_solver(solver = "CPLEX") # optional - CPLEX1290sage: p.add_variables(2) # optional - CPLEX129111292sage: p.add_linear_constraint([(0, 1), (1, 2)], None, 3) # optional - CPLEX1293sage: p.set_objective([2, 5]) # optional - CPLEX1294sage: p.write_lp(os.path.join(SAGE_TMP, "lp_problem.lp")) # optional - CPLEX1295"""12961297cdef int status1298cdef char * ext = "LP"1299status = CPXwriteprob(self.env, self.lp, filename, ext)1300check(status)13011302cpdef write_mps(self, char * filename, int modern):1303r"""1304Writes the problem to a .mps file13051306INPUT:13071308- ``filename`` (string)13091310EXAMPLE::13111312sage: from sage.numerical.backends.generic_backend import get_solver1313sage: p = get_solver(solver = "CPLEX") # optional - CPLEX1314sage: p.add_variables(2) # optional - CPLEX131511316sage: p.add_linear_constraint([(0, 1), (1, 2)], None, 3) # optional - CPLEX1317sage: p.set_objective([2, 5]) # optional - CPLEX1318sage: p.write_lp(os.path.join(SAGE_TMP, "lp_problem.lp")) # optional - CPLEX1319"""13201321cdef int status1322cdef char * ext = "MPS"1323status = CPXwriteprob(self.env, self.lp, filename, ext)1324check(status)13251326cpdef CPLEXBackend copy(self):1327r"""1328Returns a copy of self.13291330EXAMPLE::13311332sage: from sage.numerical.backends.generic_backend import get_solver1333sage: p = MixedIntegerLinearProgram(solver = "CPLEX") # optional - CPLEX1334sage: b = p.new_variable() # optional - CPLEX1335sage: p.add_constraint(b[1] + b[2] <= 6) # optional - CPLEX1336sage: p.set_objective(b[1] + b[2]) # optional - CPLEX1337sage: copy(p).solve() # optional - CPLEX13386.01339"""1340cdef CPLEXBackend p = CPLEXBackend()13411342p.lp = CPXcloneprob(p.env, self.lp, &status)1343check(status)13441345p._mixed = self._mixed1346p.current_sol = self.current_sol13471348status = CPXchgprobtype(p.env, p.lp, CPXgetprobtype(self.env, self.lp))1349check(status)13501351return p13521353cpdef solver_parameter(self, name, value = None):1354"""1355Return or define a solver parameter13561357INPUT:13581359- ``name`` (string) -- the parameter13601361- ``value`` -- the parameter's value if it is to be defined,1362or ``None`` (default) to obtain its current value.13631364.. NOTE::13651366The list of available parameters is available at1367:meth:`sage.numerical.mip.MixedIntegerlinearProgram.solver_parameter`13681369EXAMPLE::13701371sage: from sage.numerical.backends.generic_backend import get_solver1372sage: p = get_solver(solver = "CPLEX") # optional - CPLEX1373sage: p.solver_parameter("timelimit", 60) # optional - CPLEX1374sage: p.solver_parameter("timelimit") # optional - CPLEX137560.01376"""1377cdef int intv1378cdef double doublev1379cdef char * strv13801381# If the name has to be translated to a CPLEX parameter ID1382if name == "timelimit":1383name = "CPX_PARAM_TILIM"13841385cdef int paramid = parameters.get(name,-1)13861387if paramid == -1:1388raise ValueError("This parameter is not available.")13891390# Type of the parameter. Can be INT (1), Double(2) or String(3)1391cdef int paramtype1392CPXgetparamtype(self.env, paramid, ¶mtype)13931394if value is None:1395if paramtype == 1:1396CPXgetintparam(self.env, paramid, &intv)1397return intv1398elif paramtype == 2:1399CPXgetdblparam(self.env, paramid, &doublev)1400return doublev1401else:1402strv = <char *>sage_malloc(500*sizeof(char))1403CPXgetstrparam(self.env, paramid, strv)1404s = str(strv)1405sage_free(strv)1406return s1407else:1408if paramtype == 1:1409CPXsetintparam(self.env, paramid, value)1410elif paramtype == 2:1411CPXsetdblparam(self.env, paramid, value)1412else:1413CPXsetstrparam(self.env, paramid, value)14141415def __dealloc__(self):1416r"""1417Destructor for the class1418"""1419cdef int status14201421if self.lp != NULL:1422status = CPXfreeprob(self.env, &self.lp)14231424if self.env != NULL:1425status = CPXcloseCPLEX(&self.env)14261427cdef check(number):1428r"""1429Given a number, raises the corresponding exception or does nothing1430if ``number == 0``.14311432- ``number`` (integer) -- number corresponding to the error. If1433this number is unknown, the message contained in the raised1434exception will mention it.1435"""14361437# Below 1000 are 0 (no error), and some quality reports (but the1438# ERR* codes are above 1000)1439if number > 1000:1440from sage.numerical.mip import MIPSolverException1441default = "Error reported by the solver (unknown error number : "+str(number)+")"1442raise MIPSolverException("CPLEX: "+errors.get(number,default))14431444# Error codes1445#1446# Todo : when common error codes are returned, rewrite the message to1447# be more meaningful14481449cdef dict errors14501451errors = {14521001 : "CPXERR_NO_MEMORY",14531002 : "CPXERR_NO_ENVIRONMENT",14541003 : "CPXERR_BAD_ARGUMENT",14551004 : "CPXERR_NULL_POINTER",14561006 : "CPXERR_CALLBACK",14571009 : "CPXERR_NO_PROBLEM",14581012 : "CPXERR_LIMITS_TOO_BIG",14591013 : "CPXERR_BAD_PARAM_NUM",14601014 : "CPXERR_PARAM_TOO_SMALL",14611015 : "CPXERR_PARAM_TOO_BIG",14621016 : "CPXERR_RESTRICTED_VERSION",14631017 : "CPXERR_NOT_FOR_MIP",14641018 : "CPXERR_NOT_FOR_QP",14651019 : "CPXERR_CHILD_OF_CHILD",14661020 : "CPXERR_TOO_MANY_THREADS",14671021 : "CPXERR_CANT_CLOSE_CHILD",14681022 : "CPXERR_BAD_PROB_TYPE",14691023 : "CPXERR_NOT_ONE_PROBLEM",14701024 : "CPXERR_NOT_MILPCLASS",14711026 : "CPXERR_STR_PARAM_TOO_LONG",14721027 : "CPXERR_DECOMPRESSION",14731028 : "CPXERR_BAD_PARAM_NAME",14741029 : "CPXERR_NOT_MIQPCLASS",14751031 : "CPXERR_NOT_FOR_QCP",14761051 : "CPXERR_MSG_NO_CHANNEL",14771052 : "CPXERR_MSG_NO_FILEPTR",14781053 : "CPXERR_MSG_NO_FUNCTION",14791101 : "CPXERR_PRESLV_INForUNBD",14801103 : "CPXERR_PRESLV_NO_PROB",14811106 : "CPXERR_PRESLV_ABORT",14821107 : "CPXERR_PRESLV_BASIS_MEM",14831108 : "CPXERR_PRESLV_COPYSOS",14841109 : "CPXERR_PRESLV_COPYORDER",14851110 : "CPXERR_PRESLV_SOLN_MIP",14861111 : "CPXERR_PRESLV_SOLN_QP",14871112 : "CPXERR_PRESLV_START_LP",14881114 : "CPXERR_PRESLV_FAIL_BASIS",14891115 : "CPXERR_PRESLV_NO_BASIS",14901117 : "CPXERR_PRESLV_INF",14911118 : "CPXERR_PRESLV_UNBD",14921119 : "CPXERR_PRESLV_DUAL",14931120 : "CPXERR_PRESLV_UNCRUSHFORM",14941121 : "CPXERR_PRESLV_CRUSHFORM",14951122 : "CPXERR_PRESLV_BAD_PARAM",14961123 : "CPXERR_PRESLV_TIME_LIM",14971200 : "CPXERR_INDEX_RANGE",14981201 : "CPXERR_COL_INDEX_RANGE",14991203 : "CPXERR_ROW_INDEX_RANGE",15001205 : "CPXERR_INDEX_RANGE_LOW",15011206 : "CPXERR_INDEX_RANGE_HIGH",15021207 : "CPXERR_NEGATIVE_SURPLUS",15031208 : "CPXERR_ARRAY_TOO_LONG",15041209 : "CPXERR_NAME_CREATION",15051210 : "CPXERR_NAME_NOT_FOUND",15061211 : "CPXERR_NO_RHS_IN_OBJ",15071215 : "CPXERR_BAD_SENSE",15081216 : "CPXERR_NO_RNGVAL",15091217 : "CPXERR_NO_SOLN",15101219 : "CPXERR_NO_NAMES",15111221 : "CPXERR_NOT_FIXED",15121222 : "CPXERR_DUP_ENTRY",15131223 : "CPXERR_NO_BARRIER_SOLN",15141224 : "CPXERR_NULL_NAME",15151225 : "CPXERR_NAN",15161226 : "CPXERR_ARRAY_NOT_ASCENDING",15171227 : "CPXERR_COUNT_RANGE",15181228 : "CPXERR_COUNT_OVERLAP",15191229 : "CPXERR_BAD_LUB",15201230 : "CPXERR_NODE_INDEX_RANGE",15211231 : "CPXERR_ARC_INDEX_RANGE",15221232 : "CPXERR_NO_DUAL_SOLN",15231233 : "CPXERR_DBL_MAX",15241234 : "CPXERR_THREAD_FAILED",15251251 : "CPXERR_INDEX_NOT_BASIC",15261252 : "CPXERR_NEED_OPT_SOLN",15271253 : "CPXERR_BAD_STATUS",15281254 : "CPXERR_NOT_UNBOUNDED",15291255 : "CPXERR_SBASE_INCOMPAT",15301256 : "CPXERR_SINGULAR",15311257 : "CPXERR_PRIIND",15321258 : "CPXERR_NO_LU_FACTOR",15331260 : "CPXERR_NO_SENSIT",15341261 : "CPXERR_NO_BASIC_SOLN",15351262 : "CPXERR_NO_BASIS",15361263 : "CPXERR_ABORT_STRONGBRANCH",15371264 : "CPXERR_NO_NORMS",15381265 : "CPXERR_NOT_DUAL_UNBOUNDED",15391266 : "CPXERR_TILIM_STRONGBRANCH",15401267 : "CPXERR_BAD_PIVOT",15411268 : "CPXERR_TILIM_CONDITION_NO",15421292 : "CPXERR_BAD_METHOD",15431421 : "CPXERR_NO_FILENAME",15441422 : "CPXERR_FAIL_OPEN_WRITE",15451423 : "CPXERR_FAIL_OPEN_READ",15461424 : "CPXERR_BAD_FILETYPE",15471425 : "CPXERR_XMLPARSE",15481431 : "CPXERR_TOO_MANY_ROWS",15491432 : "CPXERR_TOO_MANY_COLS",15501433 : "CPXERR_TOO_MANY_COEFFS",15511434 : "CPXERR_BAD_NUMBER",15521435 : "CPXERR_BAD_EXPO_RANGE",15531436 : "CPXERR_NO_OBJ_SENSE",15541437 : "CPXERR_QCP_SENSE_FILE",15551438 : "CPXERR_BAD_LAZY_UCUT",15561439 : "CPXERR_BAD_INDCONSTR",15571441 : "CPXERR_NO_NAME_SECTION",15581442 : "CPXERR_BAD_SOS_TYPE",15591443 : "CPXERR_COL_ROW_REPEATS",15601444 : "CPXERR_RIM_ROW_REPEATS",15611445 : "CPXERR_ROW_REPEATS",15621446 : "CPXERR_COL_REPEATS",15631447 : "CPXERR_RIM_REPEATS",15641448 : "CPXERR_ROW_UNKNOWN",15651449 : "CPXERR_COL_UNKNOWN",15661453 : "CPXERR_NO_ROW_SENSE",15671454 : "CPXERR_EXTRA_FX_BOUND",15681455 : "CPXERR_EXTRA_FR_BOUND",15691456 : "CPXERR_EXTRA_BV_BOUND",15701457 : "CPXERR_BAD_BOUND_TYPE",15711458 : "CPXERR_UP_BOUND_REPEATS",15721459 : "CPXERR_LO_BOUND_REPEATS",15731460 : "CPXERR_NO_BOUND_TYPE",15741461 : "CPXERR_NO_QMATRIX_SECTION",15751462 : "CPXERR_BAD_SECTION_ENDATA",15761463 : "CPXERR_INT_TOO_BIG_INPUT",15771464 : "CPXERR_NAME_TOO_LONG",15781465 : "CPXERR_LINE_TOO_LONG",15791471 : "CPXERR_NO_ROWS_SECTION",15801472 : "CPXERR_NO_COLUMNS_SECTION",15811473 : "CPXERR_BAD_SECTION_BOUNDS",15821474 : "CPXERR_RANGE_SECTION_ORDER",15831475 : "CPXERR_BAD_SECTION_QMATRIX",15841476 : "CPXERR_NO_OBJECTIVE",15851477 : "CPXERR_ROW_REPEAT_PRINT",15861478 : "CPXERR_COL_REPEAT_PRINT",15871479 : "CPXERR_RIMNZ_REPEATS",15881480 : "CPXERR_EXTRA_INTORG",15891481 : "CPXERR_EXTRA_INTEND",15901482 : "CPXERR_EXTRA_SOSORG",15911483 : "CPXERR_EXTRA_SOSEND",15921484 : "CPXERR_TOO_MANY_RIMS",15931485 : "CPXERR_TOO_MANY_RIMNZ",15941486 : "CPXERR_NO_ROW_NAME",15951487 : "CPXERR_BAD_OBJ_SENSE",15961550 : "CPXERR_BAS_FILE_SHORT",15971551 : "CPXERR_BAD_INDICATOR",15981552 : "CPXERR_NO_ENDATA",15991553 : "CPXERR_FILE_ENTRIES",16001554 : "CPXERR_SBASE_ILLEGAL",16011555 : "CPXERR_BAS_FILE_SIZE",16021556 : "CPXERR_NO_VECTOR_SOLN",16031560 : "CPXERR_NOT_SAV_FILE",16041561 : "CPXERR_SAV_FILE_DATA",16051562 : "CPXERR_SAV_FILE_WRITE",16061563 : "CPXERR_FILE_FORMAT",16071602 : "CPXERR_ADJ_SIGNS",16081603 : "CPXERR_RHS_IN_OBJ",16091604 : "CPXERR_ADJ_SIGN_SENSE",16101605 : "CPXERR_QUAD_IN_ROW",16111606 : "CPXERR_ADJ_SIGN_QUAD",16121607 : "CPXERR_NO_OPERATOR",16131608 : "CPXERR_NO_OP_OR_SENSE",16141609 : "CPXERR_NO_ID_FIRST",16151610 : "CPXERR_NO_RHS_COEFF",16161611 : "CPXERR_NO_NUMBER_FIRST",16171612 : "CPXERR_NO_QUAD_EXP",16181613 : "CPXERR_QUAD_EXP_NOT_2",16191614 : "CPXERR_NO_QP_OPERATOR",16201615 : "CPXERR_NO_NUMBER",16211616 : "CPXERR_NO_ID",16221617 : "CPXERR_BAD_ID",16231618 : "CPXERR_BAD_EXPONENT",16241619 : "CPXERR_Q_DIVISOR",16251621 : "CPXERR_NO_BOUND_SENSE",16261622 : "CPXERR_BAD_BOUND_SENSE",16271623 : "CPXERR_NO_NUMBER_BOUND",16281627 : "CPXERR_NO_SOS_SEPARATOR",16291650 : "CPXERR_INVALID_NUMBER",16301660 : "CPXERR_PRM_DATA",16311661 : "CPXERR_PRM_HEADER",16321719 : "CPXERR_NO_CONFLICT",16331720 : "CPXERR_CONFLICT_UNSTABLE",16341801 : "CPXERR_WORK_FILE_OPEN",16351802 : "CPXERR_WORK_FILE_READ",16361803 : "CPXERR_WORK_FILE_WRITE",16371804 : "CPXERR_IN_INFOCALLBACK",16381805 : "CPXERR_MIPSEARCH_WITH_CALLBACKS",16391806 : "CPXERR_LP_NOT_IN_ENVIRONMENT",16401807 : "CPXERR_PARAM_INCOMPATIBLE",164132000 : "CPXERR_LICENSE_MIN",164232201 : "CPXERR_ILOG_LICENSE",164332301 : "CPXERR_NO_MIP_LIC",164432302 : "CPXERR_NO_BARRIER_LIC",164532305 : "CPXERR_NO_MIQP_LIC",164632018 : "CPXERR_BADLDWID",164732023 : "CPXERR_BADPRODUCT",164832024 : "CPXERR_ALGNOTLICENSED",164932999 : "CPXERR_LICENSE_MAX",16501701 : "CPXERR_IIS_NO_INFO",16511702 : "CPXERR_IIS_NO_SOLN",16521703 : "CPXERR_IIS_FEAS",16531704 : "CPXERR_IIS_NOT_INFEAS",16541705 : "CPXERR_IIS_OPT_INFEAS",16551706 : "CPXERR_IIS_DEFAULT",16561707 : "CPXERR_IIS_NO_BASIC",16571709 : "CPXERR_IIS_NO_LOAD",16581710 : "CPXERR_IIS_SUB_OBJ_LIM",16591711 : "CPXERR_IIS_SUB_IT_LIM",16601712 : "CPXERR_IIS_SUB_TIME_LIM",16611713 : "CPXERR_IIS_NUM_BEST",16621714 : "CPXERR_IIS_SUB_ABORT",16633003 : "CPXERR_NOT_MIP",16643006 : "CPXERR_BAD_PRIORITY",16653007 : "CPXERR_ORDER_BAD_DIRECTION",16663009 : "CPXERR_ARRAY_BAD_SOS_TYPE",16673010 : "CPXERR_UNIQUE_WEIGHTS",16683012 : "CPXERR_BAD_DIRECTION",16693015 : "CPXERR_NO_SOS",16703016 : "CPXERR_NO_ORDER",16713018 : "CPXERR_INT_TOO_BIG",16723019 : "CPXERR_SUBPROB_SOLVE",16733020 : "CPXERR_NO_MIPSTART",16743021 : "CPXERR_BAD_CTYPE",16753023 : "CPXERR_NO_INT_X",16763024 : "CPXERR_NO_SOLNPOOL",16773301 : "CPXERR_MISS_SOS_TYPE",16783412 : "CPXERR_NO_TREE",16793413 : "CPXERR_TREE_MEMORY_LIMIT",16803414 : "CPXERR_FILTER_VARIABLE_TYPE",16813504 : "CPXERR_NODE_ON_DISK",16823601 : "CPXERR_PTHREAD_MUTEX_INIT",16833603 : "CPXERR_PTHREAD_CREATE",16841212 : "CPXERR_UNSUPPORTED_CONSTRAINT_TYPE",16851213 : "CPXERR_ILL_DEFINED_PWL",16861530 : "CPXERR_NET_DATA",16871531 : "CPXERR_NOT_MIN_COST_FLOW",16881532 : "CPXERR_BAD_ROW_ID",16891537 : "CPXERR_BAD_CHAR",16901538 : "CPXERR_NET_FILE_SHORT",16915002 : "CPXERR_Q_NOT_POS_DEF",16925004 : "CPXERR_NOT_QP",16935011 : "CPXERR_Q_DUP_ENTRY",16945012 : "CPXERR_Q_NOT_SYMMETRIC",16955014 : "CPXERR_Q_NOT_INDEF",16966002 : "CPXERR_QCP_SENSE"1697}16981699cdef dict parameters1700parameters = {1701"CPX_PARAMTYPE_NONE" : 0,1702"CPX_PARAMTYPE_INT" : 1,1703"CPX_PARAMTYPE_DOUBLE" : 2,1704"CPX_PARAMTYPE_STRING" : 3,1705"CPX_PARAM_ADVIND" : 1001,1706"CPX_PARAM_AGGFILL" : 1002,1707"CPX_PARAM_AGGIND" : 1003,1708"CPX_PARAM_BASINTERVAL" : 1004,1709"CPX_PARAM_CFILEMUL" : 1005,1710"CPX_PARAM_CLOCKTYPE" : 1006,1711"CPX_PARAM_CRAIND" : 1007,1712"CPX_PARAM_DEPIND" : 1008,1713"CPX_PARAM_DPRIIND" : 1009,1714"CPX_PARAM_PRICELIM" : 1010,1715"CPX_PARAM_EPMRK" : 1013,1716"CPX_PARAM_EPOPT" : 1014,1717"CPX_PARAM_EPPER" : 1015,1718"CPX_PARAM_EPRHS" : 1016,1719"CPX_PARAM_FASTMIP" : 1017,1720"CPX_PARAM_SIMDISPLAY" : 1019,1721"CPX_PARAM_ITLIM" : 1020,1722"CPX_PARAM_ROWREADLIM" : 1021,1723"CPX_PARAM_NETFIND" : 1022,1724"CPX_PARAM_COLREADLIM" : 1023,1725"CPX_PARAM_NZREADLIM" : 1024,1726"CPX_PARAM_OBJLLIM" : 1025,1727"CPX_PARAM_OBJULIM" : 1026,1728"CPX_PARAM_PERIND" : 1027,1729"CPX_PARAM_PERLIM" : 1028,1730"CPX_PARAM_PPRIIND" : 1029,1731"CPX_PARAM_PREIND" : 1030,1732"CPX_PARAM_REINV" : 1031,1733"CPX_PARAM_REVERSEIND" : 1032,1734"CPX_PARAM_RFILEMUL" : 1033,1735"CPX_PARAM_SCAIND" : 1034,1736"CPX_PARAM_SCRIND" : 1035,1737"CPX_PARAM_SINGLIM" : 1037,1738"CPX_PARAM_SINGTOL" : 1038,1739"CPX_PARAM_TILIM" : 1039,1740"CPX_PARAM_XXXIND" : 1041,1741"CPX_PARAM_PREDUAL" : 1044,1742"CPX_PARAM_EPOPT_H" : 1049,1743"CPX_PARAM_EPRHS_H" : 1050,1744"CPX_PARAM_PREPASS" : 1052,1745"CPX_PARAM_DATACHECK" : 1056,1746"CPX_PARAM_REDUCE" : 1057,1747"CPX_PARAM_PRELINEAR" : 1058,1748"CPX_PARAM_LPMETHOD" : 1062,1749"CPX_PARAM_QPMETHOD" : 1063,1750"CPX_PARAM_WORKDIR" : 1064,1751"CPX_PARAM_WORKMEM" : 1065,1752"CPX_PARAM_THREADS" : 1067,1753"CPX_PARAM_CONFLICTDISPLAY" : 1074,1754"CPX_PARAM_SIFTDISPLAY" : 1076,1755"CPX_PARAM_SIFTALG" : 1077,1756"CPX_PARAM_SIFTITLIM" : 1078,1757"CPX_PARAM_MPSLONGNUM" : 1081,1758"CPX_PARAM_MEMORYEMPHASIS" : 1082,1759"CPX_PARAM_NUMERICALEMPHASIS" : 1083,1760"CPX_PARAM_FEASOPTMODE" : 1084,1761"CPX_PARAM_PARALLELMODE" : 1109,1762"CPX_PARAM_TUNINGMEASURE" : 1110,1763"CPX_PARAM_TUNINGREPEAT" : 1111,1764"CPX_PARAM_TUNINGTILIM" : 1112,1765"CPX_PARAM_TUNINGDISPLAY" : 1113,1766"CPX_PARAM_WRITELEVEL" : 1114,1767"CPX_PARAM_ALL_MIN" : 1000,1768"CPX_PARAM_ALL_MAX" : 6000,1769"CPX_PARAM_BARDSTART" : 3001,1770"CPX_PARAM_BAREPCOMP" : 3002,1771"CPX_PARAM_BARGROWTH" : 3003,1772"CPX_PARAM_BAROBJRNG" : 3004,1773"CPX_PARAM_BARPSTART" : 3005,1774"CPX_PARAM_BARALG" : 3007,1775"CPX_PARAM_BARCOLNZ" : 3009,1776"CPX_PARAM_BARDISPLAY" : 3010,1777"CPX_PARAM_BARITLIM" : 3012,1778"CPX_PARAM_BARMAXCOR" : 3013,1779"CPX_PARAM_BARORDER" : 3014,1780"CPX_PARAM_BARSTARTALG" : 3017,1781"CPX_PARAM_BARCROSSALG" : 3018,1782"CPX_PARAM_BARQCPEPCOMP" : 3020,1783"CPX_PARAM_BRDIR" : 2001,1784"CPX_PARAM_BTTOL" : 2002,1785"CPX_PARAM_CLIQUES" : 2003,1786"CPX_PARAM_COEREDIND" : 2004,1787"CPX_PARAM_COVERS" : 2005,1788"CPX_PARAM_CUTLO" : 2006,1789"CPX_PARAM_CUTUP" : 2007,1790"CPX_PARAM_EPAGAP" : 2008,1791"CPX_PARAM_EPGAP" : 2009,1792"CPX_PARAM_EPINT" : 2010,1793"CPX_PARAM_MIPDISPLAY" : 2012,1794"CPX_PARAM_MIPINTERVAL" : 2013,1795"CPX_PARAM_INTSOLLIM" : 2015,1796"CPX_PARAM_NODEFILEIND" : 2016,1797"CPX_PARAM_NODELIM" : 2017,1798"CPX_PARAM_NODESEL" : 2018,1799"CPX_PARAM_OBJDIF" : 2019,1800"CPX_PARAM_MIPORDIND" : 2020,1801"CPX_PARAM_RELOBJDIF" : 2022,1802"CPX_PARAM_STARTALG" : 2025,1803"CPX_PARAM_SUBALG" : 2026,1804"CPX_PARAM_TRELIM" : 2027,1805"CPX_PARAM_VARSEL" : 2028,1806"CPX_PARAM_BNDSTRENIND" : 2029,1807"CPX_PARAM_HEURFREQ" : 2031,1808"CPX_PARAM_MIPORDTYPE" : 2032,1809"CPX_PARAM_CUTSFACTOR" : 2033,1810"CPX_PARAM_RELAXPREIND" : 2034,1811"CPX_PARAM_PRESLVND" : 2037,1812"CPX_PARAM_BBINTERVAL" : 2039,1813"CPX_PARAM_FLOWCOVERS" : 2040,1814"CPX_PARAM_IMPLBD" : 2041,1815"CPX_PARAM_PROBE" : 2042,1816"CPX_PARAM_GUBCOVERS" : 2044,1817"CPX_PARAM_STRONGCANDLIM" : 2045,1818"CPX_PARAM_STRONGITLIM" : 2046,1819"CPX_PARAM_FRACCAND" : 2048,1820"CPX_PARAM_FRACCUTS" : 2049,1821"CPX_PARAM_FRACPASS" : 2050,1822"CPX_PARAM_FLOWPATHS" : 2051,1823"CPX_PARAM_MIRCUTS" : 2052,1824"CPX_PARAM_DISJCUTS" : 2053,1825"CPX_PARAM_AGGCUTLIM" : 2054,1826"CPX_PARAM_MIPCBREDLP" : 2055 ,1827"CPX_PARAM_CUTPASS" : 2056,1828"CPX_PARAM_MIPEMPHASIS" : 2058,1829"CPX_PARAM_SYMMETRY" : 2059,1830"CPX_PARAM_DIVETYPE" : 2060,1831"CPX_PARAM_RINSHEUR" : 2061,1832"CPX_PARAM_SUBMIPNODELIM" : 2062,1833"CPX_PARAM_LBHEUR" : 2063,1834"CPX_PARAM_REPEATPRESOLVE" : 2064,1835"CPX_PARAM_PROBETIME" : 2065,1836"CPX_PARAM_POLISHTIME" : 2066,1837"CPX_PARAM_REPAIRTRIES" : 2067,1838"CPX_PARAM_EPLIN" : 2068,1839"CPX_PARAM_EPRELAX" : 2073,1840"CPX_PARAM_FPHEUR" : 2098,1841"CPX_PARAM_EACHCUTLIM" : 2102,1842"CPX_PARAM_SOLNPOOLCAPACITY" : 2103 ,1843"CPX_PARAM_SOLNPOOLREPLACE" : 2104 ,1844"CPX_PARAM_SOLNPOOLGAP" : 2105 ,1845"CPX_PARAM_SOLNPOOLAGAP" : 2106 ,1846"CPX_PARAM_SOLNPOOLINTENSITY" : 2107,1847"CPX_PARAM_POPULATELIM" : 2108,1848"CPX_PARAM_MIPSEARCH" : 2109,1849"CPX_PARAM_MIQCPSTRAT" : 2110,1850"CPX_PARAM_ZEROHALFCUTS" : 2111,1851"CPX_PARAM_POLISHAFTEREPAGAP" : 2126,1852"CPX_PARAM_POLISHAFTEREPGAP" : 2127,1853"CPX_PARAM_POLISHAFTERNODE" : 2128,1854"CPX_PARAM_POLISHAFTERINTSOL" : 2129,1855"CPX_PARAM_POLISHAFTERTIME" : 2130,1856"CPX_PARAM_MCFCUTS" : 2134,1857"CPX_PARAM_NETITLIM" : 5001,1858"CPX_PARAM_NETEPOPT" : 5002,1859"CPX_PARAM_NETEPRHS" : 5003,1860"CPX_PARAM_NETPPRIIND" : 5004,1861"CPX_PARAM_NETDISPLAY" : 5005,1862"CPX_PARAM_QPNZREADLIM" : 4001,1863"CPX_PARAM_QPMAKEPSDIND" : 4010,1864}186518661867