### Navigation

- index
- modules |
- next |
- previous |
- Numerical Optimization »

# GLPK Backend

GLPK Backend

AUTHORS:

- Nathann Cohen (2010-10): initial implementation
- John Perry (2012-01): glp_simplex preprocessing
- John Perry and Raniere Gaia Silva (2012-03): solver parameters
- Christian Kuper (2012-10): Additions for sensitivity analysis

class `sage.numerical.backends.glpk_backend.``GLPKBackend`

  Bases: `sage.numerical.backends.generic_backend.GenericBackend`

  x.__init__(...) initializes x; see help(type(x)) for signature

  `add_col`(indices, coeffs)

    Add a column.

    INPUT:

    - `indices` (list of integers) – this list constains the indices of the constraints in which the variable’s coefficient is nonzero
    - `coeffs` (list of real values) – associates a coefficient to the variable in each of the constraints in which it appears. Namely, the ith entry of `coeffs` corresponds to the coefficient of the variable in the constraint represented by the ith entry in `indices`.

    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_linear_constraint`(coefficients, lower_bound, upper_bound, name=None)

    Add a linear constraint.

    INPUT:

    - `coefficients` an iterable with `(c,v)` pairs where `c` is a variable index (integer) and `v` is a value (real value).
    - `lower_bound` - a lower bound, either a real value or `None`
    - `upper_bound` - an upper bound, either a real value or `None`
    - `name` - an optional name for this row (default: `None`)

    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_linear_constraints`(number, lower_bound, upper_bound, names=None)

    Add `'number` linear constraints.

    INPUT:

    - `number` (integer) – the number of constraints to add.
    - `lower_bound` - a lower bound, either a real value or `None`
    - `upper_bound` - an upper bound, either a real value or `None`
    - `names` - an optional list of names (default: `None`)

    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_variable`(lower_bound=0.0, upper_bound=None, binary=False, continuous=False, integer=False, obj=0.0, name=None)

    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:

    - `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.0)
    - `name` - an optional name for the newly added variable (default: `None`).

    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_variables`(number, lower_bound=0.0, upper_bound=None, binary=False, continuous=False, integer=False, obj=0.0, names=None)

    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:

    - `n` - the number of new variables (must be > 0)
    - `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 all variables in the objective function (default: 0.0)
    - `names` - optional list of names (default: `None`)

    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

  `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 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)

  `col_name`(index)

    Return the `index` th col name

    INPUT:

    - `index` (integer) – the col’s id

    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'

  `copy`()

    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

  `get_col_dual`(variable)

    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:

    - `variable` – The number of the variable

    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

  `get_objective_value`()

    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

  `get_row_dual`(variable)

    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:

    - `variable` – The number of the constraint

    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

  `get_variable_value`(variable)

    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

  `is_maximization`()

    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

  `is_variable_binary`(index)

    Test whether the given variable is of binary type.

    INPUT:

    - `index` (integer) – the variable’s id

    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

  `is_variable_continuous`(index)

    Test whether the given variable is of continuous/real type.

    INPUT:

    - `index` (integer) – the variable’s id

    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

  `is_variable_integer`(index)

    Test whether the given variable is of integer type.

    INPUT:

    - `index` (integer) – the variable’s id

    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

  `ncols`()

    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

  `nrows`()

    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

  `objective_coefficient`(variable, coeff=None)

    Set or get the coefficient of a variable in the objective function

    INPUT:

    - `variable` (integer) – the variable’s id
    - `coeff` (double) – its coefficient or `None` for reading (default: `None`)

    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_ranges`(filename='NULL')

    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:

    - `filename` – (optional) name of the file

    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
        <BLANKLINE>
        Problem:
        Objective:  7.5 (MAXimum)
        <BLANKLINE>
           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
        <BLANKLINE>
        GLPK ... - SENSITIVITY ANALYSIS REPORT                                                                         Page   2
        <BLANKLINE>
        Problem:
        Objective:  7.5 (MAXimum)
        <BLANKLINE>
           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
        <BLANKLINE>
             2              BS       1.50000       5.00000        .                -Inf       4.00000       6.00000
                                                    .               +Inf        1.50000          +Inf          +Inf
        <BLANKLINE>
        End of report
        <BLANKLINE>
        0

  `problem_name`(name='NULL')

    Return or define the problem’s name

    INPUT:

    - `name` (`char *`) – the problem’s name. When set to `NULL` (default), the method returns the problem’s name.

    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_constraint`(i)

    Remove a constraint from self.

    INPUT:

    - `i` – index of the constraint to remove

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram(solver='GLPK')
        sage: x,y = p[0], p[1]
        doctest:...: DeprecationWarning: The default value of 'nonnegative' will change, to False instead of True. You should add the explicit 'nonnegative=True'.
        See http://trac.sagemath.org/15521 for details.
        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_constraints`(constraints)

    Remove several constraints.

    INPUT:

    - `constraints` – an iterable containing the indices of the rows to remove.

    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

  `row`(index)

    Return a row

    INPUT:

    - `index` (integer) – the constraint’s id.

    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)

  `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 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)

  `row_name`(index)

    Return the `index` th row name

    INPUT:

    - `index` (integer) – the row’s id

    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_objective`(coeff, d=0.0)

    Set the objective function.

    INPUT:

    - `coeff` - a list of real values, whose ith element is the coefficient of the ith variable in the objective function.
    - `d` (double) – the constant term in the linear function (set to \(0\) by default)

    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_sense`(sense)

    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_variable_type`(variable, vtype)

    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_verbosity`(level)

    Set the verbosity level

    INPUT:

    - `level` (integer) – From 0 (no verbosity) to 3.

    EXAMPLE:

        sage: from sage.numerical.backends.generic_backend import get_solver
        sage: p = get_solver(solver = "GLPK")
        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...)

    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.

    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_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.

    EXAMPLE:

        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]

  `solver_parameter`(name, value=None)

    Return or define a solver parameter

    INPUT:

    - `name` (string) – the parameter
    - `value` – the parameter’s value if it is to be defined, or `None` (default) to obtain its current value.

    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` | `GLP_BR_FFV` first fractional variable `GLP_BR_LFV` last fractional variable `GLP_BR_MFV` most fractional variable `GLP_BR_DTH` Driebeck-Tomlin heuristic (default) `GLP_BR_PCH` hybrid pseudocost heuristic
    `backtracking` | `GLP_BT_DFS` depth first search `GLP_BT_BFS` breadth first search `GLP_BT_BLB` best local bound (default) `GLP_BT_BPH` best projection heuristic
    `preprocessing` | `GLP_PP_NONE` `GLP_PP_ROOT` preprocessing only at root level `GLP_PP_ALL` (default)
    `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` | `GLP_PRIMAL` (default) `GLP_DUAL` `GLP_DUALP`
    `pricing` | `GLP_PT_STD` standard (textbook) `GLP_PT_PSE` projected steepest edge (default)
    `ratio_test` | `GLP_RT_STD` standard (textbook) `GLP_RT_HAR` Harris’ two-pass ratio test (default)
    `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

    - Don’t forget the difference between `timelimit` and `timelimit_intopt`

        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.

  `variable_lower_bound`(index, value=False)

    Return or define the lower bound on a variable

    INPUT:

    - `index` (integer) – the variable’s id
    - `value` – real value, or `None` to mean that the variable has not lower bound. When set to `False` (default), the method returns the current value.

    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:

    trac ticket #14581:

        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

  `variable_upper_bound`(index, value=False)

    Return or define the upper bound on a variable

    INPUT:

    - `index` (integer) – the variable’s id
    - `value` – real value, or `None` to mean that the variable has not upper bound. When set to `False` (default), the method returns the current value.

    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:

    trac ticket #14581:

        sage: P = MixedIntegerLinearProgram(solver="GLPK")
        sage: x = P["x"]
        sage: P.set_max(x, 0)
        sage: P.get_max(x)
        0.0

  `write_lp`(filename)

    Write the problem to a .lp file

    INPUT:

    - `filename` (string)

    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_mps`(filename, modern)

    Write the problem to a .mps file

    INPUT:

    - `filename` (string)

    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

### Navigation

- index
- modules |
- next |
- previous |
- Numerical Optimization »