Path: blob/master/sage/numerical/backends/generic_backend.pyx
4059 views
r"""1Generic Backend for LP solvers23This class only lists the methods that should be defined by any4interface with a LP Solver. All these methods immediately raise5``NotImplementedError`` exceptions when called, and are obviously6meant to be replaced by the solver-specific method. This file can also7be used as a template to create a new interface : one would only need8to replace the occurences of ``"Nonexistent_LP_solver"`` by the9solver's name, and replace ``GenericBackend`` by10``SolverName(GenericBackend)`` so that the new solver extends this11class.1213AUTHORS:1415- Nathann Cohen (2010-10): initial implementation1617"""1819##############################################################################20# Copyright (C) 2010 Nathann Cohen <[email protected]>21# Distributed under the terms of the GNU General Public License (GPL)22# The full text of the GPL is available at:23# http://www.gnu.org/licenses/24##############################################################################252627cdef class GenericBackend:2829cpdef int add_variable(self, lower_bound=0.0, upper_bound=None, binary=False, continuous=True, integer=False, obj=0.0, name=None) except -1:30"""31Add a variable.3233This amounts to adding a new column to the matrix. By default,34the variable is both positive and real.3536INPUT:3738- ``lower_bound`` - the lower bound of the variable (default: 0)3940- ``upper_bound`` - the upper bound of the variable (default: ``None``)4142- ``binary`` - ``True`` if the variable is binary (default: ``False``).4344- ``continuous`` - ``True`` if the variable is binary (default: ``True``).4546- ``integer`` - ``True`` if the variable is binary (default: ``False``).4748- ``obj`` - (optional) coefficient of this variable in the objective function (default: 0.0)4950- ``name`` - an optional name for the newly added variable (default: ``None``).5152OUTPUT: The index of the newly created variable5354EXAMPLE::5556sage: from sage.numerical.backends.generic_backend import get_solver57sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver58sage: p.ncols() # optional - Nonexistent_LP_solver59060sage: p.add_variable() # optional - Nonexistent_LP_solver61062sage: p.ncols() # optional - Nonexistent_LP_solver63164sage: p.add_variable(binary=True) # optional - Nonexistent_LP_solver65166sage: p.add_variable(lower_bound=-2.0, integer=True) # optional - Nonexistent_LP_solver67268sage: p.add_variable(continuous=True, integer=True) # optional - Nonexistent_LP_solver69Traceback (most recent call last):70...71ValueError: ...72sage: p.add_variable(name='x',obj=1.0) # optional - Nonexistent_LP_solver73374sage: p.col_name(3) # optional - Nonexistent_LP_solver75'x'76sage: p.objective_coefficient(3) # optional - Nonexistent_LP_solver771.078"""79raise NotImplementedError()8081cpdef int add_variables(self, int n, lower_bound=0.0, upper_bound=None, binary=False, continuous=True, integer=False, obj=0.0, names=None) except -1:82"""83Add ``n`` variables.8485This amounts to adding new columns to the matrix. By default,86the variables are both positive and real.8788INPUT:8990- ``n`` - the number of new variables (must be > 0)9192- ``lower_bound`` - the lower bound of the variable (default: 0)9394- ``upper_bound`` - the upper bound of the variable (default: ``None``)9596- ``binary`` - ``True`` if the variable is binary (default: ``False``).9798- ``continuous`` - ``True`` if the variable is binary (default: ``True``).99100- ``integer`` - ``True`` if the variable is binary (default: ``False``).101102- ``obj`` - (optional) coefficient of all variables in the objective function (default: 0.0)103104- ``names`` - optional list of names (default: ``None``)105106OUTPUT: The index of the variable created last.107108EXAMPLE::109110sage: from sage.numerical.backends.generic_backend import get_solver111sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver112sage: p.ncols() # optional - Nonexistent_LP_solver1130114sage: p.add_variables(5) # optional - Nonexistent_LP_solver1154116sage: p.ncols() # optional - Nonexistent_LP_solver1175118sage: p.add_variables(2, lower_bound=-2.0, integer=True, names=['a','b']) # optional - Nonexistent_LP_solver1196120"""121raise NotImplementedError()122123cpdef set_variable_type(self, int variable, int vtype):124"""125Set the type of a variable126127INPUT:128129- ``variable`` (integer) -- the variable's id130131- ``vtype`` (integer) :132133* 1 Integer134* 0 Binary135* -1 Continuous136137EXAMPLE::138139sage: from sage.numerical.backends.generic_backend import get_solver140sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver141sage: p.ncols() # optional - Nonexistent_LP_solver1420143sage: p.add_variable() # optional - Nonexistent_LP_solver1441145sage: p.set_variable_type(0,1) # optional - Nonexistent_LP_solver146sage: p.is_variable_integer(0) # optional - Nonexistent_LP_solver147True148"""149raise NotImplementedError()150151cpdef set_sense(self, int sense):152"""153Set the direction (maximization/minimization).154155INPUT:156157- ``sense`` (integer) :158159* +1 => Maximization160* -1 => Minimization161162EXAMPLE::163164sage: from sage.numerical.backends.generic_backend import get_solver165sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver166sage: p.is_maximization() # optional - Nonexistent_LP_solver167True168sage: p.set_sense(-1) # optional - Nonexistent_LP_solver169sage: p.is_maximization() # optional - Nonexistent_LP_solver170False171"""172raise NotImplementedError()173174cpdef objective_coefficient(self, int variable, coeff=None):175"""176Set or get the coefficient of a variable in the objective177function178179INPUT:180181- ``variable`` (integer) -- the variable's id182183- ``coeff`` (double) -- its coefficient184185EXAMPLE::186187sage: from sage.numerical.backends.generic_backend import get_solver188sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver189sage: p.add_variable() # optional - Nonexistent_LP_solver1901191sage: p.objective_coefficient(0) # optional - Nonexistent_LP_solver1920.0193sage: p.objective_coefficient(0,2) # optional - Nonexistent_LP_solver194sage: p.objective_coefficient(0) # optional - Nonexistent_LP_solver1952.0196"""197raise NotImplementedError()198199cpdef set_objective(self, list coeff, double d = 0.0):200"""201Set the objective function.202203INPUT:204205- ``coeff`` -- a list of real values, whose ith element is the206coefficient of the ith variable in the objective function.207208- ``d`` (double) -- the constant term in the linear function (set to `0` by default)209210EXAMPLE::211212sage: from sage.numerical.backends.generic_backend import get_solver213sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver214sage: p.add_variables(5) # optional - Nonexistent_LP_solver2155216sage: p.set_objective([1, 1, 2, 1, 3]) # optional - Nonexistent_LP_solver217sage: map(lambda x :p.objective_coefficient(x), range(5)) # optional - Nonexistent_LP_solver218[1.0, 1.0, 2.0, 1.0, 3.0]219220Constants in the objective function are respected::221222sage: p = MixedIntegerLinearProgram(solver='Nonexistent_LP_solver') # optional - Nonexistent_LP_solver223sage: x,y = p[0], p[1] # optional - Nonexistent_LP_solver224sage: p.add_constraint(2*x + 3*y, max = 6) # optional - Nonexistent_LP_solver225sage: p.add_constraint(3*x + 2*y, max = 6) # optional - Nonexistent_LP_solver226sage: p.set_objective(x + y + 7) # optional - Nonexistent_LP_solver227sage: p.set_integer(x); p.set_integer(y) # optional - Nonexistent_LP_solver228sage: p.solve() # optional - Nonexistent_LP_solver2299.0230"""231raise NotImplementedError()232233cpdef set_verbosity(self, int level):234"""235Set the log (verbosity) level236237INPUT:238239- ``level`` (integer) -- From 0 (no verbosity) to 3.240241EXAMPLE::242243sage: from sage.numerical.backends.generic_backend import get_solver244sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver245sage: p.set_verbosity(2) # optional - Nonexistent_LP_solver246"""247raise NotImplementedError()248249cpdef remove_constraint(self, int i):250r"""251Remove a constraint.252253INPUT::254255- ``i`` -- index of the constraint to remove.256257EXAMPLE::258259sage: from sage.numerical.backends.generic_backend import get_solver260sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver261sage: p.add_constraint(p[0] + p[1], max = 10) # optional - Nonexistent_LP_solver262sage: p.remove_constraint(0) # optional - Nonexistent_LP_solver263"""264raise NotImplementedError()265266cpdef remove_constraints(self, constraints):267r"""268Remove several constraints.269270INPUT:271272- ``constraints`` -- an iterable containing the indices of the rows to remove.273274EXAMPLE::275276sage: from sage.numerical.backends.generic_backend import get_solver277sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver278sage: p.add_constraint(p[0] + p[1], max = 10) # optional - Nonexistent_LP_solver279sage: p.remove_constraints([0]) # optional - Nonexistent_LP_solver280"""281if type(constraints) == int: self.remove_constraint(constraints)282283cdef int last = self.nrows() + 1284285for c in sorted(constraints, reverse=True):286if c != last:287self.remove_constraint(c)288last = c289290cpdef add_linear_constraint(self, coefficients, lower_bound, upper_bound, name=None):291"""292Add a linear constraint.293294INPUT:295296- ``coefficients`` an iterable with ``(c,v)`` pairs where ``c``297is a variable index (integer) and ``v`` is a value (real298value).299300- ``lower_bound`` - a lower bound, either a real value or ``None``301302- ``upper_bound`` - an upper bound, either a real value or ``None``303304- ``name`` - an optional name for this row (default: ``None``)305306EXAMPLE::307308sage: from sage.numerical.backends.generic_backend import get_solver309sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver310sage: p.add_variables(5) # optional - Nonexistent_LP_solver3114312sage: p.add_linear_constraint(zip(range(5), range(5)), 2.0, 2.0) # optional - Nonexistent_LP_solver313sage: p.row(0) # optional - Nonexistent_LP_solver314([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0]) # optional - Nonexistent_LP_solver315sage: p.row_bounds(0) # optional - Nonexistent_LP_solver316(2.0, 2.0)317sage: p.add_linear_constraint( zip(range(5), range(5)), 1.0, 1.0, name='foo') # optional - Nonexistent_LP_solver318sage: p.row_name(-1) # optional - Nonexistent_LP_solver319"foo"320"""321raise NotImplementedError()322323cpdef add_col(self, list indices, list coeffs):324"""325Add a column.326327INPUT:328329- ``indices`` (list of integers) -- this list constains the330indices of the constraints in which the variable's331coefficient is nonzero332333- ``coeffs`` (list of real values) -- associates a coefficient334to the variable in each of the constraints in which it335appears. Namely, the ith entry of ``coeffs`` corresponds to336the coefficient of the variable in the constraint337represented by the ith entry in ``indices``.338339.. NOTE::340341``indices`` and ``coeffs`` are expected to be of the same342length.343344EXAMPLE::345346sage: from sage.numerical.backends.generic_backend import get_solver347sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver348sage: p.ncols() # optional - Nonexistent_LP_solver3490350sage: p.nrows() # optional - Nonexistent_LP_solver3510352sage: p.add_linear_constraints(5, 0, None) # optional - Nonexistent_LP_solver353sage: p.add_col(range(5), range(5)) # optional - Nonexistent_LP_solver354sage: p.nrows() # optional - Nonexistent_LP_solver3555356"""357raise NotImplementedError()358359cpdef add_linear_constraints(self, int number, lower_bound, upper_bound, names=None):360"""361Add constraints.362363INPUT:364365- ``number`` (integer) -- the number of constraints to add.366367- ``lower_bound`` - a lower bound, either a real value or ``None``368369- ``upper_bound`` - an upper bound, either a real value or ``None``370371- ``names`` - an optional list of names (default: ``None``)372373EXAMPLE::374375sage: from sage.numerical.backends.generic_backend import get_solver376sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver377sage: p.add_variables(5) # optional - Nonexistent_LP_solver3785379sage: p.add_linear_constraints(5, None, 2) # optional - Nonexistent_LP_solver380sage: p.row(4) # optional - Nonexistent_LP_solver381([], [])382sage: p.row_bounds(4) # optional - Nonexistent_LP_solver383(None, 2.0)384"""385raise NotImplementedError()386387cpdef int solve(self) except -1:388"""389Solve the problem.390391.. NOTE::392393This method raises ``MIPSolverException`` exceptions when394the solution can not be computed for any reason (none395exists, or the LP solver was not able to find it, etc...)396397EXAMPLE::398399sage: from sage.numerical.backends.generic_backend import get_solver400sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver401sage: p.add_linear_constraints(5, 0, None) # optional - Nonexistent_LP_solver402sage: p.add_col(range(5), range(5)) # optional - Nonexistent_LP_solver403sage: p.solve() # optional - Nonexistent_LP_solver4040405sage: p.objective_coefficient(0,1) # optional - Nonexistent_LP_solver406sage: p.solve() # optional - Nonexistent_LP_solver407Traceback (most recent call last):408...409MIPSolverException: ...410"""411raise NotImplementedError()412413cpdef double get_objective_value(self):414"""415Return the value of the objective function.416417.. NOTE::418419Behaviour is undefined unless ``solve`` has been called before.420421EXAMPLE::422423sage: from sage.numerical.backends.generic_backend import get_solver424sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver425sage: p.add_variables(2) # optional - Nonexistent_LP_solver4262427sage: p.add_linear_constraint([(0,1), (1,2)], None, 3) # optional - Nonexistent_LP_solver428sage: p.set_objective([2, 5]) # optional - Nonexistent_LP_solver429sage: p.solve() # optional - Nonexistent_LP_solver4300431sage: p.get_objective_value() # optional - Nonexistent_LP_solver4327.5433sage: p.get_variable_value(0) # optional - Nonexistent_LP_solver4340.0435sage: p.get_variable_value(1) # optional - Nonexistent_LP_solver4361.5437"""438439raise NotImplementedError()440441cpdef double get_variable_value(self, int variable):442"""443Return the value of a variable given by the solver.444445.. NOTE::446447Behaviour is undefined unless ``solve`` has been called before.448449EXAMPLE::450451sage: from sage.numerical.backends.generic_backend import get_solver452sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver453sage: p.add_variables(2) # optional - Nonexistent_LP_solver4542455sage: p.add_linear_constraint([(0,1), (1, 2)], None, 3) # optional - Nonexistent_LP_solver456sage: p.set_objective([2, 5]) # optional - Nonexistent_LP_solver457sage: p.solve() # optional - Nonexistent_LP_solver4580459sage: p.get_objective_value() # optional - Nonexistent_LP_solver4607.5461sage: p.get_variable_value(0) # optional - Nonexistent_LP_solver4620.0463sage: p.get_variable_value(1) # optional - Nonexistent_LP_solver4641.5465"""466467raise NotImplementedError()468469cpdef int ncols(self):470"""471Return the number of columns/variables.472473EXAMPLE::474475sage: from sage.numerical.backends.generic_backend import get_solver476sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver477sage: p.ncols() # optional - Nonexistent_LP_solver4780479sage: p.add_variables(2) # optional - Nonexistent_LP_solver4802481sage: p.ncols() # optional - Nonexistent_LP_solver4822483"""484485raise NotImplementedError()486487cpdef int nrows(self):488"""489Return the number of rows/constraints.490491EXAMPLE::492493sage: from sage.numerical.backends.generic_backend import get_solver494sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver495sage: p.nrows() # optional - Nonexistent_LP_solver4960497sage: p.add_linear_constraints(2, 2.0, None) # optional - Nonexistent_LP_solver498sage: p.nrows() # optional - Nonexistent_LP_solver4992500"""501502raise NotImplementedError()503504cpdef bint is_maximization(self):505"""506Test whether the problem is a maximization507508EXAMPLE::509510sage: from sage.numerical.backends.generic_backend import get_solver511sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver512sage: p.is_maximization() # optional - Nonexistent_LP_solver513True514sage: p.set_sense(-1) # optional - Nonexistent_LP_solver515sage: p.is_maximization() # optional - Nonexistent_LP_solver516False517"""518raise NotImplementedError()519520cpdef problem_name(self, char * name = NULL):521"""522Return or define the problem's name523524INPUT:525526- ``name`` (``char *``) -- the problem's name. When set to527``NULL`` (default), the method returns the problem's name.528529EXAMPLE::530531sage: from sage.numerical.backends.generic_backend import get_solver532sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver533sage: p.problem_name("There once was a french fry") # optional - Nonexistent_LP_solver534sage: print p.get_problem_name() # optional - Nonexistent_LP_solver535There once was a french fry536"""537538raise NotImplementedError()539540cpdef write_lp(self, char * name):541"""542Write the problem to a .lp file543544INPUT:545546- ``filename`` (string)547548EXAMPLE::549550sage: from sage.numerical.backends.generic_backend import get_solver551sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver552sage: p.add_variables(2) # optional - Nonexistent_LP_solver5532554sage: p.add_linear_constraint([(0, 1], (1, 2)], None, 3) # optional - Nonexistent_LP_solver555sage: p.set_objective([2, 5]) # optional - Nonexistent_LP_solver556sage: p.write_lp(SAGE_TMP+"/lp_problem.lp") # optional - Nonexistent_LP_solver557"""558raise NotImplementedError()559560cpdef write_mps(self, char * name, int modern):561"""562Write the problem to a .mps file563564INPUT:565566- ``filename`` (string)567568EXAMPLE::569570sage: from sage.numerical.backends.generic_backend import get_solver571sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver572sage: p.add_variables(2) # optional - Nonexistent_LP_solver5732574sage: p.add_linear_constraint([(0, 1), (1, 2)], None, 3) # optional - Nonexistent_LP_solver575sage: p.set_objective([2, 5]) # optional - Nonexistent_LP_solver576sage: p.write_lp(SAGE_TMP+"/lp_problem.lp") # optional - Nonexistent_LP_solver577"""578raise NotImplementedError()579580cpdef row(self, int i):581"""582Return a row583584INPUT:585586- ``index`` (integer) -- the constraint's id.587588OUTPUT:589590A pair ``(indices, coeffs)`` where ``indices`` lists the591entries whose coefficient is nonzero, and to which ``coeffs``592associates their coefficient on the model of the593``add_linear_constraint`` method.594595EXAMPLE::596597sage: from sage.numerical.backends.generic_backend import get_solver598sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver599sage: p.add_variables(5) # optional - Nonexistent_LP_solver6005601sage: p.add_linear_constraint(zip(range(5), range(5)), 2, 2) # optional - Nonexistent_LP_solver602sage: p.row(0) # optional - Nonexistent_LP_solver603([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0])604sage: p.row_bounds(0) # optional - Nonexistent_LP_solver605(2.0, 2.0)606"""607raise NotImplementedError()608609cpdef row_bounds(self, int index):610"""611Return the bounds of a specific constraint.612613INPUT:614615- ``index`` (integer) -- the constraint's id.616617OUTPUT:618619A pair ``(lower_bound, upper_bound)``. Each of them can be set620to ``None`` if the constraint is not bounded in the621corresponding direction, and is a real value otherwise.622623EXAMPLE::624625sage: from sage.numerical.backends.generic_backend import get_solver626sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver627sage: p.add_variables(5) # optional - Nonexistent_LP_solver6285629sage: p.add_linear_constraint(range(5), range(5), 2, 2) # optional - Nonexistent_LP_solver630sage: p.row(0) # optional - Nonexistent_LP_solver631([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0])632sage: p.row_bounds(0) # optional - Nonexistent_LP_solver633(2.0, 2.0)634"""635raise NotImplementedError()636637cpdef col_bounds(self, int index):638"""639Return the bounds of a specific variable.640641INPUT:642643- ``index`` (integer) -- the variable's id.644645OUTPUT:646647A pair ``(lower_bound, upper_bound)``. Each of them can be set648to ``None`` if the variable is not bounded in the649corresponding direction, and is a real value otherwise.650651EXAMPLE::652653sage: from sage.numerical.backends.generic_backend import get_solver654sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver655sage: p.add_variable() # optional - Nonexistent_LP_solver6561657sage: p.col_bounds(0) # optional - Nonexistent_LP_solver658(0.0, None)659sage: p.variable_upper_bound(0, 5) # optional - Nonexistent_LP_solver660sage: p.col_bounds(0) # optional - Nonexistent_LP_solver661(0.0, 5.0)662"""663raise NotImplementedError()664665cpdef bint is_variable_binary(self, int index):666"""667Test whether the given variable is of binary type.668669INPUT:670671- ``index`` (integer) -- the variable's id672673EXAMPLE::674675sage: from sage.numerical.backends.generic_backend import get_solver676sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver677sage: p.ncols() # optional - Nonexistent_LP_solver6780679sage: p.add_variable() # optional - Nonexistent_LP_solver6801681sage: p.set_variable_type(0,0) # optional - Nonexistent_LP_solver682sage: p.is_variable_binary(0) # optional - Nonexistent_LP_solver683True684685"""686raise NotImplementedError()687688cpdef bint is_variable_integer(self, int index):689"""690Test whether the given variable is of integer type.691692INPUT:693694- ``index`` (integer) -- the variable's id695696EXAMPLE::697698sage: from sage.numerical.backends.generic_backend import get_solver699sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver700sage: p.ncols() # optional - Nonexistent_LP_solver7010702sage: p.add_variable() # optional - Nonexistent_LP_solver7031704sage: p.set_variable_type(0,1) # optional - Nonexistent_LP_solver705sage: p.is_variable_integer(0) # optional - Nonexistent_LP_solver706True707"""708raise NotImplementedError()709710cpdef bint is_variable_continuous(self, int index):711"""712Test whether the given variable is of continuous/real type.713714INPUT:715716- ``index`` (integer) -- the variable's id717718EXAMPLE::719720sage: from sage.numerical.backends.generic_backend import get_solver721sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver722sage: p.ncols() # optional - Nonexistent_LP_solver7230724sage: p.add_variable() # optional - Nonexistent_LP_solver7251726sage: p.is_variable_continuous(0) # optional - Nonexistent_LP_solver727True728sage: p.set_variable_type(0,1) # optional - Nonexistent_LP_solver729sage: p.is_variable_continuous(0) # optional - Nonexistent_LP_solver730False731732"""733raise NotImplementedError()734735cpdef row_name(self, int index):736"""737Return the ``index`` th row name738739INPUT:740741- ``index`` (integer) -- the row's id742743EXAMPLE::744745sage: from sage.numerical.backends.generic_backend import get_solver746sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver747sage: p.add_linear_constraints(1, 2, None, name="Empty constraint 1") # optional - Nonexistent_LP_solver748sage: p.row_name(0) # optional - Nonexistent_LP_solver749'Empty constraint 1'750751"""752raise NotImplementedError()753754cpdef col_name(self, int index):755"""756Return the ``index`` th col name757758INPUT:759760- ``index`` (integer) -- the col's id761762- ``name`` (``char *``) -- its name. When set to ``NULL``763(default), the method returns the current name.764765EXAMPLE::766767sage: from sage.numerical.backends.generic_backend import get_solver768sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver769sage: p.add_variable(name="I am a variable") # optional - Nonexistent_LP_solver7701771sage: p.col_name(0) # optional - Nonexistent_LP_solver772'I am a variable'773"""774raise NotImplementedError()775776cpdef variable_upper_bound(self, int index, value = None):777"""778Return or define the upper bound on a variable779780INPUT:781782- ``index`` (integer) -- the variable's id783784- ``value`` -- real value, or ``None`` to mean that the785variable has not upper bound. When set to ``None``786(default), the method returns the current value.787788EXAMPLE::789790sage: from sage.numerical.backends.generic_backend import get_solver791sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver792sage: p.add_variable() # optional - Nonexistent_LP_solver7931794sage: p.col_bounds(0) # optional - Nonexistent_LP_solver795(0.0, None)796sage: p.variable_upper_bound(0, 5) # optional - Nonexistent_LP_solver797sage: p.col_bounds(0) # optional - Nonexistent_LP_solver798(0.0, 5.0)799"""800raise NotImplementedError()801802cpdef variable_lower_bound(self, int index, value = None):803"""804Return or define the lower bound on a variable805806INPUT:807808- ``index`` (integer) -- the variable's id809810- ``value`` -- real value, or ``None`` to mean that the811variable has not lower bound. When set to ``None``812(default), the method returns the current value.813814EXAMPLE::815816sage: from sage.numerical.backends.generic_backend import get_solver817sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver818sage: p.add_variable() # optional - Nonexistent_LP_solver8191820sage: p.col_bounds(0) # optional - Nonexistent_LP_solver821(0.0, None)822sage: p.variable_lower_bound(0, 5) # optional - Nonexistent_LP_solver823sage: p.col_bounds(0) # optional - Nonexistent_LP_solver824(5.0, None)825"""826raise NotImplementedError()827828cpdef solver_parameter(self, name, value = None):829"""830Return or define a solver parameter831832INPUT:833834- ``name`` (string) -- the parameter835836- ``value`` -- the parameter's value if it is to be defined,837or ``None`` (default) to obtain its current value.838839.. NOTE::840841The list of available parameters is available at842:meth:`sage.numerical.mip.MixedIntegerlinearProgram.solver_parameter`843844EXAMPLE::845846sage: from sage.numerical.backends.generic_backend import get_solver847sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver848sage: p.solver_parameter("timelimit") # optional - Nonexistent_LP_solver849sage: p.solver_parameter("timelimit", 60) # optional - Nonexistent_LP_solver850sage: p.solver_parameter("timelimit") # optional - Nonexistent_LP_solver851"""852raise NotImplementedError()853854855default_solver = None856857def default_mip_solver(solver = None):858"""859Returns/Sets the default MILP Solver used by Sage860861INPUT:862863- ``solver`` -- defines the solver to use:864865- GLPK (``solver="GLPK"``). See the `GLPK866<http://www.gnu.org/software/glpk/>`_ web site.867868- COIN Branch and Cut (``solver="Coin"``). See the `COIN-OR869<http://www.coin-or.org>`_ web site.870871- CPLEX (``solver="CPLEX"``). See the872`CPLEX <http://www.ilog.com/products/cplex/>`_ web site.873874- Gurobi (``solver="Gurobi"``). See the `Gurobi875<http://www.gurobi.com/>`_ web site.876877``solver`` should then be equal to one of ``"GLPK"``,878``"Coin"``, ``"CPLEX"``, or ``"Gurobi"``.879880- If ``solver=None`` (default), the current default solver's name is881returned.882883OUTPUT:884885This function returns the current default solver's name if ``solver = None``886(default). Otherwise, it sets the default solver to the one given. If this887solver does not exist, or is not available, a ``ValueError`` exception is888raised.889890EXAMPLE::891892sage: former_solver = default_mip_solver()893sage: default_mip_solver("GLPK")894sage: default_mip_solver()895'Glpk'896sage: default_mip_solver("Yeahhhhhhhhhhh")897Traceback (most recent call last):898...899ValueError: 'solver' should be set to 'GLPK', 'Coin', 'CPLEX', 'Gurobi' or None.900sage: default_mip_solver(former_solver)901"""902global default_solver903904if solver is None:905906if default_solver is not None:907return default_solver908909else:910for s in ["Cplex", "Gurobi", "Coin", "Glpk"]:911try:912default_mip_solver(s)913return s914except ValueError:915pass916917solver = solver.capitalize()918919if solver == "Cplex":920try:921from sage.numerical.backends.cplex_backend import CPLEXBackend922default_solver = solver923except ImportError:924raise ValueError("CPLEX is not available. Please refer to the documentation to install it.")925926elif solver == "Coin":927try:928from sage.numerical.backends.coin_backend import CoinBackend929default_solver = solver930except ImportError:931raise ValueError("COIN is not available. Please refer to the documentation to install it.")932933elif solver == "Gurobi":934try:935from sage.numerical.backends.gurobi_backend import GurobiBackend936default_solver = solver937except ImportError:938raise ValueError("Gurobi is not available. Please refer to the documentation to install it.")939940elif solver == "Glpk":941default_solver = solver942943else:944raise ValueError("'solver' should be set to 'GLPK', 'Coin', 'CPLEX', 'Gurobi' or None.")945946cpdef GenericBackend get_solver(constraint_generation = False, solver = None):947"""948Return a solver according to the given preferences949950INPUT:951952- ``solver`` -- 4 solvers should be available through this class:953954- GLPK (``solver="GLPK"``). See the `GLPK955<http://www.gnu.org/software/glpk/>`_ web site.956957- COIN Branch and Cut (``solver="Coin"``). See the `COIN-OR958<http://www.coin-or.org>`_ web site.959960- CPLEX (``solver="CPLEX"``). See the961`CPLEX <http://www.ilog.com/products/cplex/>`_ web site.962963- Gurobi (``solver="Gurobi"``). See the `Gurobi964<http://www.gurobi.com/>`_ web site.965966``solver`` should then be equal to one of ``"GLPK"``, ``"Coin"``,967``"CPLEX"``, ``"Gurobi"``, or ``None``. If ``solver=None`` (default),968the default solver is used (see ``default_mip_solver`` method.969970- ``constraint_generation`` (boolean) -- whether the solver971returned is to be used for constraint/variable generation. As972the interface with Coin does not support constraint/variable973generation, setting ``constraint_generation`` to ``False``974ensures that the backend to Coin is not returned when ``solver =975None``. This is set to ``False`` by default.976977.. SEEALSO::978979- :func:`default_mip_solver` -- Returns/Sets the default MIP solver.980981EXAMPLE::982983sage: from sage.numerical.backends.generic_backend import get_solver984sage: p = get_solver()985"""986987if solver is None:988solver = default_mip_solver()989990# We do not want to use Coin for constraint_generation. It just does not991# work992if solver == "Coin" and constraint_generation:993solver = "Glpk"994995else:996solver = solver.capitalize()997998if solver == "Coin":999from sage.numerical.backends.coin_backend import CoinBackend1000return CoinBackend()10011002elif solver == "Glpk":1003from sage.numerical.backends.glpk_backend import GLPKBackend1004return GLPKBackend()10051006elif solver == "Cplex":1007from sage.numerical.backends.cplex_backend import CPLEXBackend1008return CPLEXBackend()10091010elif solver == "Gurobi":1011from sage.numerical.backends.gurobi_backend import GurobiBackend1012return GurobiBackend()10131014else:1015raise ValueError("'solver' should be set to 'GLPK', 'Coin', 'CPLEX', 'Gurobi' or None (in which case the default one is used).")10161017101810191020