Ticket #11949: trac_11949.patch

File trac_11949.patch, 58.7 KB (added by ncohen, 8 years ago)
  • doc/en/reference/numerical.rst

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1319485424 -7200
    # Node ID db118dfd3b1c39af5e7d8c4ad41f8cedca9fe914
    # Parent  60c3bcdefd3adf71af64324e8bc4342dbe31a620
    trac 11949 -- Gurobi Support
    
    diff --git a/doc/en/reference/numerical.rst b/doc/en/reference/numerical.rst
    a b  
    99   sage/numerical/optimize
    1010
    1111LP Solver backends
    12 --------------------------
     12------------------
    1313
    1414.. toctree::
    1515   :maxdepth: 1
     
    1717   sage/numerical/backends/generic_backend
    1818   sage/numerical/backends/glpk_backend
    1919
     20Sage also supports CBC (COIN-OR), CPLEX (ILOG) and Gurobi. In order to find out
     21how to use them in Sage, please refer to the `Thematic Tutorial on Linear
     22Programming
     23<http://www.sagemath.org/doc/thematic_tutorials/linear_programming.html>`_.
     24
  • doc/en/thematic_tutorials/linear_programming.rst

    diff --git a/doc/en/thematic_tutorials/linear_programming.rst b/doc/en/thematic_tutorials/linear_programming.rst
    a b  
    462462  <http://www-01.ibm.com/software/integration/optimization/cplex/>`_:
    463463  A solver from `ILOG <http://www.ilog.com/>`_
    464464
    465   Proprietary and closed source, but free for researchers and students.
     465  Proprietary, but free for researchers and students.
    466466
    467467* `GLPK <http://www.gnu.org/software/glpk/>`_: A solver from `GNU
    468468  <http://www.gnu.org/>`_
    469469
    470470  Licensed under the GPLv3. This solver is installed by default with Sage.
    471471
     472* `GUROBI <http://www.gurobi.com/>`_
    472473
    473 Installing CPLEX
    474 ----------------
     474  Proprietary, but free for researchers and students.
    475475
    476 ILOG's CPLEX being proprietary, you must be in possession of several
    477 files to use it through Sage:
    478476
    479 * A valid license file.
    480 * A compiled version of the CPLEX library (usually named ``libcplex.a``).
    481 * The header file ``cplex.h``.
     477Using CPLEX or GUROBI through Sage
     478----------------------------------
    482479
    483 The license file path must be set the value of the environment
    484 variable ``ILOG_LICENSE_FILE``. For example, you can write::
     480ILOG's CPLEX and GUROBI being proprietary softwares, you must be in possession
     481of several files to use it through Sage. In each case, the **expected** (it may
     482change !) filename is joined.
    485483
    486     export ILOG_LICENSE_FILE=/path/to/the/license/ilog/ilm/access_1.ilm
     484* A valid license file
     485    * CPLEX : a ``.ilm`` file
     486    * GUROBI : a ``.lic`` file
    487487
    488 at the end of your ``.bashrc`` file.
     488* A compiled version of the library
     489    * CPLEX : ``libcplex.a``
     490    * GUROBI : ``libgurobi45.so``
    489491
    490 As Sage also needs the files ``libcplex.a`` and ``cplex.h``, the
    491 easiest way is to create symbolic links to these files in the
    492 appropriate directories:
     492* The library file
     493    * CPLEX : ``cplex.h``
     494    * GUROBI : ``gurobi_c.h``
    493495
    494 * ``libcplex.a`` -- in ``SAGE_ROOT/local/lib/``, type::
     496The environment variable defining the licence's path must also be set when
     497running Sage. You can append to your ``.bashrc`` file one of the following :
    495498
    496     ln -s /path/to/lib/libcplex.a .
     499    * For CPLEX ::
    497500
    498 * ``cplex.h`` -- in ``SAGE_ROOT/local/include/``, type::
     501        export ILOG_LICENSE_FILE=/path/to/the/license/ilog/ilm/access_1.ilm
    499502
    500     ln -s /path/to/include/cplex.h .
     503    * For GUROBI ::
     504   
     505        export GRB_LICENSE_FILE=/path/to/the/license/gurobi.lic
     506
     507
     508As Sage also needs the files library and header files the easiest way is to
     509create symbolic links to these files in the appropriate directories:
     510
     511* For CPLEX:
     512    * ``libcplex.a`` -- in ``SAGE_ROOT/local/lib/``, type::
     513
     514        ln -s /path/to/lib/libcplex.a .
     515
     516    * ``cplex.h`` -- in ``SAGE_ROOT/local/include/``, type::
     517 
     518        ln -s /path/to/include/cplex.h .
     519
     520* For GUROBI
     521
     522    * ``libgurobi45.so`` -- in ``SAGE_ROOT/local/lib/``, type::
     523
     524        ln -s /path/to/lib/libgurobi45.so libgurobi.so
     525
     526    * ``gurobi_c.h`` -- in ``SAGE_ROOT/local/include/``, type::
     527 
     528        ln -s /path/to/include/gurobi_c.h .
     529
     530**It is very important that the names of the symbolic links in Sage's folders**
     531** be precisely as indicated. If the names differ, Sage will not notice that**
     532**the files are present**
    501533
    502534Once this is done, Sage is to be asked to notice the changes by calling::
    503535
  • module_list.py

    diff --git a/module_list.py b/module_list.py
    a b  
    17521752from sage.misc.package import is_package_installed
    17531753
    17541754
     1755if (os.path.isfile(SAGE_INC + "gurobi_c.h") and                                                                                                                                                                                   
     1756    os.path.isfile(SAGE_LOCAL + "/lib/libgurobi.so")):
     1757    ext_modules.append(
     1758        Extension("sage.numerical.backends.gurobi_backend",
     1759                  ["sage/numerical/backends/gurobi_backend.pyx"],
     1760                  include_dirs = [SAGE_INC, "sage/c_lib/include/"],
     1761                  language = 'c',
     1762                  libraries = ["csage", "stdc++", "gurobi"])
     1763        )
     1764
     1765
    17551766if (os.path.isfile(SAGE_INC + "cplex.h") and                                                                                                                                                                                   
    17561767    os.path.isfile(SAGE_LOCAL + "/lib/libcplex.a")):
    17571768    ext_modules.append(
  • sage/numerical/backends/generic_backend.pyx

    diff --git a/sage/numerical/backends/generic_backend.pyx b/sage/numerical/backends/generic_backend.pyx
    a b  
    790790
    791791        - CPLEX (``solver="CPLEX"``). See the
    792792          `CPLEX <http://www.ilog.com/products/cplex/>`_ web site.
    793           An interface to CPLEX is not yet implemented.
     793
     794        - GUROBI (``solver="GUROBI"``). See the `GUROBI
     795          <http://www.gurobi.com/>`_ web site.
    794796
    795797        ``solver`` should then be equal to one of ``"GLPK"``,
    796         ``"Coin"``, ``"CPLEX"``.
     798        ``"Coin"``, ``"CPLEX"``, or ``"GUROBI"``.
    797799
    798800        - If ``solver=None`` (default), the current default solver's name is
    799801          returned.
     
    814816        sage: default_mip_solver("Yeahhhhhhhhhhh")
    815817        Traceback (most recent call last):
    816818        ...
    817         ValueError: 'solver' should be set to 'GLPK', 'Coin', 'CPLEX' or None.
     819        ValueError: 'solver' should be set to 'GLPK', 'Coin', 'CPLEX', 'GUROBI' or None.
    818820        sage: default_mip_solver(former_solver)
    819821    """
    820822    global default_solver
     
    825827            return default_solver
    826828
    827829        else:
    828             for s in ["CPLEX", "Coin", "GLPK"]:
     830            for s in ["CPLEX", "GUROBI", "Coin", "GLPK"]:
    829831                try:
    830832                    default_mip_solver(s)
    831833                    return s
     
    846848        except ImportError:
    847849            raise ValueError("COIN is not available. Please refer to the documentation to install it.")
    848850
     851    elif solver == "GUROBI":
     852        try:
     853            from sage.numerical.backends.gurobi_backend import GurobiBackend
     854            default_solver = solver
     855        except ImportError:
     856            raise ValueError("Gurobi is not available. Please refer to the documentation to install it.")
     857
    849858    elif solver == "GLPK":
    850859        default_solver = solver
    851860
    852861    else:
    853         raise ValueError("'solver' should be set to 'GLPK', 'Coin', 'CPLEX' or None.")
     862        raise ValueError("'solver' should be set to 'GLPK', 'Coin', 'CPLEX', 'GUROBI' or None.")
    854863
    855864cpdef GenericBackend get_solver(constraint_generation = False, solver = None):
    856865    """
     
    858867
    859868    INPUT:
    860869
    861     - ``solver`` -- 3 solvers should be available through this class:
     870    - ``solver`` -- 4 solvers should be available through this class:
    862871   
    863872        - GLPK (``solver="GLPK"``). See the `GLPK
    864873          <http://www.gnu.org/software/glpk/>`_ web site.
     
    868877
    869878        - CPLEX (``solver="CPLEX"``). See the
    870879          `CPLEX <http://www.ilog.com/products/cplex/>`_ web site.
    871           An interface to CPLEX is not yet implemented.
     880
     881        - GUROBI (``solver="GUROBI"``). See the `GUROBI
     882          <http://www.gurobi.com/>`_ web site.
    872883
    873884        ``solver`` should then be equal to one of ``"GLPK"``, ``"Coin"``,
    874         ``"CPLEX"``, or ``None``. If ``solver=None`` (default), the default
    875         solver is used (see ``default_mip_solver`` method.
     885        ``"CPLEX"``, ``"GUROBI"``, or ``None``. If ``solver=None`` (default),
     886        the default solver is used (see ``default_mip_solver`` method.
    876887
    877888    - ``constraint_generation`` (boolean) -- whether the solver
    878889      returned is to be used for constraint/variable generation. As
     
    895906        solver = default_mip_solver()
    896907       
    897908        # We do not want to use Coin for constraint_generation. It just does not
    898         # work with it.
     909        # work
    899910        if solver == "Coin" and constraint_generation:
    900911            solver = "GLPK"
    901912
     
    911922        from sage.numerical.backends.cplex_backend import CPLEXBackend
    912923        return CPLEXBackend()
    913924
     925    elif solver == "GUROBI":
     926        from sage.numerical.backends.gurobi_backend import GurobiBackend
     927        return GurobiBackend()
     928
    914929    else:
    915         raise ValueError("'solver' should be set to 'GLPK', 'Coin', 'CPLEX' or None (in which case the default one is used).")
     930        raise ValueError("'solver' should be set to 'GLPK', 'Coin', 'CPLEX', 'GUROBI' or None (in which case the default one is used).")
    916931
    917932
  • new file sage/numerical/backends/gurobi_backend.pxd

    diff --git a/sage/numerical/backends/gurobi_backend.pxd b/sage/numerical/backends/gurobi_backend.pxd
    new file mode 100644
    - +  
     1##############################################################################
     2#       Copyright (C) 2010 Nathann Cohen <nathann.cohen@gmail.com>
     3#  Distributed under the terms of the GNU General Public License (GPL)
     4#  The full text of the GPL is available at:
     5#                  http://www.gnu.org/licenses/
     6##############################################################################
     7
     8from generic_backend cimport GenericBackend
     9include '../../../../../devel/sage/sage/ext/stdsage.pxi'
     10
     11
     12#cdef extern from *:
     13#    ctypedef double* const_double_ptr "const double*"
     14#    ctypedef char * const_char_ptr "const char*"
     15
     16#cdef extern from "float.h":
     17#    cdef double DBL_MAX
     18
     19cdef extern from "../../../local/include/gurobi_c.h":
     20     ctypedef struct GRBmodel:
     21         pass
     22     ctypedef struct GRBenv:
     23         pass
     24
     25     int GRBloadenv(GRBenv **, char *)
     26     int GRBnewmodel(GRBenv *env, GRBmodel **modelP, char *Pname, int numvars, double *obj, double *lb, double *ub, char *vtype, char **varnames)
     27     int GRBaddvar(GRBmodel *model, int numnz, int *vind, double *vval, double obj, double lb, double ub, char vtype, char *varname)
     28     int GRBaddvars (GRBmodel*model, intnumvars, intnumnz, int*vbeg, int*vind, double*vval, double*obj, double*lb, double*ub, char*vtype, char** varnames )
     29
     30
     31
     32     int GRBaddconstr(GRBmodel *model, int numnz, int *cind, double *cval, char sense, double rhs, char *constrnames)
     33     int GRBaddrangeconstr(GRBmodel *model, int numnz, int *cind, double *cval, double lower, double upper, char *constrnames)
     34
     35
     36     void GRBfreemodel(GRBmodel *model)
     37     void GRBfreeenv(GRBenv *env)
     38     int GRBupdatemodel(GRBmodel *model)
     39     int GRBoptimize(GRBmodel *model)
     40     char * GRBgeterrormsg(GRBenv *env)
     41     int GRBgetintattr(GRBmodel *model, char * attrname, int * result)
     42     int GRBsetintattr(GRBmodel *model, char * attrname, int value)
     43
     44     int GRBgetdblattr(GRBmodel *model, char * attrname, double * result)
     45     int GRBsetdblattr(GRBmodel *model, char * attrname, double value)
     46
     47     int GRBgetdblattrelement (GRBmodel*model, char* attrname, int element, double* valueP )
     48     int GRBsetdblattrelement (GRBmodel*model, char* attrname, int element, double valueP )
     49
     50     int GRBgetcharattrelement (GRBmodel*model, char* attrname, int element, char* valueP )
     51     int GRBsetcharattrelement (GRBmodel*model, char* attrname, int element, char valueP )
     52     int GRBsetstrattr (GRBmodel*model, char* attrname, char * valueP )
     53     int GRBgetstrattr (GRBmodel*model, char* attrname, char ** valueP )
     54
     55     #int GRBsetstrattrelement (GRBmodel*model, char* attrname, int index, char * valueP )
     56     int GRBgetstrattrelement (GRBmodel*model, char* attrname, int index, char ** valueP )
     57
     58
     59     int GRBwrite (GRBmodel*model, char* filename)
     60
     61     int GRBsetintparam(GRBenv *env, char * attrname, int value)
     62
     63     GRBenv * GRBgetenv (GRBmodel * model )
     64     
     65
     66     int GRBgetconstrs (GRBmodel * model, int * numnzP, int * cbeg, int * cind, double * cval, int start, int len )
     67
     68     int GRB_BINARY
     69     int GRB_CONTINUOUS
     70     int GRB_INTEGER
     71     int GRB_INFINITY
     72
     73     char GRB_LESS_EQUAL
     74     char GRB_GREATER_EQUAL
     75     char GRB_EQUAL
     76
     77     int GRB_LOADED
     78     int GRB_OPTIMAL
     79     int GRB_INFEASIBLE
     80     int GRB_INF_OR_UNBD
     81     int GRB_UNBOUNDED
     82     int GRB_CUTOFF
     83     int GRB_ITERATION_LIMIT
     84     int GRB_NODE_LIMIT
     85     int GRB_TIME_LIMIT
     86     int GRB_SOLUTION_LIMIT
     87     int GRB_INTERRUPTED
     88     int GRB_NUMERIC
     89     int GRB_SUBOPTIMAL
     90
     91
     92
     93
     94cdef class GurobiBackend(GenericBackend):
     95
     96    cdef GRBenv * env
     97    cdef GRBmodel ** model
     98   
     99    cdef int num_vars
     100
     101
  • new file sage/numerical/backends/gurobi_backend.pyx

    diff --git a/sage/numerical/backends/gurobi_backend.pyx b/sage/numerical/backends/gurobi_backend.pyx
    new file mode 100644
    - +  
     1"""
     2Gurobi Backend
     3
     4AUTHORS:
     5
     6- Nathann Cohen (2011-10): initial implementation
     7"""
     8
     9##############################################################################
     10#       Copyright (C) 2010 Nathann Cohen <nathann.cohen@gmail.com>
     11#  Distributed under the terms of the GNU General Public License (GPL)
     12#  The full text of the GPL is available at:
     13#                  http://www.gnu.org/licenses/
     14##############################################################################
     15
     16from sage.numerical.mip import MIPSolverException
     17
     18cdef class GurobiBackend(GenericBackend):
     19    def __cinit__(self, maximization = True):
     20        """
     21        Constructor
     22
     23        EXAMPLE::
     24
     25            sage: p = MixedIntegerLinearProgram(solver="Gurobi")            # optional - GUROBI
     26        """
     27        cdef int error
     28
     29        cdef GRBenv ** env
     30        env = <GRBenv **> sage_malloc(sizeof(GRBenv *))
     31       
     32
     33        error = GRBloadenv(env, NULL)
     34
     35        if error or (env[0] == NULL):
     36            raise Exception("Could not initialize Gurobi environment")
     37
     38        self.model = <GRBmodel **> sage_malloc(sizeof(GRBmodel *))
     39        error = GRBnewmodel(env[0], self.model, NULL, 0, NULL, NULL, NULL, NULL, NULL)
     40
     41
     42        self.env = GRBgetenv (self.model[0])
     43
     44
     45        if error:
     46            raise Exception("Could not initialize Gurobi model")
     47
     48        if maximization:
     49            error = GRBsetintattr(self.model[0], "ModelSense", -1)
     50        else:
     51            error = GRBsetintattr(self.model[0], "ModelSense", +1)
     52
     53        check(self.env, error)
     54
     55        self.set_sense(1 if maximization else -1)
     56
     57        self.set_verbosity(0)
     58
     59
     60
     61    cpdef int add_variable(self, lower_bound=0.0, upper_bound=None, binary=False, continuous=False, integer=False, obj=0.0, name=None) except -1:
     62        """
     63        Add a variable.
     64
     65        This amounts to adding a new column to the matrix. By default,
     66        the variable is both positive, real and the coefficient in the
     67        objective function is 0.0.
     68
     69        INPUT:
     70
     71        - ``lower_bound`` - the lower bound of the variable (default: 0)
     72
     73        - ``upper_bound`` - the upper bound of the variable (default: ``None``)
     74
     75        - ``binary`` - ``True`` if the variable is binary (default: ``False``).
     76
     77        - ``continuous`` - ``True`` if the variable is binary (default: ``True``).
     78
     79        - ``integer`` - ``True`` if the variable is binary (default: ``False``).
     80
     81        - ``obj`` - (optional) coefficient of this variable in the objective function (default: 0.0)
     82
     83        - ``name`` - an optional name for the newly added variable (default: ``None``).
     84
     85        OUTPUT: The index of the newly created variable           
     86
     87        EXAMPLE::
     88
     89            sage: from sage.numerical.backends.generic_backend import get_solver # optional - GUROBI
     90            sage: p = get_solver(solver = "Gurobi")                              # optional - GUROBI
     91            sage: p.ncols()                                                      # optional - GUROBI
     92            0
     93            sage: p.add_variable()                                               # optional - GUROBI
     94            0
     95            sage: p.ncols()                                                      # optional - GUROBI
     96            1
     97            sage: p.add_variable(binary=True)                                    # optional - GUROBI
     98            1
     99            sage: p.add_variable(lower_bound=-2.0, integer=True)                 # optional - GUROBI
     100            2
     101            sage: p.add_variable(continuous=True, integer=True)                  # optional - GUROBI
     102            Traceback (most recent call last):
     103            ...
     104            ValueError: ...           
     105            sage: p.add_variable(name='x',obj=1.0)                               # optional - GUROBI
     106            3
     107            sage: p.col_name(3)                                                  # optional - GUROBI
     108            'x'
     109            sage: p.objective_coefficient(3)                                     # optional - GUROBI
     110            1.0
     111        """
     112        # Checking the input
     113        cdef char vtype = int(bool(binary)) + int(bool(continuous)) + int(bool(integer))
     114        if  vtype == 0:
     115            continuous = True           
     116        elif vtype != 1:
     117            raise ValueError("Exactly one parameter of 'binary', 'integer' and 'continuous' must be 'True'.")
     118
     119        cdef int error
     120
     121        if binary:
     122            vtype = GRB_BINARY
     123        elif continuous:
     124            vtype = GRB_CONTINUOUS
     125        elif integer:
     126            vtype = GRB_INTEGER
     127
     128        cdef char * c_name = ""
     129
     130        if name is None:
     131            name = "x_"+str(self.ncols())
     132
     133        c_name = name
     134
     135        if upper_bound is None:
     136            upper_bound = GRB_INFINITY
     137        if lower_bound is None:
     138            lower_bound = -GRB_INFINITY
     139       
     140       
     141        error = GRBaddvar(self.model[0], 0, NULL, NULL, obj, <double> lower_bound, <double> upper_bound, vtype, c_name)
     142
     143        check(self.env,error)
     144
     145        check(self.env,GRBupdatemodel(self.model[0]))
     146
     147        return self.ncols()-1
     148
     149    cpdef int add_variables(self, int number, lower_bound=0.0, upper_bound=None, binary=False, continuous=False, integer=False, obj=0.0, names=None) except -1:
     150        """
     151        Add ``number`` new variables.
     152
     153        This amounts to adding new columns to the matrix. By default,
     154        the variables are both positive, real and theor coefficient in
     155        the objective function is 0.0.
     156
     157        INPUT:
     158
     159        - ``n`` - the number of new variables (must be > 0)
     160
     161        - ``lower_bound`` - the lower bound of the variable (default: 0)
     162
     163        - ``upper_bound`` - the upper bound of the variable (default: ``None``)
     164
     165        - ``binary`` - ``True`` if the variable is binary (default: ``False``).
     166
     167        - ``continuous`` - ``True`` if the variable is binary (default: ``True``).
     168
     169        - ``integer`` - ``True`` if the variable is binary (default: ``False``).
     170
     171        - ``obj`` - (optional) coefficient of all variables in the objective function (default: 0.0)
     172
     173        - ``names`` - optional list of names (default: ``None``)
     174
     175        OUTPUT: The index of the variable created last.
     176
     177        EXAMPLE::
     178
     179            sage: from sage.numerical.backends.generic_backend import get_solver           # optional - GUROBI
     180            sage: p = get_solver(solver = "Gurobi")                                        # optional - GUROBI
     181            sage: p.ncols()                                                                # optional - GUROBI
     182            0
     183            sage: p.add_variables(5)                                                       # optional - GUROBI
     184            4
     185            sage: p.ncols()                                                                # optional - GUROBI
     186            5
     187            sage: p.add_variables(2, lower_bound=-2.0, integer=True, names=['a','b'])      # optional - GUROBI
     188            6
     189        """
     190        cdef int i
     191        cdef int value
     192        for i in range(number):
     193            value = self.add_variable(lower_bound = lower_bound,
     194                              upper_bound = upper_bound,
     195                              binary = binary,
     196                              continuous = continuous,
     197                              integer = integer,
     198                              obj = obj,
     199                              name = None if names is None else names[i])
     200        return value
     201#        cdef double * p_obj = NULL
     202#        cdef double * p_lb = NULL
     203#        cdef double * p_ub = NULL
     204#        cdef char ** p_names = NULL
     205#        cdef char * p_types = NULL
     206#        cdef int i
     207#        cdef int error
     208#
     209#        cdef int NAME_MAX_LEN = 50
     210#
     211#        # Objective coefficients
     212#        if obj:
     213#            p_obj = <double*> sage_malloc(number*sizeof(double))
     214#            for i in range(number):
     215#                p_obj[i] = obj
     216#
     217#        # Lower bounds
     218#        if lower_bound != 0:
     219#            p_lb = <double*> sage_malloc(number*sizeof(double))
     220#            for i in range(number):
     221#                p_lb[i] = -GRB_INFINITY if lower_bound is None else lower_bound
     222#
     223#        # Upper bounds
     224#        if not upper_bound is None:
     225#            p_ub = <double*> sage_malloc(number*sizeof(double))
     226#            for i in range(number):
     227#                p_ub[i] = upper_bound
     228#
     229#        # Type
     230#        if not continuous:
     231#            p_types = <char *> sage_malloc(number*sizeof(char))
     232#            if binary:
     233#                p_types[0] = GRB_BINARY
     234#            else:
     235#                p_types[0] = GRB_INTEGER
     236#               
     237#            for i in range(2, number):
     238#                p_types[i] = p_types[i-1]
     239#
     240#        # Names
     241#        if not names is None:
     242#            p_names = <char **> sage_malloc((number+1)*sizeof(char *))
     243#            p_names[0] = <char *> sage_malloc(number*NAME_MAX_LEN*sizeof(char))
     244#            for i, name in enumerate(names):
     245#                p_names[i+1] = p_names[i] + NAME_MAX_LEN
     246#                p_names[i][0] = str(name)
     247#               
     248#        error = GRBaddvars (self.model[0], number, 0, NULL, NULL, NULL, p_obj, p_lb, p_ub, p_types, p_names)
     249#
     250#        # Freeing the memory
     251#        if p_obj != NULL:
     252#            sage_free(p_obj)
     253#        if p_lb != NULL:
     254#            sage_free(p_lb)
     255#        if p_ub != NULL:
     256#            sage_free(p_ub)
     257#        if p_names != NULL:
     258#            for i in range(number+1):
     259#                sage_free(p_names[i])
     260#            sage_free(p_names)
     261#        if p_types != NULL:
     262#            sage_free(p_types)
     263#
     264#        check(self.env, error)
     265
     266    cpdef set_variable_type(self, int variable, int vtype):
     267        """
     268        Set the type of a variable
     269
     270        INPUT:
     271
     272        - ``variable`` (integer) -- the variable's id
     273
     274        - ``vtype`` (integer) :
     275
     276            *  1  Integer
     277            *  0  Binary
     278            * -1 Real
     279
     280        EXAMPLE::
     281
     282            sage: from sage.numerical.backends.generic_backend import get_solver  # optional - GUROBI
     283            sage: p = get_solver(solver = "Gurobi")                               # optional - GUROBI
     284            sage: p.ncols()                                                       # optional - GUROBI
     285            0
     286            sage: p.add_variable()                                                # optional - GUROBI
     287            0
     288            sage: p.set_variable_type(0,1)                                        # optional - GUROBI
     289            sage: p.is_variable_integer(0)                                        # optional - GUROBI
     290            True
     291        """
     292        cdef int error
     293
     294        if vtype == 1:
     295            error = GRBsetcharattrelement(self.model[0], "VType", variable, 'I')
     296        elif vtype == 0:
     297            error = GRBsetcharattrelement(self.model[0], "VType", variable, 'B')
     298        else:
     299            error = GRBsetcharattrelement(self.model[0], "VType", variable, 'C')
     300        check(self.env, error)
     301
     302        check(self.env,GRBupdatemodel(self.model[0]))
     303
     304    cpdef set_sense(self, int sense):
     305        """
     306        Set the direction (maximization/minimization).
     307
     308        INPUT:
     309
     310        - ``sense`` (integer) :
     311
     312            * +1 => Maximization
     313            * -1 => Minimization
     314
     315        EXAMPLE::
     316
     317            sage: from sage.numerical.backends.generic_backend import get_solver   # optional - GUROBI
     318            sage: p = get_solver(solver = "Gurobi")                                # optional - GUROBI
     319            sage: p.is_maximization()                                              # optional - GUROBI
     320            True
     321            sage: p.set_sense(-1)                                                  # optional - GUROBI
     322            sage: p.is_maximization()                                              # optional - GUROBI
     323            False
     324        """
     325        cdef int error
     326
     327        if sense == 1:
     328            error = GRBsetintattr(self.model[0], "ModelSense", -1)
     329        else:
     330            error = GRBsetintattr(self.model[0], "ModelSense", +1)
     331
     332        check(self.env, error)
     333        check(self.env,GRBupdatemodel(self.model[0]))
     334
     335    cpdef objective_coefficient(self, int variable, coeff=None):
     336        """
     337        Set or get the coefficient of a variable in the objective function
     338
     339        INPUT:
     340
     341        - ``variable`` (integer) -- the variable's id
     342
     343        - ``coeff`` (double) -- its coefficient or ``None`` for
     344          reading (default: ``None``)
     345
     346        EXAMPLE::
     347
     348            sage: from sage.numerical.backends.generic_backend import get_solver   # optional - GUROBI
     349            sage: p = get_solver(solver = "Gurobi")                                # optional - GUROBI
     350            sage: p.add_variable()                                                 # optional - GUROBI
     351            0
     352            sage: p.objective_coefficient(0) == 0                                  # optional - GUROBI
     353            True
     354            sage: p.objective_coefficient(0,2)                                     # optional - GUROBI
     355            sage: p.objective_coefficient(0)                                       # optional - GUROBI
     356            2.0
     357        """
     358        cdef int error
     359        cdef double value[1]
     360
     361        if coeff:
     362            error = GRBsetdblattrelement(self.model[0], "Obj", variable, coeff)
     363            check(self.env, error)
     364            check(self.env,GRBupdatemodel(self.model[0]))
     365        else:
     366            error = GRBgetdblattrelement(self.model[0], "Obj", variable, value)
     367            check(self.env, error)
     368            return value[0]
     369
     370    cpdef problem_name(self, char * name = NULL):
     371        """
     372        Return or define the problem's name
     373
     374        INPUT:
     375
     376        - ``name`` (``char *``) -- the problem's name. When set to
     377          ``NULL`` (default), the method returns the problem's name.
     378
     379        EXAMPLE::
     380
     381            sage: from sage.numerical.backends.generic_backend import get_solver      # optional - GUROBI
     382            sage: p = get_solver(solver = "Gurobi")                                   # optional - GUROBI
     383            sage: p.problem_name("There once was a french fry")                       # optional - GUROBI
     384            sage: print p.problem_name()                                              # optional - GUROBI
     385            There once was a french fry
     386
     387        TESTS::
     388
     389            sage: from sage.numerical.backends.generic_backend import get_solver    # optional - GUROBI
     390            sage: p = get_solver(solver = "Gurobi")                                 # optional - GUROBI
     391            sage: print p.problem_name()                                            # optional - GUROBI
     392        """
     393        cdef int error
     394        cdef char * pp_name[1]
     395
     396        if name:
     397            error = GRBsetstrattr(self.model[0], "ModelName", name)
     398            check(self.env, error)
     399            check(self.env,GRBupdatemodel(self.model[0]))
     400       
     401        else:
     402            check(self.env,GRBgetstrattr(self.model[0], "ModelName", <char **> pp_name))
     403            if pp_name[0] == NULL:
     404                value = ""
     405            else:
     406                value = str(pp_name[0])
     407
     408            return value       
     409
     410    cpdef set_objective(self, list coeff):
     411        """
     412        Set the objective function.
     413
     414        INPUT:
     415
     416        - ``coeff`` - a list of real values, whose ith element is the
     417          coefficient of the ith variable in the objective function.
     418
     419        EXAMPLE::
     420
     421            sage: from sage.numerical.backends.generic_backend import get_solver     # optional - GUROBI
     422            sage: p = get_solver(solver = "Gurobi")                                  # optional - GUROBI
     423            sage: p.add_variables(5)                                                 # optional - GUROBI
     424            4
     425            sage: p.set_objective([1, 1, 2, 1, 3])                                   # optional - GUROBI
     426            sage: map(lambda x :p.objective_coefficient(x), range(5))                # optional - GUROBI
     427            [1.0, 1.0, 2.0, 1.0, 3.0]
     428        """
     429        cdef int i = 0
     430        cdef double value
     431        cdef int error
     432       
     433        for value in coeff:
     434            error = GRBsetdblattrelement (self.model[0], "Obj", i, value)
     435            check(self.env,error)
     436            i += 1
     437
     438        check(self.env,GRBupdatemodel(self.model[0]))
     439
     440    cpdef set_verbosity(self, int level):
     441        """
     442        Set the verbosity level
     443
     444        INPUT:
     445
     446        - ``level`` (integer) -- From 0 (no verbosity) to 3.
     447
     448        EXAMPLE::
     449
     450            sage: from sage.numerical.backends.generic_backend import get_solver   # optional - GUROBI
     451            sage: p = get_solver(solver = "Gurobi")                                # optional - GUROBI
     452            sage: p.set_verbosity(2)                                               # optional - GUROBI
     453
     454        """
     455        cdef int error
     456        if level:
     457            error = GRBsetintparam(self.env, "OutputFlag", 1)
     458        else:
     459            error = GRBsetintparam(self.env, "OutputFlag", 0)
     460
     461        check(self.env, error)
     462
     463    cpdef add_linear_constraint(self, coefficients, lower_bound, upper_bound, name=None):
     464        """
     465        Add a linear constraint.
     466
     467        INPUT:
     468
     469        - ``coefficients`` an iterable with ``(c,v)`` pairs where ``c``
     470          is a variable index (integer) and ``v`` is a value (real
     471          value).
     472
     473        - ``lower_bound`` - a lower bound, either a real value or ``None``
     474
     475        - ``upper_bound`` - an upper bound, either a real value or ``None``
     476
     477        - ``name`` - an optional name for this row (default: ``None``)
     478 
     479        EXAMPLE::
     480
     481            sage: from sage.numerical.backends.generic_backend import get_solver          # optional - GUROBI
     482            sage: p = get_solver(solver = "Gurobi")                                       # optional - GUROBI
     483            sage: p.add_variables(5)                                                      # optional - GUROBI
     484            4
     485            sage: p.add_linear_constraint( zip(range(5), range(5)), 2.0, 2.0)             # optional - GUROBI
     486            sage: p.row(0)                                                                # optional - GUROBI
     487            ([0, 1, 2, 3, 4], [0.0, 1.0, 2.0, 3.0, 4.0])
     488            sage: p.row_bounds(0)                                                         # optional - GUROBI
     489            (2.0, 2.0)
     490            sage: p.add_linear_constraint( zip(range(5), range(5)), 1.0, 1.0, name='foo') # optional - GUROBI
     491            sage: p.row_name(1)                                                           # optional - GUROBI
     492            'foo'
     493        """
     494
     495        if lower_bound is None and upper_bound is None:
     496            raise ValueError("At least one of 'upper_bound' or 'lower_bound' must be set.")
     497
     498        cdef int * row_i
     499        cdef double * row_values
     500
     501        row_i = <int *> sage_malloc((len(coefficients)) * sizeof(int))
     502        row_values = <double *> sage_malloc((len(coefficients)) * sizeof(double))
     503       
     504
     505        for i,(c,v) in enumerate(coefficients):
     506            row_i[i] = c
     507            row_values[i] = v
     508
     509        if name is None:
     510            name = ""
     511
     512        if upper_bound is not None and lower_bound is None:
     513            error = GRBaddconstr(self.model[0], len(coefficients), row_i, row_values, GRB_LESS_EQUAL, <double> upper_bound, name)
     514
     515        elif lower_bound is not None and upper_bound is None:
     516            error = GRBaddconstr(self.model[0], len(coefficients), row_i, row_values, GRB_GREATER_EQUAL, <double> lower_bound, name)
     517
     518        elif upper_bound is not None and lower_bound is not None:
     519            if lower_bound == upper_bound:
     520                error = GRBaddconstr(self.model[0], len(coefficients), row_i, row_values, GRB_EQUAL, <double> lower_bound, name)
     521
     522            else:
     523                error = GRBaddrangeconstr(self.model[0], len(coefficients), row_i, row_values, <double> lower_bound, <double> upper_bound, name)
     524
     525        check(self.env,error)
     526       
     527        error = GRBupdatemodel(self.model[0])
     528
     529        check(self.env,error)
     530
     531        sage_free(row_i)
     532        sage_free(row_values)
     533
     534    cpdef row(self, int index):
     535        r"""
     536        Return a row
     537
     538        INPUT:
     539
     540        - ``index`` (integer) -- the constraint's id.
     541
     542        OUTPUT:
     543
     544        A pair ``(indices, coeffs)`` where ``indices`` lists the
     545        entries whose coefficient is nonzero, and to which ``coeffs``
     546        associates their coefficient on the model of the
     547        ``add_linear_constraint`` method.
     548
     549        EXAMPLE::
     550
     551            sage: from sage.numerical.backends.generic_backend import get_solver   # optional - GUROBI
     552            sage: p = get_solver(solver = "Gurobi")                                # optional - GUROBI
     553            sage: p.add_variables(5)                                               # optional - GUROBI
     554            4
     555            sage: p.add_linear_constraint(zip(range(5), range(5)), 2, 2)           # optional - GUROBI
     556            sage: p.row(0)                                                         # optional - GUROBI
     557            ([0, 1, 2, 3, 4], [0.0, 1.0, 2.0, 3.0, 4.0])
     558            sage: p.row_bounds(0)                                                  # optional - GUROBI
     559            (2.0, 2.0)
     560        """
     561        cdef int error
     562        cdef int fake[1]
     563
     564        cdef int length[1]
     565        error =  GRBgetconstrs(self.model[0], length, NULL, NULL, NULL, index, 1 )
     566        check(self.env,error)
     567       
     568        cdef int * p_indices = <int *> sage_malloc(length[0] * sizeof(int))
     569        cdef double * p_values = <double *> sage_malloc(length[0] * sizeof(double))
     570       
     571        error =  GRBgetconstrs(self.model[0], length, <int *> fake, p_indices, p_values, index, 1 )
     572        check(self.env,error)
     573
     574        cdef list indices = []
     575        cdef list values = []
     576
     577        cdef int i
     578        for i in range(length[0]):
     579            indices.append(p_indices[i])
     580            values.append(p_values[i])
     581
     582        sage_free(p_indices)
     583        sage_free(p_values)
     584       
     585        return indices, values
     586
     587
     588    cpdef row_bounds(self, int index):
     589        """
     590        Return the bounds of a specific constraint.
     591
     592        INPUT:
     593
     594        - ``index`` (integer) -- the constraint's id.
     595
     596        OUTPUT:
     597
     598        A pair ``(lower_bound, upper_bound)``. Each of them can be set
     599        to ``None`` if the constraint is not bounded in the
     600        corresponding direction, and is a real value otherwise.
     601
     602        EXAMPLE::
     603
     604            sage: from sage.numerical.backends.generic_backend import get_solver    # optional - GUROBI
     605            sage: p = get_solver(solver = "Gurobi")                                 # optional - GUROBI
     606            sage: p.add_variables(5)                                                # optional - GUROBI
     607            4
     608            sage: p.add_linear_constraint(zip(range(5), range(5)), 2, 2)            # optional - GUROBI
     609            sage: p.row(0)                                                          # optional - GUROBI
     610            ([0, 1, 2, 3, 4], [0.0, 1.0, 2.0, 3.0, 4.0])
     611            sage: p.row_bounds(0)                                                   # optional - GUROBI
     612            (2.0, 2.0)
     613        """
     614        cdef double d[1]
     615        cdef char sense[1]
     616        cdef int error
     617
     618        error = GRBgetcharattrelement(self.model[0], "Sense", index, <char *> sense)
     619        check(self.env, error)
     620
     621        error = GRBgetdblattrelement(self.model[0], "RHS", index, <double *> d)
     622        check(self.env, error)
     623
     624        if sense[0] == '>':
     625            return (d[0], None)
     626        elif sense[0] == '<':
     627            return (None, d[0])
     628        else:
     629            return (d[0],d[0])
     630
     631    cpdef col_bounds(self, int index):
     632        """
     633        Return the bounds of a specific variable.
     634
     635        INPUT:
     636
     637        - ``index`` (integer) -- the variable's id.
     638
     639        OUTPUT:
     640
     641        A pair ``(lower_bound, upper_bound)``. Each of them can be set
     642        to ``None`` if the variable is not bounded in the
     643        corresponding direction, and is a real value otherwise.
     644
     645        EXAMPLE::
     646
     647            sage: from sage.numerical.backends.generic_backend import get_solver    # optional - GUROBI
     648            sage: p = get_solver(solver = "Gurobi")                                 # optional - GUROBI
     649            sage: p.add_variable()                                                  # optional - GUROBI
     650            0
     651            sage: p.col_bounds(0)                                                   # optional - GUROBI
     652            (0.0, None)
     653            sage: p.variable_upper_bound(0, 5)                                      # optional - GUROBI
     654            sage: p.col_bounds(0)                                                   # optional - GUROBI
     655            (0.0, 5.0)
     656        """
     657
     658        cdef double lb[1], ub[1]
     659
     660        error = GRBgetdblattrelement(self.model[0], "LB", index, <double *> lb)
     661        check(self.env, error)
     662
     663
     664        error = GRBgetdblattrelement(self.model[0], "UB", index, <double *> ub)
     665        check(self.env, error)
     666
     667        return (None if lb[0] <= -2147483647 else lb[0],
     668                None if  (<int> ub[0]) >= 2147483647 else ub[0])
     669
     670    cpdef int solve(self) except -1:
     671        """
     672        Solve the problem.
     673
     674        .. NOTE::
     675
     676            This method raises ``MIPSolverException`` exceptions when
     677            the solution can not be computed for any reason (none
     678            exists, or the LP solver was not able to find it, etc...)
     679
     680        EXAMPLE::
     681
     682            sage: from sage.numerical.backends.generic_backend import get_solver  # optional - GUROBI
     683            sage: p = get_solver(solver = "Gurobi")                               # optional - GUROBI
     684            sage: p.add_variables(5)                                              # optional - GUROBI
     685            4
     686            sage: p.add_linear_constraint([(0,1), (1, 1)], 1.2, 1.7)              # optional - GUROBI
     687            sage: p.set_variable_type(0, 1)                                       # optional - GUROBI
     688            sage: p.set_variable_type(1, 1)                                       # optional - GUROBI
     689            sage: p.solve()                                                       # optional - GUROBI
     690            Traceback (most recent call last):
     691            ...
     692            MIPSolverException: 'Gurobi: The problem is infeasible'
     693        """
     694        cdef int error
     695        global mip_status
     696       
     697        check(self.env, GRBoptimize(self.model[0]))
     698
     699        cdef int status[1]
     700        check(self.env, GRBgetintattr(self.model[0], "Status", <int *> status))
     701
     702        # Has there been a problem ?
     703        if status[0] != GRB_OPTIMAL:
     704            raise MIPSolverException("Gurobi: "+mip_status.get(status[0], "unknown error during call to GRBoptimize : "+str(status[0])))
     705
     706
     707    cpdef double get_objective_value(self):
     708        """
     709        Returns the value of the objective function.
     710
     711        .. NOTE::
     712
     713           Behaviour is undefined unless ``solve`` has been called before.
     714
     715        EXAMPLE::
     716
     717            sage: from sage.numerical.backends.generic_backend import get_solver  # optional - GUROBI
     718            sage: p = get_solver(solver = "Gurobi")                               # optional - GUROBI
     719            sage: p.add_variables(2)                                              # optional - GUROBI
     720            1
     721            sage: p.add_linear_constraint([[0, 1], [1, 2]], None, 3)              # optional - GUROBI
     722            sage: p.set_objective([2, 5])                                         # optional - GUROBI
     723            sage: p.solve()                                                       # optional - GUROBI
     724            0
     725            sage: p.get_objective_value()                                         # optional - GUROBI
     726            7.5
     727            sage: p.get_variable_value(0)                                         # optional - GUROBI
     728            0.0
     729            sage: p.get_variable_value(1)                                         # optional - GUROBI
     730            1.5
     731        """
     732        cdef double p_value[1]
     733       
     734        check(self.env,GRBgetdblattr(self.model[0], "ObjVal", <double* >p_value))
     735
     736        return p_value[0]
     737
     738    cpdef double get_variable_value(self, int variable):
     739        """
     740        Returns the value of a variable given by the solver.
     741
     742        .. NOTE::
     743
     744           Behaviour is undefined unless ``solve`` has been called before.
     745
     746        EXAMPLE::
     747
     748            sage: from sage.numerical.backends.generic_backend import get_solver   # optional - GUROBI
     749            sage: p = get_solver(solver = "Gurobi")                                # optional - GUROBI
     750            sage: p.add_variables(2)                                               # optional - GUROBI
     751            1
     752            sage: p.add_linear_constraint([[0, 1], [1, 2]], None, 3)               # optional - GUROBI
     753            sage: p.set_objective([2, 5])                                          # optional - GUROBI
     754            sage: p.solve()                                                        # optional - GUROBI
     755            0
     756            sage: p.get_objective_value()                                          # optional - GUROBI
     757            7.5
     758            sage: p.get_variable_value(0)                                          # optional - GUROBI
     759            0.0
     760            sage: p.get_variable_value(1)                                          # optional - GUROBI
     761            1.5
     762        """
     763
     764        cdef double value[1]
     765        check(self.env,GRBgetdblattrelement(self.model[0], "X", variable, value))
     766        return round(value[0]) if self.is_variable_binary(variable) else value[0]
     767
     768    cpdef int ncols(self):
     769        """
     770        Return the number of columns/variables.
     771
     772        EXAMPLE::
     773
     774            sage: from sage.numerical.backends.generic_backend import get_solver  # optional - GUROBI
     775            sage: p = get_solver(solver = "Gurobi")                               # optional - GUROBI
     776            sage: p.ncols()                                                       # optional - GUROBI
     777            0
     778            sage: p.add_variables(2)                                              # optional - GUROBI
     779            1
     780            sage: p.ncols()                                                       # optional - GUROBI
     781            2
     782        """
     783        cdef int i[1]
     784        check(self.env,GRBgetintattr(self.model[0], "NumVars", i))
     785        return i[0]
     786
     787    cpdef int nrows(self):
     788        """
     789        Return the number of rows/constraints.
     790
     791        EXAMPLE::
     792
     793            sage: from sage.numerical.backends.generic_backend import get_solver # optional - GUROBI
     794            sage: p = get_solver(solver = "Gurobi")                              # optional - GUROBI
     795            sage: p.nrows()                                                      # optional - GUROBI
     796            0
     797            sage: p.add_linear_constraint([], 2, None)                           # optional - GUROBI
     798            sage: p.add_linear_constraint([], 2, None)                           # optional - GUROBI
     799            sage: p.nrows()                                                      # optional - GUROBI
     800            2
     801        """
     802        cdef int i[1]
     803        check(self.env,GRBgetintattr(self.model[0], "NumConstrs", i))
     804        return i[0]
     805
     806    cpdef col_name(self, int index):
     807        """
     808        Return the ``index`` th col name
     809
     810        INPUT:
     811
     812        - ``index`` (integer) -- the col's id
     813
     814        EXAMPLE::
     815
     816            sage: from sage.numerical.backends.generic_backend import get_solver  # optional - GUROBI
     817            sage: p = get_solver(solver = "Gurobi")                               # optional - GUROBI
     818            sage: p.add_variable(name='I am a variable')                          # optional - GUROBI
     819            0
     820            sage: p.col_name(0)                                                   # optional - GUROBI
     821            'I am a variable'
     822        """
     823        cdef char * name[1]
     824        check(self.env,GRBgetstrattrelement(self.model[0], "VarName", index, <char **> name))
     825        if name[0] == NULL:
     826            value = ""
     827        else:
     828            value = str(name[0])
     829        return value
     830
     831    cpdef row_name(self, int index):
     832        """
     833        Return the ``index`` th row name
     834
     835        INPUT:
     836
     837        - ``index`` (integer) -- the row's id
     838
     839        EXAMPLE::
     840
     841            sage: from sage.numerical.backends.generic_backend import get_solver  # optional - GUROBI
     842            sage: p = get_solver(solver = "Gurobi")                               # optional - GUROBI
     843            sage: p.add_linear_constraint([], 2, None, name='Empty constraint 1') # optional - GUROBI
     844            sage: p.row_name(0)                                                   # optional - GUROBI
     845            'Empty constraint 1'
     846        """
     847        cdef char * name[1]
     848        check(self.env,GRBgetstrattrelement(self.model[0], "ConstrName", index, <char **> name))
     849        if name[0] == NULL:
     850            value = ""
     851        else:
     852            value = str(name[0])
     853        return value
     854
     855    cpdef bint is_variable_binary(self, int index):
     856        """
     857        Test whether the given variable is of binary type.
     858
     859        INPUT:
     860
     861        - ``index`` (integer) -- the variable's id
     862
     863        EXAMPLE::
     864
     865            sage: from sage.numerical.backends.generic_backend import get_solver   # optional - GUROBI
     866            sage: p = get_solver(solver = "Gurobi")                                # optional - GUROBI
     867            sage: p.ncols()                                                        # optional - GUROBI
     868            0
     869            sage: p.add_variable()                                                 # optional - GUROBI
     870            0
     871            sage: p.set_variable_type(0,0)                                         # optional - GUROBI
     872            sage: p.is_variable_binary(0)                                          # optional - GUROBI
     873            True
     874        """
     875        cdef char vtype[1]
     876        check(self.env, GRBgetcharattrelement(self.model[0], "VType", index, <char *> vtype))
     877        return vtype[0] == 'B'
     878
     879
     880    cpdef bint is_variable_integer(self, int index):
     881        """
     882        Test whether the given variable is of integer type.
     883
     884        INPUT:
     885
     886        - ``index`` (integer) -- the variable's id
     887
     888        EXAMPLE::
     889
     890            sage: from sage.numerical.backends.generic_backend import get_solver  # optional - GUROBI
     891            sage: p = get_solver(solver = "Gurobi")                               # optional - GUROBI
     892            sage: p.ncols()                                                       # optional - GUROBI
     893            0
     894            sage: p.add_variable()                                                # optional - GUROBI
     895            0
     896            sage: p.set_variable_type(0,1)                                        # optional - GUROBI
     897            sage: p.is_variable_integer(0)                                        # optional - GUROBI
     898            True
     899        """
     900        cdef char vtype[1]
     901        check(self.env, GRBgetcharattrelement(self.model[0], "VType", index, <char *> vtype))
     902        return vtype[0] == 'I'
     903
     904    cpdef bint is_variable_continuous(self, int index):
     905        """
     906        Test whether the given variable is of continuous/real type.
     907
     908        INPUT:
     909
     910        - ``index`` (integer) -- the variable's id
     911
     912        EXAMPLE::
     913
     914            sage: from sage.numerical.backends.generic_backend import get_solver   # optional - GUROBI
     915            sage: p = get_solver(solver = "Gurobi")                                # optional - GUROBI
     916            sage: p.ncols()                                                        # optional - GUROBI
     917            0
     918            sage: p.add_variable()                                                 # optional - GUROBI
     919            0
     920            sage: p.is_variable_continuous(0)                                      # optional - GUROBI
     921            True
     922            sage: p.set_variable_type(0,1)                                         # optional - GUROBI
     923            sage: p.is_variable_continuous(0)                                      # optional - GUROBI
     924            False
     925
     926        """
     927        cdef char vtype[1]
     928        check(self.env, GRBgetcharattrelement(self.model[0], "VType", index, <char *> vtype))
     929        return vtype[0] == 'C'
     930
     931    cpdef bint is_maximization(self):
     932        """
     933        Test whether the problem is a maximization
     934
     935        EXAMPLE::
     936
     937            sage: from sage.numerical.backends.generic_backend import get_solver    # optional - GUROBI
     938            sage: p = get_solver(solver = "Gurobi")                                 # optional - GUROBI
     939            sage: p.is_maximization()                                               # optional - GUROBI
     940            True
     941            sage: p.set_sense(-1)                                                   # optional - GUROBI
     942            sage: p.is_maximization()                                               # optional - GUROBI
     943            False
     944        """
     945        cdef int sense[1]
     946        check(self.env,GRBgetintattr(self.model[0], "ModelSense", <int *> sense))
     947        return sense[0] == -1
     948
     949    cpdef variable_upper_bound(self, int index, value = False):
     950        """
     951        Return or define the upper bound on a variable
     952
     953        INPUT:
     954
     955        - ``index`` (integer) -- the variable's id
     956
     957        - ``value`` -- real value, or ``None`` to mean that the
     958          variable has not upper bound. When set to ``False``
     959          (default), the method returns the current value.
     960
     961        EXAMPLE::
     962
     963            sage: from sage.numerical.backends.generic_backend import get_solver    # optional - GUROBI
     964            sage: p = get_solver(solver = "Gurobi")                                 # optional - GUROBI
     965            sage: p.add_variable()                                                  # optional - GUROBI
     966            0
     967            sage: p.col_bounds(0)                                                   # optional - GUROBI
     968            (0.0, None)
     969            sage: p.variable_upper_bound(0, 5)                                      # optional - GUROBI
     970            sage: p.col_bounds(0)                                                   # optional - GUROBI
     971            (0.0, 5.0)
     972        """
     973        cdef double b[1]
     974
     975        if not value is False:
     976            check(self.env, GRBsetdblattrelement(
     977                    self.model[0], "UB",
     978                    index,
     979                    value if value is not None else GRB_INFINITY))
     980
     981            check(self.env,GRBupdatemodel(self.model[0]))
     982        else:
     983            error = GRBgetdblattrelement(self.model[0], "UB", index, <double *> b)
     984            check(self.env, error)
     985            return None if b[0] >= 2147483647 else b[0]
     986
     987    cpdef variable_lower_bound(self, int index, value = False):
     988        """
     989        Return or define the lower bound on a variable
     990
     991        INPUT:
     992
     993        - ``index`` (integer) -- the variable's id
     994
     995        - ``value`` -- real value, or ``None`` to mean that the
     996          variable has not lower bound. When set to ``False``
     997          (default), the method returns the current value.
     998
     999        EXAMPLE::
     1000
     1001            sage: from sage.numerical.backends.generic_backend import get_solver    # optional - GUROBI
     1002            sage: p = get_solver(solver = "Gurobi")                                 # optional - GUROBI
     1003            sage: p.add_variable()                                                  # optional - GUROBI
     1004            0
     1005            sage: p.col_bounds(0)                                                   # optional - GUROBI
     1006            (0.0, None)
     1007            sage: p.variable_lower_bound(0, 5)                                      # optional - GUROBI
     1008            sage: p.col_bounds(0)                                                   # optional - GUROBI
     1009            (5.0, None)
     1010        """
     1011        cdef double b[1]
     1012
     1013       
     1014        if not value is False:
     1015            check(self.env, GRBsetdblattrelement(
     1016                    self.model[0], "LB",
     1017                    index,
     1018                    value if value is not None else -GRB_INFINITY))
     1019
     1020            check(self.env,GRBupdatemodel(self.model[0]))
     1021
     1022        else:
     1023            error = GRBgetdblattrelement(self.model[0], "LB", index, <double *> b)
     1024            check(self.env, error)
     1025            return None if b[0] <= -2147483647 else b[0]
     1026
     1027    cpdef write_lp(self, char * filename):
     1028        """
     1029        Write the problem to a .lp file
     1030
     1031        INPUT:
     1032       
     1033        - ``filename`` (string)
     1034
     1035        EXAMPLE::
     1036
     1037            sage: from sage.numerical.backends.generic_backend import get_solver    # optional - GUROBI
     1038            sage: p = get_solver(solver = "Gurobi")                                 # optional - GUROBI
     1039            sage: p.add_variables(2)                                                # optional - GUROBI
     1040            1
     1041            sage: p.add_linear_constraint([[0, 1], [1, 2]], None, 3)                # optional - GUROBI
     1042            sage: p.set_objective([2, 5])                                           # optional - GUROBI
     1043            sage: p.write_lp(SAGE_TMP+"/lp_problem.lp")                             # optional - GUROBI
     1044        """
     1045        check(self.env, GRBwrite(self.model[0], filename))
     1046
     1047    cpdef write_mps(self, char * filename, int modern):
     1048        """
     1049        Write the problem to a .mps file
     1050
     1051        INPUT:
     1052       
     1053        - ``filename`` (string)
     1054
     1055        EXAMPLE::
     1056
     1057            sage: from sage.numerical.backends.generic_backend import get_solver    # optional - GUROBI
     1058            sage: p = get_solver(solver = "Gurobi")                                 # optional - GUROBI
     1059            sage: p.add_variables(2)                                                # optional - GUROBI
     1060            1
     1061            sage: p.add_linear_constraint([[0, 1], [1, 2]], None, 3)                # optional - GUROBI
     1062            sage: p.set_objective([2, 5])                                           # optional - GUROBI
     1063            sage: p.write_lp(SAGE_TMP+"/lp_problem.lp")                             # optional - GUROBI
     1064        """
     1065        check(self.env, GRBwrite(self.model[0], filename))
     1066
     1067    def __dealloc__(self):
     1068        """
     1069        Destructor
     1070        """
     1071        GRBfreemodel(self.model[0])
     1072
     1073
     1074cdef dict errors = {
     1075    10001 : "GRB_ERROR_OUT_OF_MEMORY",
     1076    10002 : "GRB_ERROR_NULL_ARGUMENT",
     1077    10003 : "GRB_ERROR_INVALID_ARGUMENT",
     1078    10004 : "GRB_ERROR_UNKNOWN_ATTRIBUTE",
     1079    10005 : "GRB_ERROR_DATA_NOT_AVAILABLE",
     1080    10006 : "GRB_ERROR_INDEX_OUT_OF_RANGE",
     1081    10007 : "GRB_ERROR_UNKNOWN_PARAMETER",
     1082    10008 : "GRB_ERROR_VALUE_OUT_OF_RANGE",
     1083    10009 : "GRB_ERROR_NO_LICENSE",
     1084    10010 : "GRB_ERROR_SIZE_LIMIT_EXCEEDED",
     1085    10011 : "GRB_ERROR_CALLBACK",
     1086    10012 : "GRB_ERROR_FILE_READ",
     1087    10013 : "GRB_ERROR_FILE_WRITE",
     1088    10014 : "GRB_ERROR_NUMERIC",
     1089    10015 : "GRB_ERROR_IIS_NOT_INFEASIBLE",
     1090    10016 : "GRB_ERROR_NOT_FOR_MIP",
     1091    10017 : "GRB_ERROR_OPTIMIZATION_IN_PROGRESS",
     1092    10018 : "GRB_ERROR_DUPLICATES",
     1093    10019 : "GRB_ERROR_NODEFILE",
     1094    10020 : "GRB_ERROR_Q_NOT_PSD",
     1095}
     1096
     1097cdef dict mip_status = {
     1098    GRB_INFEASIBLE: "The problem is infeasible",
     1099    GRB_INF_OR_UNBD: "The problem is infeasible or unbounded",
     1100    GRB_UNBOUNDED: "The problem is unbounded",
     1101    GRB_ITERATION_LIMIT: "The iteration limit has been reached",
     1102    GRB_NODE_LIMIT: "The node limit has been reached",
     1103    GRB_TIME_LIMIT: "The time limit has been reached",
     1104    GRB_SOLUTION_LIMIT: "The solution limit has been reached",
     1105}
     1106
     1107cdef check(GRBenv * env, int error):
     1108    if error:
     1109        raise MIPSolverException("Gurobi: "+str(GRBgeterrormsg(env))+" ("+errors[error]+")")
     1110
  • sage/numerical/mip.pyx

    diff --git a/sage/numerical/mip.pyx b/sage/numerical/mip.pyx
    a b  
    114114        <http://www.coin-or.org>`_ web site.
    115115
    116116      - CPLEX (``solver="CPLEX"``). See the `CPLEX
    117         <http://www.ilog.com/products/cplex/>`_ web site.  An interface to
    118         CPLEX is not yet implemented.
     117        <http://www.ilog.com/products/cplex/>`_ web site.
    119118
    120         ``solver`` should then be equal to one of ``"GLPK"``, ``"Coin"``,
    121         ``"CPLEX"``, or ``None``.
     119      - GUROBI (``solver="GUROBI"``). See the `GUROBI <http://www.gurobi.com/>`_
     120          web site.
    122121
    123122      - If ``solver=None`` (default), the default solver is used (see
    124123        ``default_mip_solver`` method.
     
    171170            <http://www.ilog.com/products/cplex/>`_ web site.  An interface to
    172171            CPLEX is not yet implemented.
    173172
    174             ``solver`` should then be equal to one of ``"GLPK"``, ``"Coin"``,
    175             ``"CPLEX"``, or ``None``. If ``solver=None`` (default), the default
    176             solver is used (see ``default_mip_solver`` method.
     173          - GUROBI (``solver="GUROBI"``). See the `GUROBI
     174            <http://www.gurobi.com/>`_ web site.
     175
     176          -If ``solver=None`` (default), the default solver is used (see
     177           ``default_mip_solver`` method.
    177178
    178179        - ``maximization``
    179180
     
    189190
    190191        - :meth:`default_mip_solver` -- Returns/Sets the default MIP solver.
    191192
    192 
    193193        EXAMPLE::
    194194
    195195            sage: p = MixedIntegerLinearProgram(maximization=True)
     
    676676            sage: p.solve()
    677677            0.0
    678678        """
    679 
    680679        cdef list values = []
    681680
    682681        # If the objective is None, or a constant, we want to remember
     
    696695        for i in range(self._backend.ncols()):
    697696            values.append(f.get(i,0))
    698697
     698
    699699        self._backend.set_objective(values)
    700700           
    701701    def add_constraint(self, linear_function, max=None, min=None, name=None):