GLPK Backend
AUTHORS:
Bases: sage.numerical.backends.generic_backend.GenericBackend
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 = "GLPK")
sage: p.ncols()
0
sage: p.nrows()
0
sage: p.add_linear_constraints(5, 0, None)
sage: p.add_col(range(5), range(5))
sage: p.nrows()
5
Add a linear constraint.
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "GLPK")
sage: p.add_variables(5)
4
sage: p.add_linear_constraint( zip(range(5), range(5)), 2.0, 2.0)
sage: p.row(0)
([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0])
sage: p.row_bounds(0)
(2.0, 2.0)
sage: p.add_linear_constraint( zip(range(5), range(5)), 1.0, 1.0, name='foo')
sage: p.row_name(1)
'foo'
Add 'number linear constraints.
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "GLPK")
sage: p.add_variables(5)
4
sage: p.add_linear_constraints(5, None, 2)
sage: p.row(4)
([], [])
sage: p.row_bounds(4)
(None, 2.0)
sage: p.add_linear_constraints(2, None, 2, names=['foo','bar'])
Add a variable.
This amounts to adding a new column to the matrix. By default, the variable is both positive, real and the coefficient in the objective function is 0.0.
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 = "GLPK")
sage: p.ncols()
0
sage: p.add_variable()
0
sage: p.ncols()
1
sage: p.add_variable(binary=True)
1
sage: p.add_variable(lower_bound=-2.0, integer=True)
2
sage: p.add_variable(continuous=True, integer=True)
Traceback (most recent call last):
...
ValueError: ...
sage: p.add_variable(name='x',obj=1.0)
3
sage: p.col_name(3)
'x'
sage: p.objective_coefficient(3)
1.0
Add number new variables.
This amounts to adding new columns to the matrix. By default, the variables are both positive, real and theor coefficient in the objective function is 0.0.
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 = "GLPK")
sage: p.ncols()
0
sage: p.add_variables(5)
4
sage: p.ncols()
5
sage: p.add_variables(2, lower_bound=-2.0, integer=True, names=['a','b'])
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 = "GLPK")
sage: p.add_variable()
0
sage: p.col_bounds(0)
(0.0, None)
sage: p.variable_upper_bound(0, 5)
sage: p.col_bounds(0)
(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 = "GLPK")
sage: p.add_variable(name='I am a variable')
0
sage: p.col_name(0)
'I am a variable'
Returns a copy of self.
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = MixedIntegerLinearProgram(solver = "GLPK")
sage: b = p.new_variable()
sage: p.add_constraint(b[1] + b[2] <= 6)
sage: p.set_objective(b[1] + b[2])
sage: copy(p).solve()
6.0
Returns the dual value (reduced cost) of a variable
The dual value is the reduced cost of a variable. The reduced cost is the amount by which the objective coefficient of a non basic variable has to change to become a basic variable.
INPUT:
Note
Behaviour is undefined unless solve has been called before. If the simplex algorithm has not been used for solving just a 0.0 will be returned.
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "GLPK")
sage: p.add_variables(3)
2
sage: p.add_linear_constraint(zip([0, 1, 2], [8, 6, 1]), None, 48)
sage: p.add_linear_constraint(zip([0, 1, 2], [4, 2, 1.5]), None, 20)
sage: p.add_linear_constraint(zip([0, 1, 2], [2, 1.5, 0.5]), None, 8)
sage: p.set_objective([60, 30, 20])
sage: import sage.numerical.backends.glpk_backend as backend
sage: p.solver_parameter(backend.glp_simplex_or_intopt, backend.glp_simplex_only)
sage: p.solve()
0
sage: p.get_col_dual(1)
-5.0
Returns 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 = "GLPK")
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()
7.5
sage: p.get_variable_value(0)
0.0
sage: p.get_variable_value(1)
1.5
Returns the dual value of a constraint.
The dual value of the ith row is also the value of the ith variable of the dual problem.
The dual value of a constraint is the shadow price of the constraint. The shadow price is the amount by which the objective value will change if the constraints bounds change by one unit under the precondition that the basis remains the same.
INPUT:
Note
Behaviour is undefined unless solve has been called before. If the simplex algorithm has not been used for solving 0.0 will be returned.
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: lp = get_solver(solver = "GLPK")
sage: lp.add_variables(3)
2
sage: lp.add_linear_constraint(zip([0, 1, 2], [8, 6, 1]), None, 48)
sage: lp.add_linear_constraint(zip([0, 1, 2], [4, 2, 1.5]), None, 20)
sage: lp.add_linear_constraint(zip([0, 1, 2], [2, 1.5, 0.5]), None, 8)
sage: lp.set_objective([60, 30, 20])
sage: import sage.numerical.backends.glpk_backend as backend
sage: lp.solver_parameter(backend.glp_simplex_or_intopt, backend.glp_simplex_only)
sage: lp.solve()
0
sage: lp.get_row_dual(0) # tolerance 0.00001
0.0
sage: lp.get_row_dual(1) # tolerance 0.00001
10.0
Returns 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 = "GLPK")
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()
7.5
sage: p.get_variable_value(0)
0.0
sage: p.get_variable_value(1)
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 = "GLPK")
sage: p.is_maximization()
True
sage: p.set_sense(-1)
sage: p.is_maximization()
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 = "GLPK")
sage: p.ncols()
0
sage: p.add_variable()
0
sage: p.set_variable_type(0,0)
sage: p.is_variable_binary(0)
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 = "GLPK")
sage: p.ncols()
0
sage: p.add_variable()
0
sage: p.is_variable_continuous(0)
True
sage: p.set_variable_type(0,1)
sage: p.is_variable_continuous(0)
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 = "GLPK")
sage: p.ncols()
0
sage: p.add_variable()
0
sage: p.set_variable_type(0,1)
sage: p.is_variable_integer(0)
True
Return the number of columns/variables.
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "GLPK")
sage: p.ncols()
0
sage: p.add_variables(2)
1
sage: p.ncols()
2
Return the number of rows/constraints.
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "GLPK")
sage: p.nrows()
0
sage: p.add_linear_constraints(2, 2, None)
sage: p.nrows()
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 = "GLPK")
sage: p.add_variable()
0
sage: p.objective_coefficient(0)
0.0
sage: p.objective_coefficient(0,2)
sage: p.objective_coefficient(0)
2.0
Print results of a sensitivity analysis
If no filename is given as an input the results of the sensitivity analysis are displayed on the screen. If a filename is given they are written to a file.
INPUT:
OUTPUT:
Zero if the operations was successful otherwise nonzero.
Note
This method is only effective if an optimal solution has been found for the lp using the simplex algorithm. In all other cases an error message is printed.
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "GLPK")
sage: p.add_variables(2)
1
sage: p.add_linear_constraint(zip([0, 1], [1, 2]), None, 3)
sage: p.set_objective([2, 5])
sage: import sage.numerical.backends.glpk_backend as backend
sage: p.solver_parameter(backend.glp_simplex_or_intopt, backend.glp_simplex_only)
sage: p.print_ranges()
glp_print_ranges: optimal basic solution required
1
sage: p.solve()
0
sage: p.print_ranges()
Write sensitivity analysis report to...
GLPK ... - SENSITIVITY ANALYSIS REPORT Page 1
Problem:
Objective: 7.5 (MAXimum)
No. Row name St Activity Slack Lower bound Activity Obj coef Obj value at Limiting
Marginal Upper bound range range break point variable
------ ------------ -- ------------- ------------- ------------- ------------- ------------- ------------- ------------
1 NU 3.00000 . -Inf . -2.50000 .
2.50000 3.00000 +Inf +Inf +Inf
GLPK ... - SENSITIVITY ANALYSIS REPORT Page 2
Problem:
Objective: 7.5 (MAXimum)
No. Column name St Activity Obj coef Lower bound Activity Obj coef Obj value at Limiting
Marginal Upper bound range range break point variable
------ ------------ -- ------------- ------------- ------------- ------------- ------------- ------------- ------------
1 NL . 2.00000 . -Inf -Inf +Inf
-.50000 +Inf 3.00000 2.50000 6.00000
2 BS 1.50000 5.00000 . -Inf 4.00000 6.00000
. +Inf 1.50000 +Inf +Inf
End of report
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 = "GLPK")
sage: p.problem_name("There once was a french fry")
sage: print p.problem_name()
There once was a french fry
Remove a constraint from self.
INPUT:
EXAMPLE:
sage: p = MixedIntegerLinearProgram(solver='GLPK')
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.set_integer(x); p.set_integer(y)
sage: p.solve()
9.0
sage: p.remove_constraint(0)
sage: p.solve()
10.0
Removing fancy constraints does not make Sage crash:
sage: MixedIntegerLinearProgram(solver = "GLPK").remove_constraint(-2)
Traceback (most recent call last):
...
ValueError: The constraint's index i must satisfy 0 <= i < number_of_constraints
Remove several constraints.
INPUT:
EXAMPLE:
sage: p = MixedIntegerLinearProgram(solver='GLPK')
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.set_integer(x); p.set_integer(y)
sage: p.solve()
9.0
sage: p.remove_constraints([1])
sage: p.solve()
10.0
sage: p.get_values([x,y])
[3.0, 0.0]
TESTS:
Removing fancy constraints does not make Sage crash:
sage: MixedIntegerLinearProgram(solver= "GLPK").remove_constraints([0, -2])
Traceback (most recent call last):
...
ValueError: The constraint's index i must satisfy 0 <= i < number_of_constraints
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 = "GLPK")
sage: p.add_variables(5)
4
sage: p.add_linear_constraint(zip(range(5), range(5)), 2, 2)
sage: p.row(0)
([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0])
sage: p.row_bounds(0)
(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 = "GLPK")
sage: p.add_variables(5)
4
sage: p.add_linear_constraint(zip(range(5), range(5)), 2, 2)
sage: p.row(0)
([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0])
sage: p.row_bounds(0)
(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 = "GLPK")
sage: p.add_linear_constraints(1, 2, None, names=['Empty constraint 1'])
sage: p.row_name(0)
'Empty constraint 1'
Set the objective function.
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "GLPK")
sage: p.add_variables(5)
4
sage: p.set_objective([1, 1, 2, 1, 3])
sage: map(lambda x :p.objective_coefficient(x), range(5))
[1.0, 1.0, 2.0, 1.0, 3.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 = "GLPK")
sage: p.is_maximization()
True
sage: p.set_sense(-1)
sage: p.is_maximization()
False
Set the type of a variable
INPUT:
variable (integer) – the variable’s id
vtype (integer) :
- 1 Integer
- 0 Binary
- -1 Real
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "GLPK")
sage: p.ncols()
0
sage: p.add_variable()
0
sage: p.set_variable_type(0,1)
sage: p.is_variable_integer(0)
True
Set the verbosity level
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "GLPK")
sage: p.set_verbosity(2)
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 = "GLPK")
sage: p.add_linear_constraints(5, 0, None)
sage: p.add_col(range(5), range(5))
sage: p.solve()
0
sage: p.objective_coefficient(0,1)
sage: p.solve()
Traceback (most recent call last):
...
MIPSolverException: ...
Warning
Sage uses GLPK’s glp_intopt to find solutions. This routine sometimes FAILS CATASTROPHICALLY when given a system it cannot solve. (Ticket #12309.) Here, “catastrophic” can mean either “infinite loop” or segmentation fault. Upstream considers this behavior “essentially innate” to their design, and suggests preprocessing it with glpk_simplex first. Thus, if you suspect that your system is infeasible, set the preprocessing option first.
EXAMPLE:
sage: lp = MixedIntegerLinearProgram(solver = "GLPK")
sage: lp.add_constraint( lp[1] +lp[2] -2.0 *lp[3] , max =-1.0)
sage: lp.add_constraint( lp[0] -4.0/3 *lp[1] +1.0/3 *lp[2] , max =-1.0/3)
sage: lp.add_constraint( lp[0] +0.5 *lp[1] -0.5 *lp[2] +0.25 *lp[3] , max =-0.25)
sage: lp.solve()
0.0
sage: lp.add_constraint( lp[0] +4.0 *lp[1] -lp[2] +lp[3] , max =-1.0)
sage: lp.solve()
Traceback (most recent call last):
...
RuntimeError: GLPK : Signal sent, try preprocessing option
sage: lp.solver_parameter("simplex_or_intopt", "simplex_then_intopt")
sage: lp.solve()
Traceback (most recent call last):
...
MIPSolverException: 'GLPK : Simplex cannot find a feasible solution'
The user can ask sage to solve via simplex or intopt. The default solver is intopt, so we get integer solutions.
sage: lp = MixedIntegerLinearProgram(solver = ‘GLPK’, maximization = False) sage: x, y = lp[0], lp[1] sage: lp.add_constraint(-2*x + y <= 1) sage: lp.add_constraint(x - y <= 1) sage: lp.add_constraint(x + y >= 2) sage: lp.set_objective(x + y) sage: lp.set_integer(x) sage: lp.set_integer(y) sage: lp.solve() 2.0 sage: lp.get_values([x, y]) [1.0, 1.0]
If we switch to simplex, we get continuous solutions.
sage: lp.solver_parameter(“simplex_or_intopt”, “simplex_only”) # use simplex only sage: lp.solve() 2.0 sage: lp.get_values([x, y]) [1.5, 0.5]
Return or define a solver parameter
INPUT:
You can supply the name of a parameter and its value using either a string or a glp_ constant (which are defined as Cython variables of this module).
In most cases, you can use the same name for a parameter as that given in the GLPK documentation, which is available by downloading GLPK from <http://www.gnu.org/software/glpk/>. The exceptions relate to parameters common to both methods; these require you to append _simplex or _intopt to the name to resolve ambiguity, since the interface allows access to both.
We have also provided more meaningful names, to assist readability.
Parameter names are specified in lower case. To use a constant instead of a string, prepend glp_ to the name. For example, both glp_gmi_cuts or "gmi_cuts" control whether to solve using Gomory cuts.
Parameter values are specificed as strings in upper case, or as constants in lower case. For example, both glp_on and "GLP_ON" specify the same thing.
Naturally, you can use True and False in cases where glp_on and glp_off would be used.
A list of parameter names, with their possible values:
General-purpose parameters:
timelimit | specify the time limit IN SECONDS. This affects both simplex and intopt. |
timelimit_simplex and timelimit_intopt | specify the time limit IN MILLISECONDS. (This is glpk’s default.) |
simplex_or_intopt | whether to use the simplex or intopt routines in GLPK. This is controlled by using glp_simplex_only, glp_intopt_only, and glp_simplex_then_intopt. The latter is useful to deal with a problem in GLPK where problems with no solution hang when using integer optimization; if you specify glp_simplex_then_intopt, sage will try simplex first, then perform integer optimization only if a solution of the LP relaxation exists. |
verbosity_intopt and verbosity_simplex | one of GLP_MSG_OFF, GLP_MSG_ERR, GLP_MSG_ON, or GLP_MSG_ALL. The default is GLP_MSG_OFF. |
output_frequency_intopt and output_frequency_simplex | the output frequency, in milliseconds. Default is 5000. |
output_delay_intopt and output_delay_simplex | the output delay, in milliseconds, regarding the use of the simplex method on the LP relaxation. Default is 10000. |
intopt-specific parameters:
branching |
|
backtracking |
|
preprocessing |
|
feasibility_pump | GLP_ON or GLP_OFF (default) |
gomory_cuts | GLP_ON or GLP_OFF (default) |
mixed_int_rounding_cuts | GLP_ON or GLP_OFF (default) |
mixed_cover_cuts | GLP_ON or GLP_OFF (default) |
clique_cuts | GLP_ON or GLP_OFF (default) |
absolute_tolerance | (double) used to check if optimal solution to LP relaxation is integer feasible. GLPK manual advises, “do not change... without detailed understanding of its purpose.” |
relative_tolerance | (double) used to check if objective value in LP relaxation is not better than best known integer solution. GLPK manual advises, “do not change... without detailed understanding of its purpose.” |
mip_gap_tolerance | (double) relative mip gap tolerance. Default is 0.0. |
presolve_intopt | GLP_ON (default) or GLP_OFF. |
binarize | GLP_ON or GLP_OFF (default) |
simplex-specific parameters:
primal_v_dual |
|
pricing |
|
ratio_test |
|
tolerance_primal | (double) tolerance used to check if basic solution is primal feasible. GLPK manual advises, “do not change... without detailed understanding of its purpose.” |
tolerance_dual | (double) tolerance used to check if basic solution is dual feasible. GLPK manual advises, “do not change... without detailed understanding of its purpose.” |
tolerance_pivot | (double) tolerance used to choose pivot. GLPK manual advises, “do not change... without detailed understanding of its purpose.” |
obj_lower_limit | (double) lower limit of the objective function. The default is -DBL_MAX. |
obj_upper_limit | (double) upper limit of the objective function. The default is DBL_MAX. |
iteration_limit | (int) iteration limit of the simplex algorithm. The default is INT_MAX. |
presolve_simplex | GLP_ON or GLP_OFF (default). |
Note
The coverage for GLPK’s control parameters for simplex and integer optimization is nearly complete. The only thing lacking is a wrapper for callback routines.
To date, no attempt has been made to expose the interior point methods.
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "GLPK")
sage: p.solver_parameter("timelimit", 60)
sage: p.solver_parameter("timelimit")
60.0
sage: p.solver_parameter("timelimit_intopt")
60000
If you don’t care for an integer answer, you can ask for an lp relaxation instead. The default solver performs integer optimization, but you can switch to the standard simplex algorithm through the glp_simplex_or_intopt parameter.
EXAMPLE:
sage: lp = MixedIntegerLinearProgram(solver = 'GLPK', maximization = False)
sage: x, y = lp[0], lp[1]
sage: lp.add_constraint(-2*x + y <= 1)
sage: lp.add_constraint(x - y <= 1)
sage: lp.add_constraint(x + y >= 2)
sage: lp.set_integer(x); lp.set_integer(y)
sage: lp.set_objective(x + y)
sage: lp.solve()
2.0
sage: lp.get_values([x,y])
[1.0, 1.0]
sage: import sage.numerical.backends.glpk_backend as backend
sage: lp.solver_parameter(backend.glp_simplex_or_intopt, backend.glp_simplex_only)
sage: lp.solve()
2.0
sage: lp.get_values([x,y])
[1.5, 0.5]
You can get glpk to spout all sorts of information at you. The default is to turn this off, but sometimes (debugging) it’s very useful:
sage: lp.solver_parameter(backend.glp_simplex_or_intopt, backend.glp_simplex_then_intopt)
sage: lp.solver_parameter(backend.glp_mir_cuts, backend.glp_on)
sage: lp.solver_parameter(backend.glp_msg_lev_intopt, backend.glp_msg_all)
sage: lp.solver_parameter(backend.glp_mir_cuts)
1
If you actually try to solve lp, you will get a lot of detailed information.
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 = "GLPK")
sage: p.add_variable()
0
sage: p.col_bounds(0)
(0.0, None)
sage: p.variable_lower_bound(0, 5)
sage: p.col_bounds(0)
(5.0, None)
TESTS:
sage: P = MixedIntegerLinearProgram(solver="GLPK")
sage: x = P["x"]
sage: P.set_min(x, 5)
sage: P.set_min(x, 0)
sage: P.get_min(x)
0.0
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 = "GLPK")
sage: p.add_variable()
0
sage: p.col_bounds(0)
(0.0, None)
sage: p.variable_upper_bound(0, 5)
sage: p.col_bounds(0)
(0.0, 5.0)
TESTS:
sage: P = MixedIntegerLinearProgram(solver="GLPK")
sage: x = P["x"]
sage: P.set_max(x, 0)
sage: P.get_max(x)
0.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 = "GLPK")
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.write_lp(os.path.join(SAGE_TMP, "lp_problem.lp"))
Writing problem data to ...
9 lines were written
Write the problem to a .mps file
INPUT:
EXAMPLE:
sage: from sage.numerical.backends.generic_backend import get_solver
sage: p = get_solver(solver = "GLPK")
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.write_mps(os.path.join(SAGE_TMP, "lp_problem.mps"), 2)
Writing problem data to...
17 records were written