Generic Backend for LP solvers
This class only lists the methods that should be defined by any interface with a LP Solver. All these methods immediately raise NotImplementedError exceptions when called, and are obviously meant to be replaced by the solver-specific method. This file can also be used as a template to create a new interface : one would only need to replace the occurences of "Nonexistent_LP_solver" by the solver’s name, and replace GenericBackend by SolverName(GenericBackend) so that the new solver extends this class.
AUTHORS:
Bases: object
x.__init__(...) initializes x; see help(type(x)) for signature
Add a column.
INPUT:
Note
indices and coeffs are expected to be of the same length.
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.ncols() # optional - Nonexistent_LP_solver
0
sage: p.nrows() # optional - Nonexistent_LP_solver
0
sage: p.add_linear_constraints(5, 0, None) # optional - Nonexistent_LP_solver
sage: p.add_col(range(5), range(5)) # optional - Nonexistent_LP_solver
sage: p.nrows() # optional - Nonexistent_LP_solver
5
Add a linear constraint.
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.add_variables(5) # optional - Nonexistent_LP_solver
4
sage: p.add_linear_constraint(zip(range(5), range(5)), 2.0, 2.0) # optional - Nonexistent_LP_solver
sage: p.row(0) # optional - Nonexistent_LP_solver
([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0]) # optional - Nonexistent_LP_solver
sage: p.row_bounds(0) # optional - Nonexistent_LP_solver
(2.0, 2.0)
sage: p.add_linear_constraint( zip(range(5), range(5)), 1.0, 1.0, name='foo') # optional - Nonexistent_LP_solver
sage: p.row_name(-1) # optional - Nonexistent_LP_solver
"foo"
Add constraints.
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.add_variables(5) # optional - Nonexistent_LP_solver
5
sage: p.add_linear_constraints(5, None, 2) # optional - Nonexistent_LP_solver
sage: p.row(4) # optional - Nonexistent_LP_solver
([], [])
sage: p.row_bounds(4) # optional - Nonexistent_LP_solver
(None, 2.0)
Add a variable.
This amounts to adding a new column to the matrix. By default, the variable is both positive and real.
INPUT:
OUTPUT: The index of the newly created variable
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.ncols() # optional - Nonexistent_LP_solver
0
sage: p.add_variable() # optional - Nonexistent_LP_solver
0
sage: p.ncols() # optional - Nonexistent_LP_solver
1
sage: p.add_variable(binary=True) # optional - Nonexistent_LP_solver
1
sage: p.add_variable(lower_bound=-2.0, integer=True) # optional - Nonexistent_LP_solver
2
sage: p.add_variable(continuous=True, integer=True) # optional - Nonexistent_LP_solver
Traceback (most recent call last):
...
ValueError: ...
sage: p.add_variable(name='x',obj=1.0) # optional - Nonexistent_LP_solver
3
sage: p.col_name(3) # optional - Nonexistent_LP_solver
'x'
sage: p.objective_coefficient(3) # optional - Nonexistent_LP_solver
1.0
Add n variables.
This amounts to adding new columns to the matrix. By default, the variables are both positive and real.
INPUT:
OUTPUT: The index of the variable created last.
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.ncols() # optional - Nonexistent_LP_solver
0
sage: p.add_variables(5) # optional - Nonexistent_LP_solver
4
sage: p.ncols() # optional - Nonexistent_LP_solver
5
sage: p.add_variables(2, lower_bound=-2.0, integer=True, names=['a','b']) # optional - Nonexistent_LP_solver
6
Return the bounds of a specific variable.
INPUT:
OUTPUT:
A pair (lower_bound, upper_bound). Each of them can be set to None if the variable is not bounded in the corresponding direction, and is a real value otherwise.
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.add_variable() # optional - Nonexistent_LP_solver
1
sage: p.col_bounds(0) # optional - Nonexistent_LP_solver
(0.0, None)
sage: p.variable_upper_bound(0, 5) # optional - Nonexistent_LP_solver
sage: p.col_bounds(0) # optional - Nonexistent_LP_solver
(0.0, 5.0)
Return the index th col name
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.add_variable(name="I am a variable") # optional - Nonexistent_LP_solver
1
sage: p.col_name(0) # optional - Nonexistent_LP_solver
'I am a variable'
Return the value of the objective function.
Note
Behaviour is undefined unless solve has been called before.
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.add_variables(2) # optional - Nonexistent_LP_solver
2
sage: p.add_linear_constraint([(0,1), (1,2)], None, 3) # optional - Nonexistent_LP_solver
sage: p.set_objective([2, 5]) # optional - Nonexistent_LP_solver
sage: p.solve() # optional - Nonexistent_LP_solver
0
sage: p.get_objective_value() # optional - Nonexistent_LP_solver
7.5
sage: p.get_variable_value(0) # optional - Nonexistent_LP_solver
0.0
sage: p.get_variable_value(1) # optional - Nonexistent_LP_solver
1.5
Return the value of a variable given by the solver.
Note
Behaviour is undefined unless solve has been called before.
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.add_variables(2) # optional - Nonexistent_LP_solver
2
sage: p.add_linear_constraint([(0,1), (1, 2)], None, 3) # optional - Nonexistent_LP_solver
sage: p.set_objective([2, 5]) # optional - Nonexistent_LP_solver
sage: p.solve() # optional - Nonexistent_LP_solver
0
sage: p.get_objective_value() # optional - Nonexistent_LP_solver
7.5
sage: p.get_variable_value(0) # optional - Nonexistent_LP_solver
0.0
sage: p.get_variable_value(1) # optional - Nonexistent_LP_solver
1.5
Test whether the problem is a maximization
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.is_maximization() # optional - Nonexistent_LP_solver
True
sage: p.set_sense(-1) # optional - Nonexistent_LP_solver
sage: p.is_maximization() # optional - Nonexistent_LP_solver
False
Test whether the given variable is of binary type.
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.ncols() # optional - Nonexistent_LP_solver
0
sage: p.add_variable() # optional - Nonexistent_LP_solver
1
sage: p.set_variable_type(0,0) # optional - Nonexistent_LP_solver
sage: p.is_variable_binary(0) # optional - Nonexistent_LP_solver
True
Test whether the given variable is of continuous/real type.
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.ncols() # optional - Nonexistent_LP_solver
0
sage: p.add_variable() # optional - Nonexistent_LP_solver
1
sage: p.is_variable_continuous(0) # optional - Nonexistent_LP_solver
True
sage: p.set_variable_type(0,1) # optional - Nonexistent_LP_solver
sage: p.is_variable_continuous(0) # optional - Nonexistent_LP_solver
False
Test whether the given variable is of integer type.
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.ncols() # optional - Nonexistent_LP_solver
0
sage: p.add_variable() # optional - Nonexistent_LP_solver
1
sage: p.set_variable_type(0,1) # optional - Nonexistent_LP_solver
sage: p.is_variable_integer(0) # optional - Nonexistent_LP_solver
True
Return the number of columns/variables.
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.ncols() # optional - Nonexistent_LP_solver
0
sage: p.add_variables(2) # optional - Nonexistent_LP_solver
2
sage: p.ncols() # optional - Nonexistent_LP_solver
2
Return the number of rows/constraints.
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.nrows() # optional - Nonexistent_LP_solver
0
sage: p.add_linear_constraints(2, 2.0, None) # optional - Nonexistent_LP_solver
sage: p.nrows() # optional - Nonexistent_LP_solver
2
Set or get the coefficient of a variable in the objective function
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.add_variable() # optional - Nonexistent_LP_solver
1
sage: p.objective_coefficient(0) # optional - Nonexistent_LP_solver
0.0
sage: p.objective_coefficient(0,2) # optional - Nonexistent_LP_solver
sage: p.objective_coefficient(0) # optional - Nonexistent_LP_solver
2.0
Return or define the problem’s name
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.problem_name("There once was a french fry") # optional - Nonexistent_LP_solver
sage: print p.get_problem_name() # optional - Nonexistent_LP_solver
There once was a french fry
Remove a constraint.
INPUT:
- ``i`` -- index of the constraint to remove.
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.add_constraint(p[0] + p[1], max = 10) # optional - Nonexistent_LP_solver
sage: p.remove_constraint(0) # optional - Nonexistent_LP_solver
Remove several constraints.
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.add_constraint(p[0] + p[1], max = 10) # optional - Nonexistent_LP_solver
sage: p.remove_constraints([0]) # optional - Nonexistent_LP_solver
Return a row
INPUT:
OUTPUT:
A pair (indices, coeffs) where indices lists the entries whose coefficient is nonzero, and to which coeffs associates their coefficient on the model of the add_linear_constraint method.
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.add_variables(5) # optional - Nonexistent_LP_solver
5
sage: p.add_linear_constraint(zip(range(5), range(5)), 2, 2) # optional - Nonexistent_LP_solver
sage: p.row(0) # optional - Nonexistent_LP_solver
([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0])
sage: p.row_bounds(0) # optional - Nonexistent_LP_solver
(2.0, 2.0)
Return the bounds of a specific constraint.
INPUT:
OUTPUT:
A pair (lower_bound, upper_bound). Each of them can be set to None if the constraint is not bounded in the corresponding direction, and is a real value otherwise.
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.add_variables(5) # optional - Nonexistent_LP_solver
5
sage: p.add_linear_constraint(range(5), range(5), 2, 2) # optional - Nonexistent_LP_solver
sage: p.row(0) # optional - Nonexistent_LP_solver
([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0])
sage: p.row_bounds(0) # optional - Nonexistent_LP_solver
(2.0, 2.0)
Return the index th row name
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.add_linear_constraints(1, 2, None, name="Empty constraint 1") # optional - Nonexistent_LP_solver
sage: p.row_name(0) # optional - Nonexistent_LP_solver
'Empty constraint 1'
Set the objective function.
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.add_variables(5) # optional - Nonexistent_LP_solver
5
sage: p.set_objective([1, 1, 2, 1, 3]) # optional - Nonexistent_LP_solver
sage: map(lambda x :p.objective_coefficient(x), range(5)) # optional - Nonexistent_LP_solver
[1.0, 1.0, 2.0, 1.0, 3.0]
Constants in the objective function are respected:
sage: p = MixedIntegerLinearProgram(solver='Nonexistent_LP_solver') # optional - Nonexistent_LP_solver
sage: x,y = p[0], p[1] # optional - Nonexistent_LP_solver
sage: p.add_constraint(2*x + 3*y, max = 6) # optional - Nonexistent_LP_solver
sage: p.add_constraint(3*x + 2*y, max = 6) # optional - Nonexistent_LP_solver
sage: p.set_objective(x + y + 7) # optional - Nonexistent_LP_solver
sage: p.set_integer(x); p.set_integer(y) # optional - Nonexistent_LP_solver
sage: p.solve() # optional - Nonexistent_LP_solver
9.0
Set the direction (maximization/minimization).
INPUT:
sense (integer) :
- +1 => Maximization
- -1 => Minimization
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.is_maximization() # optional - Nonexistent_LP_solver
True
sage: p.set_sense(-1) # optional - Nonexistent_LP_solver
sage: p.is_maximization() # optional - Nonexistent_LP_solver
False
Set the type of a variable
INPUT:
variable (integer) – the variable’s id
vtype (integer) :
1 Integer
0 Binary
-1 Continuous
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.ncols() # optional - Nonexistent_LP_solver
0
sage: p.add_variable() # optional - Nonexistent_LP_solver
1
sage: p.set_variable_type(0,1) # optional - Nonexistent_LP_solver
sage: p.is_variable_integer(0) # optional - Nonexistent_LP_solver
True
Set the log (verbosity) level
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.set_verbosity(2) # optional - Nonexistent_LP_solver
Solve the problem.
Note
This method raises MIPSolverException exceptions when the solution can not be computed for any reason (none exists, or the LP solver was not able to find it, etc...)
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.add_linear_constraints(5, 0, None) # optional - Nonexistent_LP_solver
sage: p.add_col(range(5), range(5)) # optional - Nonexistent_LP_solver
sage: p.solve() # optional - Nonexistent_LP_solver
0
sage: p.objective_coefficient(0,1) # optional - Nonexistent_LP_solver
sage: p.solve() # optional - Nonexistent_LP_solver
Traceback (most recent call last):
...
MIPSolverException: ...
Return or define a solver parameter
INPUT:
Note
The list of available parameters is available at sage.numerical.mip.MixedIntegerlinearProgram.solver_parameter()
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.solver_parameter("timelimit") # optional - Nonexistent_LP_solver
sage: p.solver_parameter("timelimit", 60) # optional - Nonexistent_LP_solver
sage: p.solver_parameter("timelimit") # optional - Nonexistent_LP_solver
Return or define the lower bound on a variable
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.add_variable() # optional - Nonexistent_LP_solver
1
sage: p.col_bounds(0) # optional - Nonexistent_LP_solver
(0.0, None)
sage: p.variable_lower_bound(0, 5) # optional - Nonexistent_LP_solver
sage: p.col_bounds(0) # optional - Nonexistent_LP_solver
(5.0, None)
Return or define the upper bound on a variable
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.add_variable() # optional - Nonexistent_LP_solver
1
sage: p.col_bounds(0) # optional - Nonexistent_LP_solver
(0.0, None)
sage: p.variable_upper_bound(0, 5) # optional - Nonexistent_LP_solver
sage: p.col_bounds(0) # optional - Nonexistent_LP_solver
(0.0, 5.0)
Write the problem to a .lp file
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.add_variables(2) # optional - Nonexistent_LP_solver
2
sage: p.add_linear_constraint([(0, 1], (1, 2)], None, 3) # optional - Nonexistent_LP_solver
sage: p.set_objective([2, 5]) # optional - Nonexistent_LP_solver
sage: p.write_lp(os.path.join(SAGE_TMP, "lp_problem.lp")) # optional - Nonexistent_LP_solver
Write the problem to a .mps file
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
sage: p.add_variables(2) # optional - Nonexistent_LP_solver
2
sage: p.add_linear_constraint([(0, 1), (1, 2)], None, 3) # optional - Nonexistent_LP_solver
sage: p.set_objective([2, 5]) # optional - Nonexistent_LP_solver
sage: p.write_lp(os.path.join(SAGE_TMP, "lp_problem.lp")) # optional - Nonexistent_LP_solver
Returns/Sets the default MILP Solver used by Sage
INPUT:
solver – defines the solver to use:
- GLPK (solver="GLPK"). See the GLPK web site.
- COIN Branch and Cut (solver="Coin"). See the COIN-OR web site.
- CPLEX (solver="CPLEX"). See the CPLEX web site.
- Gurobi (solver="Gurobi"). See the Gurobi web site.
solver should then be equal to one of "GLPK", "Coin", "CPLEX", or "Gurobi".
- If solver=None (default), the current default solver’s name is returned.
OUTPUT:
This function returns the current default solver’s name if solver = None (default). Otherwise, it sets the default solver to the one given. If this solver does not exist, or is not available, a ValueError exception is raised.
EXAMPLE:
sage: former_solver = default_mip_solver()
sage: default_mip_solver("GLPK")
sage: default_mip_solver()
'Glpk'
sage: default_mip_solver("Yeahhhhhhhhhhh")
Traceback (most recent call last):
...
ValueError: 'solver' should be set to 'GLPK', 'Coin', 'CPLEX', 'Gurobi' or None.
sage: default_mip_solver(former_solver)
Return a solver according to the given preferences
INPUT:
solver – 4 solvers should be available through this class:
- GLPK (solver="GLPK"). See the GLPK web site.
- COIN Branch and Cut (solver="Coin"). See the COIN-OR web site.
- CPLEX (solver="CPLEX"). See the CPLEX web site.
- Gurobi (solver="Gurobi"). See the Gurobi web site.
- PPL (solver="PPL"). See the PPL web site.
solver should then be equal to one of "GLPK", "Coin", "CPLEX", "Gurobi", "PPL", or None. If solver=None (default), the default solver is used (see default_mip_solver method.
constraint_generation (boolean) – whether the solver returned is to be used for constraint/variable generation. As the interface with Coin does not support constraint/variable generation, setting constraint_generation to False ensures that the backend to Coin is not returned when solver = None. This is set to False by default.
See also
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver()