InteractiveLP Backend¶
AUTHORS:
- Nathann Cohen (2010-10) : generic_backend template
- Matthias Koeppe (2016-03) : this backend
-
class
sage.numerical.backends.interactivelp_backend.
InteractiveLPBackend
¶ Bases:
sage.numerical.backends.generic_backend.GenericBackend
MIP Backend that works with
InteractiveLPProblem
.This backend should be used only for linear programs over general fields, or for educational purposes. For fast computations with floating point arithmetic, use one of the numerical backends. For exact computations with rational numbers, use backend ‘PPL’.
There is no support for integer variables.
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP")
-
add_col
(indices, coeffs)¶ Add a column.
INPUT:
indices
(list of integers) – this list contains the indices of the constraints in which the variable’s coefficient is nonzerocoeffs
(list of real values) – associates a coefficient to the variable in each of the constraints in which it appears. Namely, the i-th entry ofcoeffs
corresponds to the coefficient of the variable in the constraint represented by the i-th entry inindices
.
Note
indices
andcoeffs
are expected to be of the same length.EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.ncols() 0 sage: p.nrows() 0 sage: p.add_linear_constraints(5, 0, None) sage: p.add_col(list(range(5)), list(range(5))) sage: p.nrows() 5
-
add_linear_constraint
(coefficients, lower_bound, upper_bound, name=None)¶ Add a linear constraint.
INPUT:
coefficients
– an iterable of pairs(i, v)
. In each pair,i
is a variable index (integer) andv
is a value (element ofbase_ring()
).lower_bound
– element ofbase_ring()
orNone
. The lower bound.upper_bound
– element ofbase_ring()
orNone
. The upper bound.name
– string orNone
. Optional name for this row.
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.add_variables(5) 4 sage: p.add_linear_constraint( zip(range(5), range(5)), 2, 2) sage: p.row(0) ([1, 2, 3, 4], [1, 2, 3, 4]) sage: p.row_bounds(0) (2, 2) sage: p.add_linear_constraint( zip(range(5), range(5)), 1, 1, name='foo') sage: p.row_name(1) 'foo'
-
add_variable
(lower_bound=0, upper_bound=None, binary=False, continuous=True, integer=False, obj=None, name=None, coefficients=None)¶ Add a variable.
This amounts to adding a new column to the matrix. By default, the variable is both nonnegative and real.
In this backend, variables are always continuous (real). If integer variables are requested via the parameters
binary
andinteger
, an error will be raised.INPUT:
lower_bound
- the lower bound of the variable (default: 0)upper_bound
- the upper bound of the variable (default:None
)binary
-True
if the variable is binary (default:False
).continuous
-True
if the variable is binary (default:True
).integer
-True
if the variable is binary (default:False
).obj
- (optional) coefficient of this variable in the objective function (default: 0)name
- an optional name for the newly added variable (default:None
).coefficients
– (optional) an iterable of pairs(i, v)
. In each pair,i
is a variable index (integer) andv
is a value (element ofbase_ring()
).
OUTPUT: The index of the newly created variable
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.ncols() 0 sage: p.add_variable() 0 sage: p.ncols() 1 sage: p.add_variable(continuous=True, integer=True) Traceback (most recent call last): ... ValueError: ... sage: p.add_variable(name='x',obj=1) 1 sage: p.col_name(1) 'x' sage: p.objective_coefficient(1) 1
-
base_ring
()¶ Return the base ring.
OUTPUT:
A ring. The coefficients that the chosen solver supports.
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.base_ring() Rational Field
-
col_bounds
(index)¶ Return the bounds of a specific variable.
INPUT:
index
(integer) – the variable’s id.
OUTPUT:
A pair
(lower_bound, upper_bound)
. Each of them can be set toNone
if the variable is not bounded in the corresponding direction, and is a real value otherwise.EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.add_variable(lower_bound=None) 0 sage: p.col_bounds(0) (None, None) sage: p.variable_lower_bound(0, 0) sage: p.col_bounds(0) (0, None)
-
col_name
(index)¶ Return the
index
-th column nameINPUT:
index
(integer) – the column idname
(char *
) – its name. When set toNULL
(default), the method returns the current name.
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.add_variable(name="I_am_a_variable") 0 sage: p.col_name(0) 'I_am_a_variable'
-
dictionary
()¶ Return a dictionary representing the current basis.
EXAMPLES:
sage: p = MixedIntegerLinearProgram(maximization=True, solver="InteractiveLP") sage: x = p.new_variable(nonnegative=True) sage: p.add_constraint(-x[0] + x[1] <= 2) sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) sage: p.set_objective(11/2 * x[0] - 3 * x[1]) sage: b = p.get_backend() sage: # Backend-specific commands to instruct solver to use simplex method here sage: b.solve() 0 sage: d = b.dictionary(); d LP problem dictionary ... sage: set(d.basic_variables()) {x1, x3} sage: d.basic_solution() (17/8, 0)
-
get_objective_value
()¶ Return the value of the objective function.
Note
Behavior is undefined unless
solve
has been called before.EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.add_variables(2) 1 sage: p.add_linear_constraint([(0,1), (1,2)], None, 3) sage: p.set_objective([2, 5]) sage: p.solve() 0 sage: p.get_objective_value() 15/2 sage: p.get_variable_value(0) 0 sage: p.get_variable_value(1) 3/2
-
get_variable_value
(variable)¶ Return the value of a variable given by the solver.
Note
Behavior is undefined unless
solve
has been called before.EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.add_variables(2) 1 sage: p.add_linear_constraint([(0,1), (1, 2)], None, 3) sage: p.set_objective([2, 5]) sage: p.solve() 0 sage: p.get_objective_value() 15/2 sage: p.get_variable_value(0) 0 sage: p.get_variable_value(1) 3/2
-
interactive_lp_problem
()¶ Return the
InteractiveLPProblem
object associated with this backend.EXAMPLES:
sage: p = MixedIntegerLinearProgram(maximization=True, solver="InteractiveLP") sage: x = p.new_variable(nonnegative=True) sage: p.add_constraint(-x[0] + x[1] <= 2) sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) sage: p.set_objective(11/2 * x[0] - 3 * x[1]) sage: b = p.get_backend() sage: b.interactive_lp_problem() LP problem ...
-
is_maximization
()¶ Test whether the problem is a maximization
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.is_maximization() True sage: p.set_sense(-1) sage: p.is_maximization() False
-
is_slack_variable_basic
(index)¶ Test whether the slack variable of the given row is basic.
This assumes that the problem has been solved with the simplex method and a basis is available. Otherwise an exception will be raised.
INPUT:
index
(integer) – the variable’s id
EXAMPLES:
sage: p = MixedIntegerLinearProgram(maximization=True, solver="InteractiveLP") sage: x = p.new_variable(nonnegative=True) sage: p.add_constraint(-x[0] + x[1] <= 2) sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) sage: p.set_objective(11/2 * x[0] - 3 * x[1]) sage: b = p.get_backend() sage: # Backend-specific commands to instruct solver to use simplex method here sage: b.solve() 0 sage: b.is_slack_variable_basic(0) True sage: b.is_slack_variable_basic(1) False
-
is_slack_variable_nonbasic_at_lower_bound
(index)¶ Test whether the given variable is nonbasic at lower bound.
This assumes that the problem has been solved with the simplex method and a basis is available. Otherwise an exception will be raised.
INPUT:
index
(integer) – the variable’s id
EXAMPLES:
sage: p = MixedIntegerLinearProgram(maximization=True, solver="InteractiveLP") sage: x = p.new_variable(nonnegative=True) sage: p.add_constraint(-x[0] + x[1] <= 2) sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) sage: p.set_objective(11/2 * x[0] - 3 * x[1]) sage: b = p.get_backend() sage: # Backend-specific commands to instruct solver to use simplex method here sage: b.solve() 0 sage: b.is_slack_variable_nonbasic_at_lower_bound(0) False sage: b.is_slack_variable_nonbasic_at_lower_bound(1) True
-
is_variable_basic
(index)¶ Test whether the given variable is basic.
This assumes that the problem has been solved with the simplex method and a basis is available. Otherwise an exception will be raised.
INPUT:
index
(integer) – the variable’s id
EXAMPLES:
sage: p = MixedIntegerLinearProgram(maximization=True, solver="InteractiveLP") sage: x = p.new_variable(nonnegative=True) sage: p.add_constraint(-x[0] + x[1] <= 2) sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) sage: p.set_objective(11/2 * x[0] - 3 * x[1]) sage: b = p.get_backend() sage: # Backend-specific commands to instruct solver to use simplex method here sage: b.solve() 0 sage: b.is_variable_basic(0) True sage: b.is_variable_basic(1) False
-
is_variable_binary
(index)¶ Test whether the given variable is of binary type.
INPUT:
index
(integer) – the variable’s id
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.ncols() 0 sage: p.add_variable() 0 sage: p.is_variable_binary(0) False
-
is_variable_continuous
(index)¶ Test whether the given variable is of continuous/real type.
INPUT:
index
(integer) – the variable’s id
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.ncols() 0 sage: p.add_variable() 0 sage: p.is_variable_continuous(0) True
-
is_variable_integer
(index)¶ Test whether the given variable is of integer type.
INPUT:
index
(integer) – the variable’s id
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.ncols() 0 sage: p.add_variable() 0 sage: p.is_variable_integer(0) False
-
is_variable_nonbasic_at_lower_bound
(index)¶ Test whether the given variable is nonbasic at lower bound.
This assumes that the problem has been solved with the simplex method and a basis is available. Otherwise an exception will be raised.
INPUT:
index
(integer) – the variable’s id
EXAMPLES:
sage: p = MixedIntegerLinearProgram(maximization=True, solver="InteractiveLP") sage: x = p.new_variable(nonnegative=True) sage: p.add_constraint(-x[0] + x[1] <= 2) sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) sage: p.set_objective(11/2 * x[0] - 3 * x[1]) sage: b = p.get_backend() sage: # Backend-specific commands to instruct solver to use simplex method here sage: b.solve() 0 sage: b.is_variable_nonbasic_at_lower_bound(0) False sage: b.is_variable_nonbasic_at_lower_bound(1) True
-
ncols
()¶ Return the number of columns/variables.
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.ncols() 0 sage: p.add_variables(2) 1 sage: p.ncols() 2
-
nrows
()¶ Return the number of rows/constraints.
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.nrows() 0 sage: p.add_linear_constraints(2, 0, None) sage: p.nrows() 2
-
objective_coefficient
(variable, coeff=None)¶ Set or get the coefficient of a variable in the objective function
INPUT:
variable
(integer) – the variable’s idcoeff
(double) – its coefficient
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.add_variable() 0 sage: p.objective_coefficient(0) 0 sage: p.objective_coefficient(0,2) sage: p.objective_coefficient(0) 2
-
objective_constant_term
(d=None)¶ Set or get the constant term in the objective function
INPUT:
d
(double) – its coefficient. If \(None\) (default), return the current value.
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.objective_constant_term() 0 sage: p.objective_constant_term(42) sage: p.objective_constant_term() 42
-
problem_name
(name=None)¶ Return or define the problem’s name
INPUT:
name
(str
) – the problem’s name. When set toNone
(default), the method returns the problem’s name.
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.problem_name("There_once_was_a_french_fry") sage: print(p.problem_name()) There_once_was_a_french_fry
-
remove_constraint
(i)¶ Remove a constraint.
INPUT:
i
– index of the constraint to remove.
EXAMPLES:
sage: p = MixedIntegerLinearProgram(solver="InteractiveLP") sage: v = p.new_variable(nonnegative=True) sage: x,y = v[0], v[1] sage: p.add_constraint(2*x + 3*y, max = 6) sage: p.add_constraint(3*x + 2*y, max = 6) sage: p.set_objective(x + y + 7) sage: p.solve() 47/5 sage: p.remove_constraint(0) sage: p.solve() 10 sage: p.get_values([x,y]) [0, 3]
-
row
(i)¶ Return a row
INPUT:
index
(integer) – the constraint’s id.
OUTPUT:
A pair
(indices, coeffs)
whereindices
lists the entries whose coefficient is nonzero, and to whichcoeffs
associates their coefficient on the model of theadd_linear_constraint
method.EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.add_variables(5) 4 sage: p.add_linear_constraint(zip(range(5), range(5)), 0, None) sage: p.row(0) ([1, 2, 3, 4], [1, 2, 3, 4])
-
row_bounds
(index)¶ Return the bounds of a specific constraint.
INPUT:
index
(integer) – the constraint’s id.
OUTPUT:
A pair
(lower_bound, upper_bound)
. Each of them can be set toNone
if the constraint is not bounded in the corresponding direction, and is a real value otherwise.EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.add_variables(5) 4 sage: p.add_linear_constraint(zip(range(5), range(5)), 2, 2) sage: p.row_bounds(0) (2, 2)
-
row_name
(index)¶ Return the
index
th row nameINPUT:
index
(integer) – the row’s id
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.add_linear_constraints(1, 2, None, names=['Empty constraint 1']) sage: p.row_name(0) 'Empty constraint 1'
-
set_objective
(coeff, d=0)¶ Set the objective function.
INPUT:
coeff
– a list of real values, whose i-th element is the coefficient of the i-th variable in the objective function.d
(real) – the constant term in the linear function (set to \(0\) by default)
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.add_variables(5) 4 sage: p.set_objective([1, 1, 2, 1, 3]) sage: [p.objective_coefficient(x) for x in range(5)] [1, 1, 2, 1, 3]
Constants in the objective function are respected:
sage: p = MixedIntegerLinearProgram(solver='InteractiveLP') sage: x,y = p[0], p[1] sage: p.add_constraint(2*x + 3*y, max = 6) sage: p.add_constraint(3*x + 2*y, max = 6) sage: p.set_objective(x + y + 7) sage: p.solve() 47/5
-
set_sense
(sense)¶ Set the direction (maximization/minimization).
INPUT:
sense
(integer) :- +1 => Maximization
- -1 => Minimization
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.is_maximization() True sage: p.set_sense(-1) sage: p.is_maximization() False
-
set_variable_type
(variable, vtype)¶ Set the type of a variable.
In this backend, variables are always continuous (real). If integer or binary variables are requested via the parameter
vtype
, an error will be raised.INPUT:
variable
(integer) – the variable’s idvtype
(integer) :1 Integer
0 Binary
-1 Continuous
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.ncols() 0 sage: p.add_variable() 0 sage: p.set_variable_type(0,-1) sage: p.is_variable_continuous(0) True
-
set_verbosity
(level)¶ Set the log (verbosity) level
INPUT:
level
(integer) – From 0 (no verbosity) to 3.
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.set_verbosity(2)
-
solve
()¶ 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…)EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.add_linear_constraints(5, 0, None) sage: p.add_col(list(range(5)), list(range(5))) sage: p.solve() 0 sage: p.objective_coefficient(0,1) sage: p.solve() Traceback (most recent call last): ... MIPSolverException: ...
-
variable_lower_bound
(index, value=False)¶ Return or define the lower bound on a variable
INPUT:
index
(integer) – the variable’s idvalue
– real value, orNone
to mean that the variable has no lower bound. When set toNone
(default), the method returns the current value.
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.add_variable(lower_bound=None) 0 sage: p.col_bounds(0) (None, None) sage: p.variable_lower_bound(0) is None True sage: p.variable_lower_bound(0, 0) sage: p.col_bounds(0) (0, None) sage: p.variable_lower_bound(0) 0 sage: p.variable_lower_bound(0, None) sage: p.variable_lower_bound(0) is None True
-
variable_upper_bound
(index, value=False)¶ Return or define the upper bound on a variable
INPUT:
index
(integer) – the variable’s idvalue
– real value, orNone
to mean that the variable has not upper bound. When set toNone
(default), the method returns the current value.
EXAMPLES:
sage: from sage.numerical.backends.generic_backend import get_solver sage: p = get_solver(solver = "InteractiveLP") sage: p.add_variable(lower_bound=None) 0 sage: p.col_bounds(0) (None, None) sage: p.variable_upper_bound(0) is None True sage: p.variable_upper_bound(0, 0) sage: p.col_bounds(0) (None, 0) sage: p.variable_upper_bound(0) 0 sage: p.variable_upper_bound(0, None) sage: p.variable_upper_bound(0) is None True
-