### Navigation

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

# Mixed Integer Linear Programming

Mixed Integer Linear Programming

A linear program (LP) is an optimization problem in the following form

\[\max \{ c^T x \;|\; A x \leq b, x \geq 0 \}\]

with given \(A \in \mathbb{R}^{m,n}\), \(b \in \mathbb{R}^m\), \(c \in \mathbb{R}^n\) and unknown \(x \in \mathbb{R}^{n}\). If some or all variables in the vector \(x\) are restricted over the integers \(\mathbb{Z}\), the problem is called mixed integer linear program (MILP). A wide variety of problems in optimization can be formulated in this standard form. Then, solvers are able to calculate a solution.

Imagine you want to solve the following linear system of three equations:

> - \(w_0 + w_1 + w_2 - 14 w_3 = 0\)
> - \(w_1 + 2 w_2 - 8 w_3 = 0\)
> - \(2 w_2 - 3 w_3 = 0\)

and this additional inequality:

> - \(w_0 - w_1 - w_2 \geq 0\)

where all \(w_i \in \mathbb{Z}^+\). You know that the trivial solution is \(w_i=0\), but what is the first non-trivial one with \(w_3 \geq 1\)?

A mixed integer linear program can give you an answer:

> 1. You have to create an instance of `MixedIntegerLinearProgram` and – in our case – specify that it is a minimization.
> 2. Create an dictionary `w` of integer variables `w` via `w = p.new_variable(integer=True)` (note that by default all variables are non-negative, cf `new_variable()`).
> 3. Add those three equations as equality constraints via `add_constraint`.
> 4. Also add the inequality constraint.
> 5. Add an inequality constraint \(w_3 \geq 1\) to exclude the trivial solution.
> 6. By default, all variables are non-negative. We remove that constraint via `p.set_min(variable, None)`, see `set_min`.
> 7. Specify the objective function via `set_objective`. In our case that is just \(w_3\). If it is a pure constraint satisfaction problem, specify it as `None`.
> 8. To check if everything is set up correctly, you can print the problem via `show`.
> 9. `Solve` it and print the solution.

The following example shows all these steps:

    sage: p = MixedIntegerLinearProgram(maximization=False, solver = "GLPK")
    sage: w = p.new_variable(integer=True, nonnegative=True)
    sage: p.add_constraint(w[0] + w[1] + w[2] - 14*w[3] == 0)
    sage: p.add_constraint(w[1] + 2*w[2] - 8*w[3] == 0)
    sage: p.add_constraint(2*w[2] - 3*w[3] == 0)
    sage: p.add_constraint(w[0] - w[1] - w[2] >= 0)
    sage: p.add_constraint(w[3] >= 1)
    sage: _ = [ p.set_min(w[i], None) for i in range(1,4) ]
    sage: p.set_objective(w[3])
    sage: p.show()
    Minimization:
       x_3
    Constraints:
      0.0 <= x_0 + x_1 + x_2 - 14.0 x_3 <= 0.0
      0.0 <= x_1 + 2.0 x_2 - 8.0 x_3 <= 0.0
      0.0 <= 2.0 x_2 - 3.0 x_3 <= 0.0
      - x_0 + x_1 + x_2 <= 0.0
      - x_3 <= -1.0
    Variables:
      x_0 is an integer variable (min=0.0, max=+oo)
      x_1 is an integer variable (min=-oo, max=+oo)
      x_2 is an integer variable (min=-oo, max=+oo)
      x_3 is an integer variable (min=-oo, max=+oo)
    sage: print 'Objective Value:', p.solve()
    Objective Value: 2.0
    sage: for i, v in p.get_values(w).iteritems():
    ....:     print 'w_%s = %s' % (i, int(round(v)))
    w_0 = 15
    w_1 = 10
    w_2 = 3
    w_3 = 2

Different backends compute with different base fields, for example:

    sage: p = MixedIntegerLinearProgram(solver='GLPK')
    sage: p.base_ring()
    Real Double Field
    sage: x = p.new_variable(real=True, nonnegative=True)
    sage: 0.5 + 3/2*x[1]
    0.5 + 1.5*x_0

    sage: p = MixedIntegerLinearProgram(solver='ppl')
    sage: p.base_ring()
    Rational Field
    sage: x = p.new_variable(nonnegative=True)
    sage: 0.5 + 3/2*x[1]
    1/2 + 3/2*x_0

## Linear Variables and Expressions

The underlying linear programming backends always work with matrices where each column corresponds to a linear variable. These variables can be accessed using the `MixedIntegerLinearProgram.gen()` method or by calling with a dictionary variable index to coefficient:

    sage: mip = MixedIntegerLinearProgram()
    sage: 5 + mip.gen(0) + 2*mip.gen(1)
    5 + x_0 + 2*x_1
    sage: mip({-1:5, 0:1, 1:2})
    5 + x_0 + 2*x_1

However, this alone is often not convenient to construct a linear program. To make your code more readable, you can construct `MIPVariable` objects that can be arbitrarily named and indexed. Internally, this is then translated back to the \(x_i\) variables. For example:

    sage: mip.<a,b> = MixedIntegerLinearProgram()
    sage: a
    MIPVariable of dimension 1.
    sage: 5 + a[1] + 2*b[3]
    5 + x_0 + 2*x_1

Indices can be any object, not necessarily integers. Multi-indices are also allowed:

    sage: a[4, 'string', QQ]
    x_2
    sage: a[4, 'string', QQ] - 7*b[2]
    x_2 - 7*x_3
    sage: mip.show()
    Maximization:
    <BLANKLINE>
    Constraints:
    Variables:
      a[1] = x_0 is a continuous variable (min=-oo, max=+oo)
      b[3] = x_1 is a continuous variable (min=-oo, max=+oo)
      a[(4, 'string', Rational Field)] = x_2 is a continuous variable (min=-oo, max=+oo)
      b[2] = x_3 is a continuous variable (min=-oo, max=+oo)

## Index of functions and methods

Below are listed the methods of `MixedIntegerLinearProgram`. This module also implements the `MIPSolverException` exception, as well as the `MIPVariable` class.

