Ticket #14238: trac_14238.patch

File trac_14238.patch, 11.3 KB (added by ncohen, 8 years ago)
  • sage/geometry/polyhedron/constructor.py

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1362579903 -3600
    # Node ID 2e3b5f0d8c5e582fb31291b81ca76a0b94ebc921
    # Parent  1036db3ba4310db517f9fe505043e76194d67f1a
    a polyhedron() method for Linear Programs
    
    diff --git a/sage/geometry/polyhedron/constructor.py b/sage/geometry/polyhedron/constructor.py
    a b  
    198198    - ``lines`` -- list of lines. Each line can be specified as any
    199199      iterable container of ``base_ring`` elements.
    200200
    201     - ``ieqs`` -- list of inequalities. Each line can be specified as
    202       any iterable container of ``base_ring`` elements.
     201    - ``ieqs`` -- list of inequalities. Each line can be specified as any
     202      iterable container of ``base_ring`` elements. An entry equal to
     203      ``[-1,7,3,4]`` represents the inequality `7x_1+3x_2+4x_3\geq 1`.
    203204
    204205    - ``eqns`` -- list of equalities. Each line can be specified as
    205       any iterable container of ``base_ring`` elements.
     206      any iterable container of ``base_ring`` elements. An entry equal to
     207      ``[-1,7,3,4]`` represents the equality `7x_1+3x_2+4x_3= 1`.
    206208
    207209    - ``base_ring`` -- either ``QQ`` or ``RDF``. The field over which
    208210      the polyhedron will be defined. For ``QQ``, exact arithmetic
  • sage/numerical/mip.pyx

    diff --git a/sage/numerical/mip.pyx b/sage/numerical/mip.pyx
    a b  
    103103AUTHORS:
    104104
    105105- Risan (2012/02): added extension for exact computation
     106
     107Index of functions and methods
     108------------------------------
     109
     110Below are listed the methods of :class:`MixedIntegerLinearProgram`. This module
     111also implements the :class:`MIPSolverException` exception, as well as the
     112:class:`MIPVariable` class.
     113
     114.. csv-table::
     115    :class: contentstable
     116    :widths: 30, 70
     117    :delim: |
     118
     119    :meth:`~MixedIntegerLinearProgram.add_constraint`            | Adds a constraint to the ``MixedIntegerLinearProgram``
     120    :meth:`~MixedIntegerLinearProgram.base_ring`                 | Return the base ring
     121    :meth:`~MixedIntegerLinearProgram.constraints`               | Returns a list of constraints, as 3-tuples
     122    :meth:`~MixedIntegerLinearProgram.get_backend`               | Returns the backend instance used
     123    :meth:`~MixedIntegerLinearProgram.get_max`                   | Returns the maximum value of a variable
     124    :meth:`~MixedIntegerLinearProgram.get_min`                   | Returns the minimum value of a variable
     125    :meth:`~MixedIntegerLinearProgram.get_values`                | Return values found by the previous call to ``solve()``
     126    :meth:`~MixedIntegerLinearProgram.is_binary`                 | Tests whether the variable ``e`` is binary
     127    :meth:`~MixedIntegerLinearProgram.is_integer`                | Tests whether the variable is an integer
     128    :meth:`~MixedIntegerLinearProgram.is_real`                   | Tests whether the variable is real
     129    :meth:`~MixedIntegerLinearProgram.linear_constraints_parent` | Return the parent for all linear constraints
     130    :meth:`~MixedIntegerLinearProgram.linear_function`           | Construct a new linear function
     131    :meth:`~MixedIntegerLinearProgram.linear_functions_parent`   | Return the parent for all linear functions
     132    :meth:`~MixedIntegerLinearProgram.new_variable`              | Returns an instance of ``MIPVariable`` associated
     133    :meth:`~MixedIntegerLinearProgram.number_of_constraints`     | Returns the number of constraints assigned so far
     134    :meth:`~MixedIntegerLinearProgram.number_of_variables`       | Returns the number of variables used so far
     135    :meth:`~MixedIntegerLinearProgram.polyhedron`                | Returns the polyhedron defined by the Linear Program
     136    :meth:`~MixedIntegerLinearProgram.remove_constraint`         | Removes a constraint from self
     137    :meth:`~MixedIntegerLinearProgram.remove_constraints`        | Remove several constraints
     138    :meth:`~MixedIntegerLinearProgram.set_binary`                | Sets a variable or a ``MIPVariable`` as binary
     139    :meth:`~MixedIntegerLinearProgram.set_integer`               | Sets a variable or a ``MIPVariable`` as integer
     140    :meth:`~MixedIntegerLinearProgram.set_max`                   | Sets the maximum value of a variable
     141    :meth:`~MixedIntegerLinearProgram.set_min`                   | Sets the minimum value of a variable
     142    :meth:`~MixedIntegerLinearProgram.set_objective`             | Sets the objective of the ``MixedIntegerLinearProgram``
     143    :meth:`~MixedIntegerLinearProgram.set_problem_name`          | Sets the name of the ``MixedIntegerLinearProgram``
     144    :meth:`~MixedIntegerLinearProgram.set_real`                  | Sets a variable or a ``MIPVariable`` as real
     145    :meth:`~MixedIntegerLinearProgram.show`                      | Displays the ``MixedIntegerLinearProgram`` in a human-readable
     146    :meth:`~MixedIntegerLinearProgram.solve`                     | Solves the ``MixedIntegerLinearProgram``
     147    :meth:`~MixedIntegerLinearProgram.solver_parameter`          | Return or define a solver parameter
     148    :meth:`~MixedIntegerLinearProgram.sum`                       | Efficiently computes the sum of a sequence of LinearFunction elements
     149    :meth:`~MixedIntegerLinearProgram.write_lp`                  | Write the linear program as a LP file
     150    :meth:`~MixedIntegerLinearProgram.write_mps`                 | Write the linear program as a MPS file
     151
     152Classes and methods
     153-------------------
    106154"""
    107155
    108156#*****************************************************************************
     
    114162#                  http://www.gnu.org/licenses/
    115163#*****************************************************************************
    116164
    117 
    118 
    119165include "../ext/stdsage.pxi"
    120166include "../ext/interrupt.pxi"
    121167include "../ext/cdefs.pxi"
     
    634680            sage: p.constraints([1])       # not tested
    635681            [(1.0, ([2, 0], [-2.0, 1.0]), None)]
    636682
    637 
    638683        TESTS:
    639684
    640685        As the ordering of the variables in each constraint depends on the
     
    687732        else:
    688733          raise ValueError, "constraints() requires a list of integers, though it will accommodate None or an integer."
    689734
     735    def polyhedron(self, **kwds):
     736        r"""
     737        Returns the polyhedron defined by the Linear Program.
     738
     739        INPUT:
     740
     741        All arguments given to this method are forwarded to the constructor of
     742        the :class:`Polyhedron` class.
     743
     744        OUTPUT:
     745
     746        A :class:`Polyhedron` object whose `i`-th variable represents the `i`-th
     747        variable of ``self``.
     748
     749        .. warning::
     750
     751            The polyhedron is built from the variables stored by the LP solver
     752            (i.e. the output of :meth:`show`). While they usually match the ones
     753            created explicitely when defining the LP, a solver like Gurobi has
     754            been known to introduce additional variables to store constraints of
     755            the type ``lower_bound <= linear_function <= upper bound``. You
     756            should be fine if you did not install Gurobi or if you do not use it
     757            as a solver, but keep an eye on the number of variables in the
     758            polyhedron, or on the output of :meth:`show`. Just in case.
     759
     760        EXAMPLES:
     761
     762        A LP on two variables::
     763
     764            sage: p = MixedIntegerLinearProgram()
     765            sage: p.add_constraint(2*p['x'] + p['y'] <= 1)
     766            sage: p.add_constraint(3*p['y'] + p['x'] <= 2)
     767            sage: P = p.polyhedron(); P
     768            A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 4 vertices
     769
     770        3-D Polyhedron::
     771
     772            sage: p = MixedIntegerLinearProgram()
     773            sage: p.add_constraint(2*p['x'] + p['y'] + 3*p['z'] <= 1)
     774            sage: p.add_constraint(2*p['y'] + p['z'] + 3*p['x'] <= 1)
     775            sage: p.add_constraint(2*p['z'] + p['x'] + 3*p['y'] <= 1)
     776            sage: P = p.polyhedron(); P
     777            A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 8 vertices
     778
     779        An empty polyhedron::
     780
     781            sage: p = MixedIntegerLinearProgram()
     782            sage: p.add_constraint(2*p['x'] + p['y'] + 3*p['z'] <= 1)
     783            sage: p.add_constraint(2*p['y'] + p['z'] + 3*p['x'] <= 1)
     784            sage: p.add_constraint(2*p['z'] + p['x'] + 3*p['y'] >= 2)
     785            sage: P = p.polyhedron(); P
     786            The empty polyhedron in QQ^3
     787
     788        An unbounded polyhedron::
     789
     790            sage: p = MixedIntegerLinearProgram()
     791            sage: p.add_constraint(2*p['x'] + p['y'] - p['z'] <= 1)
     792            sage: P = p.polyhedron(); P
     793            A 3-dimensional polyhedron in QQ^3 defined as the convex hull of 3 vertices and 3 rays
     794
     795        """
     796        from sage.geometry.polyhedron.constructor import Polyhedron
     797        from copy import copy
     798
     799        cdef GenericBackend b = self._backend
     800        cdef int i
     801
     802        inequalities = []
     803        equalities = []
     804        nvar = self.number_of_variables()
     805
     806        # Constraints
     807        for lb, (indices, values), ub in self.constraints():
     808
     809            coeffs = dict(zip(indices, values))
     810
     811            # Equalities
     812            if lb == ub:
     813                linear_function = []
     814                linear_function = [coeffs.get(i,0) for i in range(nvar)]
     815                linear_function.insert(0,-lb)
     816                equalities.append(linear_function)
     817                continue
     818
     819            # Lower Bound
     820            if not lb is None:
     821                linear_function = []
     822                linear_function = [coeffs.get(i,0) for i in range(nvar)]
     823                linear_function.insert(0,-lb)
     824                inequalities.append(linear_function)
     825
     826            # Upper Bound
     827            if not ub is None:
     828                linear_function = []
     829                linear_function = [-coeffs.get(i,0) for i in range(nvar)]
     830                linear_function.insert(0,ub)
     831                inequalities.append(linear_function)
     832
     833        zero = [0] * nvar
     834
     835        # Variable bounds
     836        for 0<= i < nvar:
     837            lb, ub = b.col_bounds(i)
     838
     839            # Fixed variable
     840            if lb == ub:
     841                linear_function = copy(zero)
     842                linear_function[i] = 1
     843                linear_function.insert(0,-lb)
     844                equalities.append(linear_function)
     845                continue
     846
     847            # Lower bound
     848            if not lb is None:
     849                linear_function = copy(zero)
     850                linear_function[i] = 1
     851                linear_function.insert(0,-lb)
     852                inequalities.append(linear_function)
     853
     854            # Upper bound
     855            if not ub is None:
     856                linear_function = copy(zero)
     857                linear_function[i] = -1
     858                linear_function.insert(0,ub)
     859                inequalities.append(linear_function)
     860
     861        return Polyhedron(ieqs = inequalities, eqns = equalities)
     862
    690863    def show(self):
    691864        r"""
    692865        Displays the ``MixedIntegerLinearProgram`` in a human-readable
     
    18442017
    18452018        This example uses the simplex algorthm and prints information::
    18462019
    1847             sage: p = MixedIntegerLinearProgram()
     2020            sage: p = MixedIntegerLinearProgram(solver="GLPK")
    18482021            sage: x, y = p[0], p[1]
    18492022            sage: p.add_constraint(2*x + 3*y, max = 6)
    18502023            sage: p.add_constraint(3*x + 2*y, max = 6)
     
    20872260        """
    20882261        return self._dict.values()
    20892262
    2090 
    2091 
    20922263def Sum(x):
    20932264    """
    20942265    Only for legacy support, use :meth:`MixedIntegerLinearProgram.sum` instead.