`add_constraint()` | Adds a constraint to the `MixedIntegerLinearProgram`
`base_ring()` | Return the base ring
`constraints()` | Returns a list of constraints, as 3-tuples
`get_backend()` | Returns the backend instance used
`get_max()` | Returns the maximum value of a variable
`get_min()` | Returns the minimum value of a variable
`get_values()` | Return values found by the previous call to `solve()`
`is_binary()` | Tests whether the variable `e` is binary
`is_integer()` | Tests whether the variable is an integer
`is_real()` | Tests whether the variable is real
`linear_constraints_parent()` | Return the parent for all linear constraints
`linear_function()` | Construct a new linear function
`linear_functions_parent()` | Return the parent for all linear functions
`new_variable()` | Returns an instance of `MIPVariable` associated
`number_of_constraints()` | Returns the number of constraints assigned so far
`number_of_variables()` | Returns the number of variables used so far
`polyhedron()` | Returns the polyhedron defined by the Linear Program
`remove_constraint()` | Removes a constraint from self
`remove_constraints()` | Remove several constraints
`set_binary()` | Sets a variable or a `MIPVariable` as binary
`set_integer()` | Sets a variable or a `MIPVariable` as integer
`set_max()` | Sets the maximum value of a variable
`set_min()` | Sets the minimum value of a variable
`set_objective()` | Sets the objective of the `MixedIntegerLinearProgram`
`set_problem_name()` | Sets the name of the `MixedIntegerLinearProgram`
`set_real()` | Sets a variable or a `MIPVariable` as real
`show()` | Displays the `MixedIntegerLinearProgram` in a human-readable
`solve()` | Solves the `MixedIntegerLinearProgram`
`solver_parameter()` | Return or define a solver parameter
`sum()` | Efficiently computes the sum of a sequence of LinearFunction elements
`write_lp()` | Write the linear program as a LP file
`write_mps()` | Write the linear program as a MPS file

AUTHORS:

- Risan (2012/02): added extension for exact computation

exception `sage.numerical.mip.``MIPSolverException`(value)

  Bases: `exceptions.RuntimeError`

  Exception raised when the solver fails.

class `sage.numerical.mip.``MIPVariable`

  Bases: `sage.structure.element.Element`

  `MIPVariable` is a variable used by the class `MixedIntegerLinearProgram`.

  Warning

  You should not instantiate this class directly. Instead, use `MixedIntegerLinearProgram.new_variable()`.

  `depth`()

    Returns the current variable’s depth.

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram()
        sage: v = p.new_variable(nonnegative=True)
        sage: p.set_objective(v[0] + v[1])
        sage: v.depth()
        1

  `items`()

    Returns the pairs (keys,value) contained in the dictionary.

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram()
        sage: v = p.new_variable(nonnegative=True)
        sage: p.set_objective(v[0] + v[1])
        sage: v.items()
        [(0, x_0), (1, x_1)]

  `keys`()

    Returns the keys already defined in the dictionary.

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram()
        sage: v = p.new_variable(nonnegative=True)
        sage: p.set_objective(v[0] + v[1])
        sage: v.keys()
        [0, 1]

  `set_max`(max)

    Sets an upper bound on the variable.

    INPUT:

    - `max` – an upper bound, or `None` to mean that the variable is unbounded.

    EXAMPLES:

        sage: p = MixedIntegerLinearProgram()
        sage: v = p.new_variable(real=True, nonnegative=True, dim=2)
        sage: p.get_max(v)
        sage: p.get_max(v[0])
        sage: p.get_max(v[0][0])
        sage: p.set_max(v,4)
        sage: p.get_max(v)
        4
        sage: p.get_max(v[0])
        4
        sage: p.get_max(v[0][0])
        4.0

  `set_min`(min)

    Sets a lower bound on the variable.

    INPUT:

    - `min` – a lower bound, or `None` to mean that the variable is unbounded.

    EXAMPLES:

        sage: p = MixedIntegerLinearProgram()
        sage: v = p.new_variable(real=True, nonnegative=True, dim=2)
        sage: p.get_min(v)
        0
        sage: p.get_min(v[0])
        0
        sage: p.get_min(v[0][0])
        0.0
        sage: p.set_min(v,4)
        sage: p.get_min(v)
        4
        sage: p.get_min(v[0])
        4
        sage: p.get_min(v[0][0])
        4.0

  `values`()

    Returns the symbolic variables associated to the current dictionary.

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram()
        sage: v = p.new_variable(nonnegative=True)
        sage: p.set_objective(v[0] + v[1])
        sage: v.values()
        [x_0, x_1]

class `sage.numerical.mip.``MIPVariableParent`

  Bases: `sage.structure.parent.Parent`

  Parent for `MIPVariable`.

  Warning

  This class is for internal use. You should not instantiate it yourself. Use `MixedIntegerLinearProgram.new_variable()` to generate mip variables.

  `Element`

    alias of `MIPVariable`

class `sage.numerical.mip.``MixedIntegerLinearProgram`

  Bases: `sage.structure.sage_object.SageObject`

  The `MixedIntegerLinearProgram` class is the link between Sage, linear programming (LP) and mixed integer programming (MIP) solvers.

  A Mixed Integer Linear Program (MILP) consists of variables, linear constraints on these variables, and an objective function which is to be maximised or minimised under these constraints.

  See the Wikipedia article Linear_programming for further information on linear programming, and the `MILP module` for its use in Sage.

  INPUT:

  - `solver` – selects a solver:

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

    - CVXOPT (`solver="CVXOPT"`). See the CVXOPT

        web site.

    - PPL (`solver="PPL"`). See the PPL

        web site.

    - If `solver=None` (default), the default solver is used (see `default_mip_solver()`)

  - `maximization`

    - When set to `True` (default), the `MixedIntegerLinearProgram` is defined as a maximization.
    - When set to `False`, the `MixedIntegerLinearProgram` is defined as a minimization.

  - `constraint_generation` – Only used when `solver=None`.

    - When set to `True`, after solving the `MixedIntegerLinearProgram`, it is possible to add a constraint, and then solve it again. The effect is that solvers that do not support this feature will not be used.
    - Defaults to `False`.

  Warning

  All LP variables are non-negative by default (see `new_variable()` and `set_min()`).

  See also

  - `default_mip_solver()` – Returns/Sets the default MIP solver.

  EXAMPLES:

  Computation of a maximum stable set in Petersen’s graph:

      sage: g = graphs.PetersenGraph()
      sage: p = MixedIntegerLinearProgram(maximization=True)
      sage: b = p.new_variable(binary=True)
      sage: p.set_objective(sum([b[v] for v in g]))
      sage: for (u,v) in g.edges(labels=None):
      ....:     p.add_constraint(b[u] + b[v], max=1)
      sage: p.solve(objective_only=True)
      4.0

  TESTS:

  Check that trac ticket #16497 is fixed:

      sage: from sage.numerical.mip import MixedIntegerLinearProgram
      sage: for type in ["binary", "integer"]:
      ....:     k = 3
      ....:     items = [1/5, 1/3, 2/3, 3/4, 5/7]
      ....:     maximum=1
      ....:     p=MixedIntegerLinearProgram()
      ....:     box=p.new_variable(nonnegative=True, **{type:True})
      ....:     for b in range(k):
      ....:          p.add_constraint(p.sum([items[i]*box[i,b] for i in range(len(items))]) <= maximum)
      ....:     for i in range(len(items)):
      ....:         p.add_constraint(p.sum([box[i,b] for b in range(k)]) == 1)
      ....:     p.set_objective(None)
      ....:     _ = p.solve()
      ....:     box=p.get_values(box)
      ....:     print(all(v in ZZ for v in box.values()))
      True
      True

  `add_constraint`(linear_function, max=None, min=None, name=None)

    Adds a constraint to the `MixedIntegerLinearProgram`.

    INPUT:

    - `linear_function` – Four different types of arguments are admissible:

      > - A linear function. In this case, one of the arguments `min` or `max` has to be specified.
      > - A linear constraint of the form `A <= B`, `A >= B`, `A <= B <= C`, `A >= B >= C` or `A == B`.
      > - A vector-valued linear function, see `linear_tensor`. In this case, one of the arguments `min` or `max` has to be specified.
      > - An (in)equality of vector-valued linear functions, that is, elements of the space of linear functions tensored with a vector space. See `linear_tensor_constraints` for details.

    - `max` – constant or `None` (default). An upper bound on the linear function. This must be a numerical value for scalar linear functions, or a vector for vector-valued linear functions. Not allowed if the `linear_function` argument is a symbolic (in)-equality.

    - `min` – constant or `None` (default). A lower bound on the linear function. This must be a numerical value for scalar linear functions, or a vector for vector-valued linear functions. Not allowed if the `linear_function` argument is a symbolic (in)-equality.

    - `name` – A name for the constraint.

    To set a lower and/or upper bound on the variables use the methods `set_min` and/or `set_max` of `MixedIntegerLinearProgram`.

    EXAMPLE:

    Consider the following linear program:

        Maximize:
          x + 5 * y
        Constraints:
          x + 0.2 y       <= 4
          1.5 * x + 3 * y <= 4
        Variables:
          x is Real (min = 0, max = None)
          y is Real (min = 0, max = None)

    It can be solved as follows:

        sage: p = MixedIntegerLinearProgram(maximization=True)
        sage: x = p.new_variable(nonnegative=True)
        sage: p.set_objective(x[0] + 5*x[1])
        sage: p.add_constraint(x[0] + 0.2*x[1], max=4)
        sage: p.add_constraint(1.5*x[0] + 3*x[1], max=4)
        sage: p.solve()     # rel tol 1e-15
        6.666666666666666

    There are two different ways to add the constraint `x[5] + 3*x[7] <= x[6] + 3` to a `MixedIntegerLinearProgram`.

    The first one consists in giving `add_constraint` this very expression:

        sage: p.add_constraint(x[5] + 3*x[7] <= x[6] + 3)

    The second (slightly more efficient) one is to use the arguments `min` or `max`, which can only be numerical values:

        sage: p.add_constraint(x[5] + 3*x[7] - x[6], max=3)

    One can also define double-bounds or equality using symbols `<=`, `>=` and `==`:

        sage: p.add_constraint(x[5] + 3*x[7] == x[6] + 3)
        sage: p.add_constraint(x[5] + 3*x[7] <= x[6] + 3 <= x[8] + 27)

    Using this notation, the previous program can be written as:

        sage: p = MixedIntegerLinearProgram(maximization=True)
        sage: x = p.new_variable(nonnegative=True)
        sage: p.set_objective(x[0] + 5*x[1])
        sage: p.add_constraint(x[0] + 0.2*x[1] <= 4)
        sage: p.add_constraint(1.5*x[0] + 3*x[1] <= 4)
        sage: p.solve()     # rel tol 1e-15
        6.666666666666666

    The two constraints can alse be combined into a single vector-valued constraint:

        sage: p = MixedIntegerLinearProgram(maximization=True)
        sage: x = p.new_variable(nonnegative=True)
        sage: p.set_objective(x[0] + 5*x[1])
        sage: f_vec = vector([1, 1.5]) * x[0] + vector([0.2, 3]) * x[1];  f_vec
        (1.0, 1.5)*x_0 + (0.2, 3.0)*x_1
        sage: p.add_constraint(f_vec, max=vector([4, 4]))
        sage: p.solve()     # rel tol 1e-15
        6.666666666666666

    Instead of specifying the maximum in the optional `max` argument, we can also use (in)equality notation for vector-valued linear functions:

        sage: f_vec <= 4    # constant rhs becomes vector
        (1.0, 1.5)*x_0 + (0.2, 3.0)*x_1 <= (4.0, 4.0)
        sage: p = MixedIntegerLinearProgram(maximization=True)
        sage: x = p.new_variable(nonnegative=True)
        sage: p.set_objective(x[0] + 5*x[1])
        sage: p.add_constraint(f_vec <= 4)
        sage: p.solve()     # rel tol 1e-15
        6.666666666666666

    Finally, one can use the matrix * `MIPVariable` notation to write vector-valued linear functions:

        sage: m = matrix([[1.0, 0.2], [1.5, 3.0]]);  m
        [ 1.00000000000000 0.200000000000000]
        [ 1.50000000000000  3.00000000000000]
        sage: p = MixedIntegerLinearProgram(maximization=True)
        sage: x = p.new_variable(nonnegative=True)
        sage: p.set_objective(x[0] + 5*x[1])
        sage: p.add_constraint(m * x <= 4)
        sage: p.solve()     # rel tol 1e-15
        6.666666666666666

    TESTS:

    Complex constraints:

        sage: p = MixedIntegerLinearProgram(solver = "GLPK")
        sage: b = p.new_variable(nonnegative=True)
        sage: p.add_constraint( b[8] - b[15] <= 3*b[8] + 9)
        sage: p.show()
        Maximization:
        <BLANKLINE>
        Constraints:
          -2.0 x_0 - x_1 <= 9.0
        Variables:
          x_0 is a continuous variable (min=0.0, max=+oo)
          x_1 is a continuous variable (min=0.0, max=+oo)

    Empty constraint:

        sage: p = MixedIntegerLinearProgram()
        sage: p.add_constraint(sum([]),min=2)

    Min/Max are numerical

        sage: v = p.new_variable(nonnegative=True)
        sage: p.add_constraint(v[3] + v[5], min = v[6])
        Traceback (most recent call last):
        ...
        ValueError: min and max arguments are required to be constants
        sage: p.add_constraint(v[3] + v[5], max = v[6])
        Traceback (most recent call last):
        ...
        ValueError: min and max arguments are required to be constants

    Do not add redundant elements (notice only one copy of each constraint is added):

        sage: lp = MixedIntegerLinearProgram(solver="GLPK", check_redundant=True)
        sage: for each in xrange(10): lp.add_constraint(lp[0]-lp[1],min=1)
        sage: lp.show()
        Maximization:
        <BLANKLINE>
        Constraints:
          1.0 <= x_0 - x_1
        Variables:
          x_0 is a continuous variable (min=0.0, max=+oo)
          x_1 is a continuous variable (min=0.0, max=+oo)

    We check for constant multiples of constraints as well:

        sage: for each in xrange(10): lp.add_constraint(2*lp[0]-2*lp[1],min=2)
        sage: lp.show()
        Maximization:
        <BLANKLINE>
        Constraints:
          1.0 <= x_0 - x_1
        Variables:
          x_0 is a continuous variable (min=0.0, max=+oo)
          x_1 is a continuous variable (min=0.0, max=+oo)

    But if the constant multiple is negative, we should add it anyway (once):

        sage: for each in xrange(10): lp.add_constraint(-2*lp[0]+2*lp[1],min=-2)
        sage: lp.show()
        Maximization:
        <BLANKLINE>
        Constraints:
          1.0 <= x_0 - x_1
          -2.0 <= -2.0 x_0 + 2.0 x_1
        Variables:
          x_0 is a continuous variable (min=0.0, max=+oo)
          x_1 is a continuous variable (min=0.0, max=+oo)

    TESTS:

    Catch `True` / `False` as INPUT (trac ticket #13646):

        sage: p = MixedIntegerLinearProgram()
        sage: x = p.new_variable(nonnegative=True)
        sage: p.add_constraint(True)
        Traceback (most recent call last):
        ...
        ValueError: argument must be a linear function or constraint, got True

  `base_ring`()

    Return the base ring.

    OUTPUT:

    A ring. The coefficients that the chosen solver supports.

    EXAMPLES:

        sage: p = MixedIntegerLinearProgram(solver='GLPK')
        sage: p.base_ring()
        Real Double Field
        sage: p = MixedIntegerLinearProgram(solver='ppl')
        sage: p.base_ring()
        Rational Field

  `constraints`(indices=None)

    Returns a list of constraints, as 3-tuples.

    INPUT:

    - `indices` – select which constraint(s) to return

      > - If `indices = None`, the method returns the list of all the constraints.
      > - If `indices` is an integer \(i\), the method returns constraint \(i\).
      > - If `indices` is a list of integers, the method returns the list of the corresponding constraints.

    OUTPUT:

    Each constraint is returned as a triple `lower_bound, (indices, coefficients), upper_bound`. For each of those entries, the corresponding linear function is the one associating to variable `indices[i]` the coefficient `coefficients[i]`, and \(0\) to all the others.

    `lower_bound` and `upper_bound` are numerical values.

    EXAMPLE:

    First, let us define a small LP:

        sage: p = MixedIntegerLinearProgram()
        sage: p.add_constraint(p[0] - p[2], min = 1, max = 4)
        sage: p.add_constraint(p[0] - 2*p[1], min = 1)

    To obtain the list of all constraints:

        sage: p.constraints()          # not tested
        [(1.0, ([1, 0], [-1.0, 1.0]), 4.0), (1.0, ([2, 0], [-2.0, 1.0]), None)]

    Or constraint \(0\) only:

        sage: p.constraints(0)         # not tested
        (1.0, ([1, 0], [-1.0, 1.0]), 4.0)

    A list of constraints containing only \(1\):

        sage: p.constraints([1])       # not tested
        [(1.0, ([2, 0], [-2.0, 1.0]), None)]

    TESTS:

    As the ordering of the variables in each constraint depends on the solver used, we define a short function reordering it before it is printed. The output would look the same without this function applied:

        sage: def reorder_constraint((lb,(ind,coef),ub)):
        ....:    d = dict(zip(ind, coef))
        ....:    ind.sort()
        ....:    return (lb, (ind, [d[i] for i in ind]), ub)

    Running the examples from above, reordering applied:

        sage: p = MixedIntegerLinearProgram(solver = "GLPK")
        sage: p.add_constraint(p[0] - p[2], min = 1, max = 4)
        sage: p.add_constraint(p[0] - 2*p[1], min = 1)
        sage: sorted(map(reorder_constraint,p.constraints()))
        [(1.0, ([0, 1], [1.0, -1.0]), 4.0), (1.0, ([0, 2], [1.0, -2.0]), None)]
        sage: reorder_constraint(p.constraints(0))
        (1.0, ([0, 1], [1.0, -1.0]), 4.0)
        sage: sorted(map(reorder_constraint,p.constraints([1])))
        [(1.0, ([0, 2], [1.0, -2.0]), None)]

  `gen`(i)

    Return the linear variable \(x_i\).

    OUTPUT:

    > sage: mip = MixedIntegerLinearProgram() sage: mip.gen(0) x_0 sage: [mip.gen(i) for i in range(10)] [x_0, x_1, x_2, x_3, x_4, x_5, x_6, x_7, x_8, x_9]

  `get_backend`()

    Returns the backend instance used.

    This might be useful when acces to additional functions provided by the backend is needed.

    EXAMPLE:

    This example uses the simplex algorthm and prints information:

        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: b = p.get_backend()
        sage: b.solver_parameter("simplex_or_intopt", "simplex_only")
        sage: b.solver_parameter("verbosity_simplex", "GLP_MSG_ALL")
        sage: p.solve()  # tol 0.00001
        GLPK Simplex Optimizer, v4.44
        2 rows, 2 columns, 4 non-zeros
        *     0: obj =   7.000000000e+00  infeas =  0.000e+00 (0)
        *     2: obj =   9.400000000e+00  infeas =  0.000e+00 (0)
        OPTIMAL SOLUTION FOUND
        9.4

  `get_max`(v)

    Returns the maximum value of a variable.

    INPUT:

    - `v` – a variable.

    OUTPUT:

    Maximum value of the variable, or `None` if the variable has no upper bound.

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram()
        sage: v = p.new_variable(nonnegative=True)
        sage: p.set_objective(v[1])
        sage: p.get_max(v[1])
        sage: p.set_max(v[1],6)
        sage: p.get_max(v[1])
        6.0

  `get_min`(v)

    Returns the minimum value of a variable.

    INPUT:

    - `v` – a variable

    OUTPUT:

    Minimum value of the variable, or `None` if the variable has no lower bound.

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram()
        sage: v = p.new_variable(nonnegative=True)
        sage: p.set_objective(v[1])
        sage: p.get_min(v[1])
        0.0
        sage: p.set_min(v[1],6)
        sage: p.get_min(v[1])
        6.0
        sage: p.set_min(v[1], None)
        sage: p.get_min(v[1])

  `get_values`(*lists)

    Return values found by the previous call to `solve()`.

    INPUT:

    - Any instance of `MIPVariable` (or one of its elements), or lists of them.

    OUTPUT:

    - Each instance of `MIPVariable` is replaced by a dictionary containing the numerical values found for each corresponding variable in the instance.
    - Each element of an instance of a `MIPVariable` is replaced by its corresponding numerical value.

    Note

    While a variable may be declared as binary or integer, its value as returned by the solver is of type `float`.

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram()
        sage: x = p.new_variable(nonnegative=True)
        sage: y = p.new_variable(nonnegative=True)
        sage: p.set_objective(x[3] + 3*y[2,9] + x[5])
        sage: p.add_constraint(x[3] + y[2,9] + 2*x[5], max=2)
        sage: p.solve()
        6.0

    To return the optimal value of `y[2,9]`:

        sage: p.get_values(y[2,9])
        2.0

    To get a dictionary identical to `x` containing optimal values for the corresponding variables

        sage: x_sol = p.get_values(x)
        sage: x_sol.keys()
        [3, 5]

    Obviously, it also works with variables of higher dimension:

        sage: y_sol = p.get_values(y)

    We could also have tried

        sage: [x_sol, y_sol] = p.get_values(x, y)

    Or:

        sage: [x_sol, y_sol] = p.get_values([x, y])

    TESTS:

    When ‘dim’ will be removed, also remove from this function the code that uses it:

        sage: p = MixedIntegerLinearProgram()
        sage: b = p.new_variable(dim=2)
        doctest:...: DeprecationWarning: The 'dim' argument will soon disappear. Fortunately variable[1,2] is easier to use than variable[1][2]
        See http://trac.sagemath.org/15489 for details.
        sage: p.add_constraint(b[1][2] +  b[2][3] == 0)
        sage: _ = p.solve()
        sage: _ = p.get_values(b)

  `is_binary`(e)

    Tests whether the variable `e` is binary. Variables are real by default.

    INPUT:

    - `e` – A variable (not a `MIPVariable`, but one of its elements.)

    OUTPUT:

    `True` if the variable `e` is binary; `False` otherwise.

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram()
        sage: v = p.new_variable(nonnegative=True)
        sage: p.set_objective(v[1])
        sage: p.is_binary(v[1])
        False
        sage: p.set_binary(v[1])
        sage: p.is_binary(v[1])
        True

  `is_integer`(e)

    Tests whether the variable is an integer. Variables are real by default.

    INPUT:

    - `e` – A variable (not a `MIPVariable`, but one of its elements.)

    OUTPUT:

    `True` if the variable `e` is an integer; `False` otherwise.

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram()
        sage: v = p.new_variable(nonnegative=True)
        sage: p.set_objective(v[1])
        sage: p.is_integer(v[1])
        False
        sage: p.set_integer(v[1])
        sage: p.is_integer(v[1])
        True

  `is_real`(e)

    Tests whether the variable is real.

    INPUT:

    - `e` – A variable (not a `MIPVariable`, but one of its elements.)

    OUTPUT:

    `True` if the variable is real; `False` otherwise.

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram()
        sage: v = p.new_variable(nonnegative=True)
        sage: p.set_objective(v[1])
        sage: p.is_real(v[1])
        True
        sage: p.set_binary(v[1])
        sage: p.is_real(v[1])
        False
        sage: p.set_real(v[1])
        sage: p.is_real(v[1])
        True

  `linear_constraints_parent`()

    Return the parent for all linear constraints

    See `linear_functions` for more details.

    EXAMPLES:

        sage: p = MixedIntegerLinearProgram()
        sage: p.linear_constraints_parent()
        Linear constraints over Real Double Field

  `linear_function`(x)

    Construct a new linear function

    EXAMPLES:

        sage: p = MixedIntegerLinearProgram()
        sage: p.linear_function({1:3, 4:5})
        3*x_1 + 5*x_4

    This is equivalent to:

        sage: p({1:3, 4:5})
        3*x_1 + 5*x_4

  `linear_functions_parent`()

    Return the parent for all linear functions

    EXAMPLES:

        sage: p = MixedIntegerLinearProgram()
        sage: p.linear_functions_parent()
        Linear functions over Real Double Field

  `new_variable`(real=False, binary=False, integer=False, nonnegative=None, dim=1, name='')

    Return a new MIPVariable

    A new variable `x` is defined by:

        sage: p = MixedIntegerLinearProgram()
        sage: x = p.new_variable(nonnegative=True)

    It behaves exactly as an usual dictionary would. It can use any key argument you may like, as `x[5]` or `x["b"]`, and has methods `items()` and `keys()`.

    See also

    - `set_min()`,:meth:\(get_min\) – set/get the lower bound of a variable. Note that by default, all variables are non-negative.
    - `set_max()`,:meth:\(get_max\) – set/get the upper bound of a variable.

    INPUT:

    - `dim` – integer. Defines the dimension of the dictionary. If `x` has dimension \(2\), its fields will be of the form `x[key1][key2]`. Deprecated.
    - `binary, integer, real` – boolean. Set one of these arguments to `True` to ensure that the variable gets the corresponding type.
    - `nonnegative` – boolean. Whether the variable should be assumed to be nonnegative. Rather useless for the binary type.
    - `name` – string. Associates a name to the variable. This is only useful when exporting the linear program to a file using `write_mps` or `write_lp`, and has no other effect.

    OUTPUT:

    A new instance of `MIPVariable` associated to the current `MixedIntegerLinearProgram`.

    EXAMPLE:

           sage: p = MixedIntegerLinearProgram()

        To define two dictionaries of variables, the first being
        of real type, and the second of integer type ::

           sage: x = p.new_variable(real=True, nonnegative=True)
           sage: y = p.new_variable(integer=True, nonnegative=True)
           sage: p.add_constraint(x[2] + y[3,5], max=2)
           sage: p.is_integer(x[2])
           False
           sage: p.is_integer(y[3,5])
           True

    An exception is raised when two types are supplied

        sage: z = p.new_variable(real = True, integer = True)
        Traceback (most recent call last):
        ...
        ValueError: Exactly one of the available types has to be True

    Unbounded variables:

        sage: p = MixedIntegerLinearProgram()
        sage: x = p.new_variable(real=True, nonnegative=False)
        sage: y = p.new_variable(integer=True, nonnegative=False)
        sage: p.add_constraint(x[0]+x[3] <= 8)
        sage: p.add_constraint(y[0] >= y[1])
        sage: p.show()
        Maximization:
        <BLANKLINE>
        Constraints:
          x_0 + x_1 <= 8.0
          - x_2 + x_3 <= 0.0
        Variables:
          x_0 is a continuous variable (min=-oo, max=+oo)
          x_1 is a continuous variable (min=-oo, max=+oo)
          x_2 is an integer variable (min=-oo, max=+oo)
          x_3 is an integer variable (min=-oo, max=+oo)

    On the Sage command line, generator syntax is accepted as a shorthand for generating new variables with default (`nonnegative=False`) settings:

        sage: mip.<x, y, z> = MixedIntegerLinearProgram()
        sage: mip.add_constraint(x[0] + y[1] + z[2] <= 10)
        sage: mip.show()
        Maximization:
        <BLANKLINE>
        Constraints:
          x[0] + y[1] + z[2] <= 10.0
        Variables:
          x[0] = x_0 is a continuous variable (min=-oo, max=+oo)
          y[1] = x_1 is a continuous variable (min=-oo, max=+oo)
          z[2] = x_2 is a continuous variable (min=-oo, max=+oo)

    TESTS:

    Default behaviour (trac ticket #15521):

        sage: x = p.new_variable(nonnegative=True)
        sage: p.get_min(x[0])
        0.0

  `number_of_constraints`()

    Returns the number of constraints assigned so far.

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram()
        sage: p.add_constraint(p[0] - p[2], min = 1, max = 4)
        sage: p.add_constraint(p[0] - 2*p[1], min = 1)
        sage: p.number_of_constraints()
        2

  `number_of_variables`()

    Returns the number of variables used so far.

    Note that this is backend-dependent, i.e. we count solver’s variables rather than user’s variables. An example of the latter can be seen below: Gurobi converts double inequalities, i.e. inequalities like \(m <= c^T x <= M\), with \(m<M\), into equations, by adding extra variables: \(c^T x + y = M\), \(0 <= y <= M-m\).

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram()
        sage: p.add_constraint(p[0] - p[2], max = 4)
        sage: p.number_of_variables()
        2
        sage: p.add_constraint(p[0] - 2*p[1], min = 1)
        sage: p.number_of_variables()
        3
        sage: p = MixedIntegerLinearProgram(solver="glpk")
        sage: p.add_constraint(p[0] - p[2], min = 1, max = 4)
        sage: p.number_of_variables()
        2
        sage: p = MixedIntegerLinearProgram(solver="gurobi")   # optional - Gurobi
        sage: p.add_constraint(p[0] - p[2], min = 1, max = 4)  # optional - Gurobi
        sage: p.number_of_variables()                          # optional - Gurobi
        3

  `polyhedron`(**kwds)

    Returns the polyhedron defined by the Linear Program.

    INPUT:

    All arguments given to this method are forwarded to the constructor of the `Polyhedron()` class.

    OUTPUT:

    A `Polyhedron()` object whose \(i\)-th variable represents the \(i\)-th variable of `self`.

    Warning

    The polyhedron is built from the variables stored by the LP solver (i.e. the output of `show()`). While they usually match the ones created explicitely when defining the LP, a solver like Gurobi has been known to introduce additional variables to store constraints of the type `lower_bound <= linear_function <= upper bound`. You should be fine if you did not install Gurobi or if you do not use it as a solver, but keep an eye on the number of variables in the polyhedron, or on the output of `show()`. Just in case.

    EXAMPLES:

    A LP on two variables:

        sage: p = MixedIntegerLinearProgram()
        sage: p.add_constraint(2*p['x'] + p['y'] <= 1)
        sage: p.add_constraint(3*p['y'] + p['x'] <= 2)
        sage: P = p.polyhedron(); P
        A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices

    3-D Polyhedron:

        sage: p = MixedIntegerLinearProgram()
        sage: p.add_constraint(2*p['x'] + p['y'] + 3*p['z'] <= 1)
        sage: p.add_constraint(2*p['y'] + p['z'] + 3*p['x'] <= 1)
        sage: p.add_constraint(2*p['z'] + p['x'] + 3*p['y'] <= 1)
        sage: P = p.polyhedron(); P
        A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices

    An empty polyhedron:

        sage: p = MixedIntegerLinearProgram()
        sage: p.add_constraint(2*p['x'] + p['y'] + 3*p['z'] <= 1)
        sage: p.add_constraint(2*p['y'] + p['z'] + 3*p['x'] <= 1)
        sage: p.add_constraint(2*p['z'] + p['x'] + 3*p['y'] >= 2)
        sage: P = p.polyhedron(); P
        The empty polyhedron in QQ^3

    An unbounded polyhedron:

        sage: p = MixedIntegerLinearProgram()
        sage: p.add_constraint(2*p['x'] + p['y'] - p['z'] <= 1)
        sage: P = p.polyhedron(); P
        A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 3 vertices and 3 rays

    A square (see trac ticket #14395)

        sage: p = MixedIntegerLinearProgram()
        sage: x,y = p['x'], p['y']
        sage: p.set_min(x,None)
        sage: p.set_min(y,None)
        sage: p.add_constraint( x <= 1 )
        sage: p.add_constraint( x >= -1 )
        sage: p.add_constraint( y <= 1 )
        sage: p.add_constraint( y >= -1 )
        sage: p.polyhedron()
        A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices

  `remove_constraint`(i)

    Removes a constraint from self.

    INPUT:

    - `i` – Index of the constraint to remove.

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram()
        sage: x, y = p[0], p[1]
        sage: p.add_constraint(x + y, max = 10)
        sage: p.add_constraint(x - y, max = 0)
        sage: p.add_constraint(x, max = 4)
        sage: p.show()
        Maximization:
        <BLANKLINE>
        Constraints:
          x_0 + x_1 <= 10.0
          x_0 - x_1 <= 0.0
          x_0 <= 4.0
        ...
        sage: p.remove_constraint(1)
        sage: p.show()
        Maximization:
        <BLANKLINE>
        Constraints:
          x_0 + x_1 <= 10.0
          x_0 <= 4.0
        ...
        sage: p.number_of_constraints()
        2

  `remove_constraints`(constraints)

    Remove several constraints.

    INPUT:

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

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram()
        sage: x, y = p[0], p[1]
        sage: p.add_constraint(x + y, max = 10)
        sage: p.add_constraint(x - y, max = 0)
        sage: p.add_constraint(x, max = 4)
        sage: p.show()
        Maximization:
        <BLANKLINE>
        Constraints:
          x_0 + x_1 <= 10.0
          x_0 - x_1 <= 0.0
          x_0 <= 4.0
        ...
        sage: p.remove_constraints([0, 1])
        sage: p.show()
        Maximization:
        <BLANKLINE>
        Constraints:
          x_0 <= 4.0
        ...
        sage: p.number_of_constraints()
        1

    When checking for redundant constraints, make sure you remove only the constraints that were actually added. Problems could arise if you have a function that builds lps non-interactively, but it fails to check whether adding a constraint actually increases the number of constraints. The function might later try to remove constraints that are not actually there:

        sage: p = MixedIntegerLinearProgram(check_redundant=True)
        sage: x, y = p[0], p[1]
        sage: p.add_constraint(x + y, max = 10)
        sage: for each in xrange(10): p.add_constraint(x - y, max = 10)
        sage: p.add_constraint(x, max = 4)
        sage: p.number_of_constraints()
        3
        sage: p.remove_constraints(range(1,9))
        Traceback (most recent call last):
        ...
        IndexError: pop index out of range
        sage: p.remove_constraint(1)
        sage: p.number_of_constraints()
        2

    We should now be able to add the old constraint back in:

        sage: for each in xrange(10): p.add_constraint(x - y, max = 10)
        sage: p.number_of_constraints()
        3

  `set_binary`(ee)

    Sets a variable or a `MIPVariable` as binary.

    INPUT:

    - `ee` – An instance of `MIPVariable` or one of its elements.

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram()
        sage: x = p.new_variable(nonnegative=True)

    With the following instruction, all the variables from x will be binary:

        sage: p.set_binary(x)
        sage: p.set_objective(x[0] + x[1])
        sage: p.add_constraint(-3*x[0] + 2*x[1], max=2)

    It is still possible, though, to set one of these variables as integer while keeping the others as they are:

        sage: p.set_integer(x[3])

    TESTS:

    When ‘dim’ will be removed, also remove all the `is_*` and `set_*` functions the code that uses it:

        sage: p = MixedIntegerLinearProgram()
        sage: b = p.new_variable(dim=2)
        sage: p.add_constraint(b[1][2] +  b[2][3] == 0)
        sage: p.set_binary(b)

  `set_integer`(ee)

    Sets a variable or a `MIPVariable` as integer.

    INPUT:

    - `ee` – An instance of `MIPVariable` or one of its elements.

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram()
        sage: x = p.new_variable(nonnegative=True)

    With the following instruction, all the variables from x will be integers:

        sage: p.set_integer(x)
        sage: p.set_objective(x[0] + x[1])
        sage: p.add_constraint(-3*x[0] + 2*x[1], max=2)

    It is still possible, though, to set one of these variables as binary while keeping the others as they are:

        sage: p.set_binary(x[3])

  `set_max`(v, max)

    Sets the maximum value of a variable.

    INPUT

    - `v` – a variable.
    - `max` – the maximum value the variable can take. When `max=None`, the variable has no upper bound.

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram()
        sage: v = p.new_variable(nonnegative=True)
        sage: p.set_objective(v[1])
        sage: p.get_max(v[1])
        sage: p.set_max(v[1],6)
        sage: p.get_max(v[1])
        6.0

    With a `MIPVariable` as an argument:

        sage: vv = p.new_variable(real=True, nonnegative=False)
        sage: p.get_max(vv)
        sage: p.get_max(vv[0])
        sage: p.set_max(vv,5)
        sage: p.get_max(vv[0])
        5.0
        sage: p.get_max(vv[9])
        5.0

  `set_min`(v, min)

    Sets the minimum value of a variable.

    INPUT:

    - `v` – a variable.
    - `min` – the minimum value the variable can take. When `min=None`, the variable has no lower bound.

    See also

    - `get_min()` – get the minimum value of a variable.

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram()
        sage: v = p.new_variable(nonnegative=True)
        sage: p.set_objective(v[1])
        sage: p.get_min(v[1])
        0.0
        sage: p.set_min(v[1],6)
        sage: p.get_min(v[1])
        6.0
        sage: p.set_min(v[1], None)
        sage: p.get_min(v[1])

    With a `MIPVariable` as an argument:

        sage: vv = p.new_variable(real=True, nonnegative=False)
        sage: p.get_min(vv)
        sage: p.get_min(vv[0])
        sage: p.set_min(vv,5)
        sage: p.get_min(vv[0])
        5.0
        sage: p.get_min(vv[9])
        5.0

  `set_objective`(obj)

    Sets the objective of the `MixedIntegerLinearProgram`.

    INPUT:

    - `obj` – A linear function to be optimized. ( can also be set to `None` or `0` when just looking for a feasible solution )

    EXAMPLE:

    Let’s solve the following linear program:

        Maximize:
          x + 5 * y
        Constraints:
          x + 0.2 y       <= 4
          1.5 * x + 3 * y <= 4
        Variables:
          x is Real (min = 0, max = None)
          y is Real (min = 0, max = None)

    This linear program can be solved as follows:

        sage: p = MixedIntegerLinearProgram(maximization=True)
        sage: x = p.new_variable(nonnegative=True)
        sage: p.set_objective(x[1] + 5*x[2])
        sage: p.add_constraint(x[1] + 2/10*x[2], max=4)
        sage: p.add_constraint(1.5*x[1]+3*x[2], max=4)
        sage: round(p.solve(),5)
        6.66667
        sage: p.set_objective(None)
        sage: _ = p.solve()

  `set_problem_name`(name)

    Sets the name of the `MixedIntegerLinearProgram`.

    INPUT:

    - `name` – A string representing the name of the `MixedIntegerLinearProgram`.

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram()
        sage: p.set_problem_name("Test program")
        sage: p
        Mixed Integer Program "Test program" ( maximization, 0 variables, 0 constraints )

  `set_real`(ee)

    Sets a variable or a `MIPVariable` as real.

    INPUT:

    - `ee` – An instance of `MIPVariable` or one of its elements.

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram()
        sage: x = p.new_variable(nonnegative=True)

    With the following instruction, all the variables from x will be real:

           sage: p.set_real(x)
           sage: p.set_objective(x[0] + x[1])
           sage: p.add_constraint(-3*x[0] + 2*x[1], max=2)

        It is still possible, though, to set one of these
        variables as binary while keeping the others as they are::

           sage: p.set_binary(x[3])

  `show`()

    Displays the `MixedIntegerLinearProgram` in a human-readable way.

    EXAMPLES:

    When constraints and variables have names

        sage: p = MixedIntegerLinearProgram(solver="GLPK")
        sage: x = p.new_variable(name="Hey")
        sage: p.set_objective(x[1] + x[2])
        sage: p.add_constraint(-3*x[1] + 2*x[2], max=2, name="Constraint_1")
        sage: p.show()
        Maximization:
          Hey[1] + Hey[2]
        Constraints:
          Constraint_1: -3.0 Hey[1] + 2.0 Hey[2] <= 2.0
        Variables:
          Hey[1] = x_0 is a continuous variable (min=0.0, max=+oo)
          Hey[2] = x_1 is a continuous variable (min=0.0, max=+oo)

    Without any names

        sage: p = MixedIntegerLinearProgram(solver="GLPK")
        sage: x = p.new_variable(nonnegative=True)
        sage: p.set_objective(x[1] + x[2])
        sage: p.add_constraint(-3*x[1] + 2*x[2], max=2)
        sage: p.show()
        Maximization:
          x_0 + x_1
        Constraints:
          -3.0 x_0 + 2.0 x_1 <= 2.0
        Variables:
          x_0 is a continuous variable (min=0.0, max=+oo)
          x_1 is a continuous variable (min=0.0, max=+oo)

    With \(\QQ\) coefficients:

        sage: p = MixedIntegerLinearProgram(solver='ppl')
        sage: x = p.new_variable(nonnegative=True)
        sage: p.set_objective(x[1] + 1/2*x[2])
        sage: p.add_constraint(-3/5*x[1] + 2/7*x[2], max=2/5)
        sage: p.show()
        Maximization:
          x_0 + 1/2 x_1
        Constraints:
          constraint_0: -3/5 x_0 + 2/7 x_1 <= 2/5
        Variables:
          x_0 is a continuous variable (min=0, max=+oo)
          x_1 is a continuous variable (min=0, max=+oo)

  `solve`(log=None, objective_only=False)

    Solves the `MixedIntegerLinearProgram`.

    INPUT:

    - `log` – integer (default: `None`) The verbosity level. Indicates whether progress should be printed during computation. The solver is initialized to report no progress.
    - `objective_only` – Boolean variable.
      - When set to `True`, only the objective function is returned.
      - When set to `False` (default), the optimal numerical values are stored (takes computational time).

    OUTPUT:

    The optimal value taken by the objective function.

    Warning

    By default, all variables of a LP are assumed to be non-negative. See `set_min()` to change it.

    EXAMPLES:

    Consider the following linear program:

        Maximize:
          x + 5 * y
        Constraints:
          x + 0.2 y       <= 4
          1.5 * x + 3 * y <= 4
        Variables:
          x is Real (min = 0, max = None)
          y is Real (min = 0, max = None)

    This linear program can be solved as follows:

           sage: p = MixedIntegerLinearProgram(maximization=True)
           sage: x = p.new_variable(nonnegative=True)
           sage: p.set_objective(x[1] + 5*x[2])
           sage: p.add_constraint(x[1] + 0.2*x[2], max=4)
           sage: p.add_constraint(1.5*x[1] + 3*x[2], max=4)
           sage: round(p.solve(),6)
           6.666667
           sage: x = p.get_values(x)
           sage: round(x[1],6)
           0.0
           sage: round(x[2],6)
           1.333333

        Computation of a maximum stable set in Petersen's graph::

           sage: g = graphs.PetersenGraph()
           sage: p = MixedIntegerLinearProgram(maximization=True)
           sage: b = p.new_variable(nonnegative=True)
           sage: p.set_objective(sum([b[v] for v in g]))
           sage: for (u,v) in g.edges(labels=None):
           ...       p.add_constraint(b[u] + b[v], max=1)
           sage: p.set_binary(b)
           sage: p.solve(objective_only=True)
           4.0

    Constraints in the objective function are respected:

        sage: p = MixedIntegerLinearProgram()
        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

  `solver_parameter`(name, value=None)

    Return or define a solver parameter

    The solver parameters are by essence solver-specific, which means their meaning heavily depends on the solver used.

    (If you do not know which solver you are using, then you use use GLPK).

    Aliases:

    Very common parameters have aliases making them solver-independent. For example, the following:

        sage: p = MixedIntegerLinearProgram(solver = "GLPK")
        sage: p.solver_parameter("timelimit", 60)

    Sets the solver to stop its computations after 60 seconds, and works with GLPK, CPLEX and Gurobi.

    > - `"timelimit"` – defines the maximum time spent on a computation. Measured in seconds.

    Solver-specific parameters:

    > - GLPK : We have implemented very close to comprehensive coverage of the GLPK solver parameters for the simplex and integer optimization methods. For details, see the documentation of `GLPKBackend.solver_parameter`.

    > - CPLEX’s parameters are identified by a string. Their list is available on ILOG’s website.

    >   The command

    >       sage: p = MixedIntegerLinearProgram(solver = "CPLEX") # optional - CPLEX
    >       sage: p.solver_parameter("CPX_PARAM_TILIM", 60)       # optional - CPLEX

    >   works as intended.

    > - Gurobi’s parameters should all be available through this method. Their list is available on Gurobi’s website http://www.gurobi.com/documentation/5.5/reference-manual/node798.

    INPUT:

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

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram(solver = "GLPK")
        sage: p.solver_parameter("timelimit", 60)
        sage: p.solver_parameter("timelimit")
        60.0

  `sum`(L)

    Efficiently computes the sum of a sequence of `LinearFunction` elements

    INPUT:

    - `mip` – the `MixedIntegerLinearProgram` parent.
    - `L` – list of `LinearFunction` instances.

    Note

    The use of the regular `sum` function is not recommended as it is much less efficient than this one

    EXAMPLES:

        sage: p = MixedIntegerLinearProgram()
        sage: v = p.new_variable(nonnegative=True)

    The following command:

        sage: s = p.sum([v[i] for i in xrange(90)])

    is much more efficient than:

        sage: s = sum([v[i] for i in xrange(90)])

  `write_lp`(filename)

    Write the linear program as a LP file.

    This function export the problem as a LP file.

    INPUT:

    - `filename` – The file in which you want the problem to be written.

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram(solver="GLPK")
        sage: x = p.new_variable(nonnegative=True)
        sage: p.set_objective(x[1] + x[2])
        sage: p.add_constraint(-3*x[1] + 2*x[2], max=2)
        sage: p.write_lp(os.path.join(SAGE_TMP, "lp_problem.lp"))
        Writing problem data to ...
        9 lines were written

    For more information about the LP file format : http://lpsolve.sourceforge.net/5.5/lp-format.htm

  `write_mps`(filename, modern=True)

    Write the linear program as a MPS file.

    This function export the problem as a MPS file.

    INPUT:

    - `filename` – The file in which you want the problem to be written.

    - `modern` – Lets you choose between Fixed MPS and Free MPS

      > - `True` – Outputs the problem in Free MPS
      > - `False` – Outputs the problem in Fixed MPS

    EXAMPLE:

        sage: p = MixedIntegerLinearProgram(solver="GLPK")
        sage: x = p.new_variable(nonnegative=True)
        sage: p.set_objective(x[1] + x[2])
        sage: p.add_constraint(-3*x[1] + 2*x[2], max=2,name="OneConstraint")
        sage: p.write_mps(os.path.join(SAGE_TMP, "lp_problem.mps"))
        Writing problem data to ...
        17 records were written

    For information about the MPS file format : http://en.wikipedia.org/wiki/MPS_%28format%29

`sage.numerical.mip.``Sum`(x)

  Only for legacy support, use `MixedIntegerLinearProgram.sum()` instead.

  EXAMPLES:

      sage: from sage.numerical.mip import Sum
      sage: Sum([])
      doctest:...: DeprecationWarning: use MixedIntegerLinearProgram.sum() instead
      See http://trac.sagemath.org/13646 for details.

      sage: p = MixedIntegerLinearProgram()
      sage: x = p.new_variable(nonnegative=True)
      sage: Sum([ x[0]+x[1], x[1]+x[2], x[2]+x[3] ])   # deprecation is only shown once
      x_0 + 2*x_1 + 2*x_2 + x_3

### Navigation

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