Ticket #9853: trac_9853.patch

File trac_9853.patch, 41.0 KB (added by ncohen, 11 years ago)
  • module_list.py

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1283540524 -7200
    # Node ID 74cf4208d81e6b95fa4a2b62ee7a5aaaef1ff213
    # Parent  12663152c47016462d0248e5b32740a5a1c406c4
    trac 9853 - Enumerate Integer solution of a LP through new CPLEX interface
    
    diff -r 12663152c470 -r 74cf4208d81e module_list.py
    a b  
    15781578
    15791579from sage.misc.package import is_package_installed
    15801580
    1581 
     1581######### GLPK
    15821582if is_package_installed('glpk'):
    15831583    ext_modules.append(
    15841584        Extension("sage.numerical.mip_glpk",
     
    15881588                  libraries=["csage", "stdc++", "glpk", "gmp", "z"])
    15891589        )
    15901590
     1591######### CPLEX
     1592if (os.path.isfile(SAGE_ROOT+"/local/include/cplex.h") and
     1593    os.path.isfile(SAGE_ROOT+"/local/lib/libcplex.a")):
     1594    ext_modules.append(
     1595        Extension("sage.numerical.mip_cplex",
     1596                  ["sage/numerical/mip_cplex.pyx"],
     1597                  include_dirs = [SAGE_ROOT+"/local/include/","/sage/c_lib/include/"],
     1598                  language = 'c',
     1599                  libraries = ["csage", "stdc++", "cplex"])
     1600        )
     1601
     1602
     1603######### CBC (Coin Branch and Cut)
    15911604if is_package_installed('cbc'):
    15921605
    15931606    ext_modules.append(
     
    15991612        )
    16001613
    16011614
     1615    # if Cplex is compiled through CBC, we add the interface "CPLEX
     1616    # through OSI" (file numerical/mip_osi_cplex)
     1617
    16021618    if os.path.isfile(SAGE_ROOT+"/local/include/coin/OsiCpxSolverInterface.hpp"):
    1603     # if Cplex is installed too
    16041619        ext_modules.append(
    16051620            Extension("sage.numerical.mip_coin",
    16061621                      ["sage/numerical/mip_coin.pyx"],
     
    16111626           
    16121627            )
    16131628        ext_modules.append(
    1614             Extension("sage.numerical.mip_cplex",
    1615                       ["sage/numerical/mip_cplex.pyx"],
     1629            Extension("sage.numerical.mip_osi_cplex",
     1630                      ["sage/numerical/mip_osi_cplex.pyx"],
    16161631                      include_dirs = [SAGE_ROOT+"/local/include/","/sage/c_lib/include/"],
    16171632                      language = 'c++',
    16181633                      libraries = ["csage", "stdc++", "Cbc", "CbcSolver", "Cgl", "Clp", "CoinUtils", "OsiCbc", "OsiClp", "Osi", "OsiVol", "Vol", "OsiCpx"])
  • sage/numerical/mip.pyx

    diff -r 12663152c470 -r 74cf4208d81e sage/numerical/mip.pyx
    a b  
    10941094
    10951095          - CPLEX (``solver="CPLEX"``). See the
    10961096            `CPLEX <http://www.ilog.com/products/cplex/>`_ web site.
    1097             An interface to CPLEX is not yet implemented.
    10981097
    1099           ``solver`` should then be equal to one of ``"GLPK"``, ``"Coin"``,
    1100           ``"CPLEX"``, or ``None``. If ``solver=None`` (default), the default
    1101           solver is used (COIN if available, GLPK otherwise).
     1098          - CPLEX through OSI (``solver="OSI_CPLEX"``). Same as
     1099            previously, but the CPLEX library is this time used
     1100            through COIN's OSI interface.
     1101
     1102          ``solver`` should then be equal to one of ``"GLPK"``,
     1103          ``"Coin"``, ``"CPLEX"``, ``"OSI_CPLEX"``, or ``None``. If
     1104          ``solver=None`` (default), the default solver is used (COIN
     1105          if available, GLPK otherwise).
    11021106
    11031107        - ``log`` -- integer (default: ``0``) The verbosity level. Indicates
    11041108          whether progress should be printed during computation.
     
    11721176                from sage.numerical.mip_glpk import solve_glpk as solve
    11731177            elif solver == "CPLEX":
    11741178                from sage.numerical.mip_cplex import solve_cplex as solve
     1179            elif solver == "OSI_CPLEX":
     1180                from sage.numerical.mip_osi_cplex import solve_cplex as solve
    11751181            else:
    1176                 raise ValueError("'solver' should be set to 'GLPK', 'Coin', 'CPLEX' or None (in which case the default one is used).")
     1182                raise ValueError("'solver' should be set to 'GLPK', 'Coin', 'CPLEX', 'OSI_CPLEX' or None (in which case the default one is used).")
    11771183
    11781184        except ImportError:
    11791185            from sage.misc.exceptions import OptionalPackageNotFoundError
     
    11841190            return solve(self, log=log, objective_only=objective_only, threads=threads)
    11851191        else:
    11861192            return solve(self, log=log, objective_only=objective_only)
    1187        
     1193
     1194    def solve_next(self, log = 0):
     1195        r"""
     1196        Computes the next solution of the MILP.
     1197
     1198        This method can be used to iterate through all the solutions
     1199        of a Mixed Integer Linear Program.
     1200
     1201        INPUT:
     1202
     1203        - ``log`` -- integer (default: ``0``) The verbosity level. Indicates
     1204          whether progress should be printed during computation.
     1205
     1206        OUTPUT:
     1207
     1208        This method return the optimal value of the objective function
     1209        (as ``solve`` does), which obviously stays the same at each
     1210        call. The solution stored in the ``MixedIntegerLinearProgram``
     1211        object, though, is modified.
     1212
     1213        .. NOTE::
     1214
     1215                * Only available through the optional package CPLEX
     1216           
     1217                * All the solutions are still in memory inside of
     1218                  CPLEX's solution pool (TODO: Fix it !)
     1219
     1220        EXAMPLE:
     1221
     1222        `a`, `b`, and `c` are three binary variables whose sum is less
     1223        than 2. Let us find out which values they can take::
     1224
     1225            sage: p = MixedIntegerLinearProgram()
     1226            sage: p.set_objective(None)
     1227            sage: p.add_constraint( p['a'] + p['b'] + p['c'] <= 2 )
     1228            sage: p.set_binary(p['a'])
     1229            sage: p.set_binary(p['b'])
     1230            sage: p.set_binary(p['c'])
     1231            sage: try:                                 # optional - CPLEX
     1232            ...     while True:                        # optional - CPLEX
     1233            ...        obj = p.solve_next()            # optional - CPLEX
     1234            ...        a = p.get_values(p['a'])        # optional - CPLEX
     1235            ...        b = p.get_values(p['b'])        # optional - CPLEX
     1236            ...        c = p.get_values(p['c'])        # optional - CPLEX
     1237            ...        print a,b,c                     # optional - CPLEX
     1238            ... except:                                # optional - CPLEX
     1239            ...      pass                              # optional - CPLEX
     1240            0 0 0
     1241            1 0 0
     1242            0 1 0
     1243            1 1 0
     1244            0 1 1
     1245            1 0 1
     1246            0 0 1
     1247
     1248        We now try to enumerate the permutation matrices on 3
     1249        elements using LP::
     1250
     1251            sage: p = MixedIntegerLinearProgram()
     1252            sage: p.set_objective(None)
     1253            sage: v = p.new_variable(dim = 2)
     1254            sage: I = range(3)
     1255            sage: for i in I:
     1256            ...      p.add_constraint( sum( v[i][j] for j in I ) == 1)
     1257            ...
     1258            sage: for i in I:
     1259            ...      p.add_constraint( sum( v[j][i] for j in I ) == 1)
     1260            ...
     1261            sage: p.set_binary(v)
     1262            sage: def print_result():
     1263            ...      v_sol = p.get_values(v)
     1264            ...      for i in I:
     1265            ...         for j in I:
     1266            ...            print v_sol[i][j],
     1267            ...         print ""
     1268            ...      print "-"
     1269            ...
     1270            sage: try:                       # optional - CPLEX
     1271            ...     while True:              # optional - CPLEX
     1272            ...        obj = p.solve_next()  # optional - CPLEX
     1273            ...        print_result()        # optional - CPLEX
     1274            ...                              # optional - CPLEX
     1275            ... except:                      # optional - CPLEX
     1276            ...      pass                    # optional - CPLEX
     1277            0 0 1
     1278            0 1 0
     1279            1 0 0
     1280            -
     1281            1 0 0
     1282            0 0 1
     1283            0 1 0
     1284            -
     1285            0 1 0
     1286            0 0 1
     1287            1 0 0
     1288            -
     1289            0 0 1
     1290            1 0 0
     1291            0 1 0
     1292            -
     1293            1 0 0
     1294            0 1 0
     1295            0 0 1
     1296            -
     1297            0 1 0
     1298            1 0 0
     1299            0 0 1
     1300            -
     1301        """
     1302        if not hasattr(self, "_cplex_backend"):
     1303
     1304            from sage.numerical.mip_cplex import get_CPX_instance
     1305            self._cplex_backend = get_CPX_instance(self, log=log)
     1306
     1307        obj = self._cplex_backend.compute_next_solution(False)
     1308        self._cplex_backend.save_solution(self)
     1309        return obj
     1310           
    11881311
    11891312    def _add_element_to_ring(self, vtype):
    11901313        r"""
  • sage/numerical/mip_cplex.pxd

    diff -r 12663152c470 -r 74cf4208d81e sage/numerical/mip_cplex.pxd
    a b  
     1cdef struct c_cpxlp
     2
    13cdef extern from *:
    24    ctypedef double* const_double_ptr "const double*"
    35
    4 cdef extern from "../../local/include/coin/CoinPackedVector.hpp":
    5      ctypedef struct c_CoinPackedVector "CoinPackedVector":
    6          void insert(float, float)
    7      c_CoinPackedVector *new_c_CoinPackedVector "new CoinPackedVector" ()
    8      void del_CoinPackedVector "delete" (c_CoinPackedVector *)
    9 cdef extern from "../../local/include/coin/CoinPackedMatrix.hpp":
    10      ctypedef struct c_CoinPackedMatrix "CoinPackedMatrix":
    11          void setDimensions(int, int)
    12          void appendRow(c_CoinPackedVector)
    13      c_CoinPackedMatrix *new_c_CoinPackedMatrix "new CoinPackedMatrix" (bool, double, double)
    14      void del_CoinPackedMatrix "delete" (c_CoinPackedMatrix *)
    156
    16 cdef extern from "../../local/include/coin/OsiCpxSolverInterface.hpp":
    17      ctypedef struct c_OsiCpxSolverInterface "OsiCpxSolverInterface":
    18          double getInfinity()
    19          void loadProblem(c_CoinPackedMatrix, const_double_ptr, const_double_ptr, const_double_ptr, const_double_ptr, const_double_ptr)
    20          void assignProblem(c_CoinPackedMatrix *, const_double_ptr, const_double_ptr, const_double_ptr, const_double_ptr, const_double_ptr)
    21          void writeMps(char *, char *, double)
    22          void initialSolve()
    23          void branchAndBound()
    24          void readMps(string)
    25          float getObjValue()
    26          double * getColSolution()
    27          void setObjSense (double )
    28          void setLogLevel(int)
    29          void setInteger(int)
    30          void setContinuous(int)
    31          int isAbandoned ()
    32          int isProvenOptimal ()
    33          int isProvenPrimalInfeasible ()
    34          int isProvenDualInfeasible ()
    35          int isPrimalObjectiveLimitReached ()
    36          int isDualObjectiveLimitReached ()
    37          int isIterationLimitReached ()
    38          void setMaximumSolutions(int)
    39          int getMaximumSolutions()
    40      c_OsiCpxSolverInterface *new_c_OsiCpxSolverInterface "new OsiCpxSolverInterface" ()
    41      void del_OsiCpxSolverInterface "delete" (c_OsiCpxSolverInterface *)
     7cdef class CPX:
     8    cdef bool _mixed
     9    cdef c_cpxlp * env
     10    cdef c_cpxlp * lp
     11    cdef current_sol
    4212
    4313
     14cdef extern from "../../local/include/cplex.h":
    4415
    45 from sage.numerical.osi_interface cimport Osi_interface
    46 from sage.numerical.osi_interface cimport c_OsiSolverInterface
     16     # Create problem
     17     c_cpxlp * CPXcreateprob (c_cpxlp *  env, int *status_p,
     18                              char *probname_str)
     19
     20     # Add constraints
     21     int CPXaddrows (c_cpxlp * env, c_cpxlp *  lp, int ccnt, int rcnt,
     22                   int nzcnt, double *rhs, char *sense,
     23                   int *rmatbeg, int *rmatind,
     24                   double *rmatval, char **colname,
     25                   char **rowname)
     26
     27     # Solve MILP
     28     int CPXmipopt (c_cpxlp * env, c_cpxlp * lp)
     29
     30     # Solve LP
     31     int CPXlpopt (c_cpxlp * env, c_cpxlp * lp)
     32
     33     # Solve MILP through filling the solution pool
     34     int CPXpopulate (c_cpxlp * env, c_cpxlp * lp)
     35
     36     # Number of solutions in the pool
     37     int CPXgetsolnpoolx (c_cpxlp * env, c_cpxlp * lp, int id, double * x, int beg, int end)
     38
     39     # Set the sense of the optimization problem
     40     int CPXchgobjsen(c_cpxlp * env, c_cpxlp * lp, int)
     41
     42     # Set a "double" parameter
     43     int CPXsetdblparam (c_cpxlp * env, int, double)
     44
     45     # Set an integer parameter
     46     int CPXsetintparam  (c_cpxlp * env, int whichparam, int newvalue)
     47
     48     # Number of solutions in the pool
     49     int CPXgetsolnpoolnumsolns (c_cpxlp * env, c_cpxlp * lp)
     50
     51     # Number of replaces solutions in the pool
     52     int CPXgetsolnpoolnumreplaced(c_cpxlp * env, c_cpxlp * lp)
     53     
     54     # Remove a solution from the pool
     55     int CPXdelsolnpoolsolns (c_cpxlp * env, c_cpxlp * lp, int begin, int end)
     56
     57     int CPXgetsubstat (c_cpxlp * env, c_cpxlp * lp)
     58
     59     # Get the objective value
     60     int CPXgetobjval (c_cpxlp *, c_cpxlp *, double *)
     61
     62     # Add columns
     63     int CPXnewcols(c_cpxlp * env, c_cpxlp * lp, int, double *, double *, double *, char *, char **)
     64
     65     # get solution of a MILP
     66     int CPXsolution(c_cpxlp * env, c_cpxlp * lp, int * lpstat, double * obj, double * x, double *, double *, double *)
     67
     68     # Create a CPLEX enviromnment
     69     c_cpxlp * CPXopenCPLEX (int *status_p)
     70
     71     # Close a CPLEX enviromnment
     72     int * CPXcloseCPLEX (c_cpxlp * env)
     73
     74
     75     # CONSTANTS
     76     int CPX_ON = 1
     77     int CPX_PARAM_SCRIND = 1035
     78     int CPX_INFBOUND = 1.0E+20
     79     int CPX_PARAM_POPULATELIM = 2108
     80     int CPX_PARAM_SOLNPOOLGAP = 2105
     81     int CPX_PARAM_SOLNPOOLINTENSITY = 2107
     82     int CPX_MAX = -1
     83     int CPX_MIN = 1
  • sage/numerical/mip_cplex.pyx

    diff -r 12663152c470 -r 74cf4208d81e sage/numerical/mip_cplex.pyx
    a b  
    11include '../../../../devel/sage/sage/ext/stdsage.pxi'
     2include '../ext/cdefs.pxi'           
     3
    24
    35cdef int BINARY = 1
    46cdef int REAL = -1
    57cdef int INTEGER = 0
     8cdef int status
    69
    710
     11def solve_cplex(self, log=0,objective_only=False):
     12    r"""
     13    Solves the MILP
    814
    9 def solve_cplex(self,log=0,objective_only=False):
    10     r"""
    11     Solves the ``MixedIntegerLinearProgram`` using CPLEX
    12     *Use ``solve()`` instead*
     15    This methods solves the current MILP.
    1316
    14     INPUT:
    15    
    16     - ``log`` (integer) -- level of verbosity during the
    17       solving process. Set ``log=3`` for maximal verbosity and
    18       ``log=0`` for no verbosity at all.
     17    .. WARNING::
    1918
    20     - ``objective_only`` (boolean) -- Indicates whether the
    21       values corresponding to an optimal assignment of the
    22       variables should be computed. Setting ``objective_only``
    23       to ``True`` saves some time on the computation when
    24       this information is not needed.
    25 
    26     OUTPUT:
    27 
    28     This function returns the optimal value of the objective
    29     function given by CPLEX.
     19        This method should not be used to enumerate the solutions.
    3020
    3121    EXAMPLE:
    3222
     
    4535        4.0
    4636    """
    4737
     38    cdef CPX CPX_LP
     39    CPX_LP = CPX(self,log, objective_only)
    4840
     41    cdef double obj
     42    obj = CPX_LP.compute_next_solution(True)
     43
     44    if not objective_only:
     45        CPX_LP.save_solution(self)
     46
     47    return obj
     48
     49def get_CPX_instance(self, log=0):
     50    r"""
     51    Returns a ``CPX`` instance corresponding to a
     52    ``MixedIntegerLinearProgram`` object.
     53
     54    INPUT:
     55
     56    - ``log`` -- integer (default: ``0``) The verbosity level. Indicates
     57    whether progress should be printed during computation.
     58
     59    EXAMPLE::
     60
     61        sage: from sage.numerical.mip_cplex import get_CPX_instance     # optional - CPLEX
     62        sage: p = MixedIntegerLinearProgram()
     63        sage: v = p.new_variable()
     64        sage: p.add_constraint(v[1] + v[2] == 2)
     65        sage: p.set_objective(None)
     66        sage: get_CPX_instance(p)                                        # optional - CPLEX
     67        CPLEX Mixed Integer Linear Program
     68    """
     69
     70    cdef CPX CPX_LP
     71    CPX_LP = CPX(self,log,False)
     72
     73    return CPX_LP
     74
     75
     76cdef class CPX:
     77    r"""
     78    Represents a CPLEX MILP.
     79    """
     80
     81    def __repr__(self):
     82        r"""
     83        Returns a short string describing ``self``.
     84
     85        EXAMPLE::
     86
     87            sage: from sage.numerical.mip_cplex import get_CPX_instance    # optional - CPLEX
     88            sage: p = MixedIntegerLinearProgram()
     89            sage: v = p.new_variable()
     90            sage: p.add_constraint(v[1] + v[2] == 2)
     91            sage: p.set_objective(None)
     92            sage: get_CPX_instance(p)                                       # optional - CPLEX
     93            CPLEX Mixed Integer Linear Program
     94        """
     95
     96        return "CPLEX Mixed Integer Linear Program"
     97
     98    def compute_next_solution(self, only_one):
     99        r"""
     100        Computes the next possible solution of the current MILP.
     101
     102        This method is used to iterate over all the solutions of a
     103        MILP.
     104
     105        INPUT:
     106
     107        - ``only_one`` (boolean) -- do we want only one answer, or are
     108          we trying to iterate over all the possible solutions ?
     109
     110        EXAMPLE::
     111
     112            sage: from sage.numerical.mip_cplex import get_CPX_instance  # optional - CPLEX
     113            sage: p = MixedIntegerLinearProgram()
     114            sage: v = p.new_variable()
     115            sage: p.add_constraint(v[1] + v[2] == 1)
     116            sage: p.set_binary(v)
     117            sage: p.set_objective(2*v[1] + v[2])
     118            sage: CPX = get_CPX_instance(p)                               # optional - CPLEX
     119            sage: CPX.compute_next_solution(True)                         # optional - CPLEX
     120            2.0
     121            sage: CPX.save_solution(p)                                    # optional - CPLEX
     122            sage: p.get_values(v[1]), p.get_values(v[2])                  # optional - CPLEX
     123            (1, 0)
     124        """
     125        check(15)
     126
     127        # We want to compute at most 1 new solution at each call
     128        status = CPXsetintparam(self.env, CPX_PARAM_POPULATELIM, 1)
     129        check(status)
     130
     131        # We want *all* the possible solutions
     132        status = CPXsetintparam(self.env, CPX_PARAM_SOLNPOOLINTENSITY, 4)
     133        check(status)
     134
     135        # We only want optimal solutions
     136        status = CPXsetdblparam (self.env, CPX_PARAM_SOLNPOOLGAP, 0.0)
     137        check(status)
     138
     139        ################################################################
     140        # TODO : Remove solutions from the pool as they are returned !!
     141        ################################################################
     142           
     143        ## If the solution pool already contains a solution we
     144        ## delete it, so as not to keep them all through the many
     145        ## calls of next_solution
     146        #if CPXgetsolnpoolnumsolns (self.env, self.lp) > 0:
     147        #    #print "before, ", CPXgetsolnpoolnumsolns (self.env, self.lp)
     148        #    status = CPXdelsolnpoolsolns (self.env, self.lp, 0, 0)
     149        #    #print status
     150        #    #print "after, ", CPXgetsolnpoolnumsolns (self.env, self.lp)
     151               
     152
     153        # If this is the method's first call, we compute the
     154        # optimal solution
     155        if CPXgetsolnpoolnumsolns (self.env, self.lp) == 0:
     156            status = CPXmipopt(self.env, self.lp)
     157            check(status)
    49158   
    50     # Creates the solver interfaces
    51     cdef c_OsiCpxSolverInterface* si
    52     si = new_c_OsiCpxSolverInterface();
     159        # If we want more than one solution, we are then using the
     160        # solution pool !
     161        if not only_one:
    53162
    54     from sage.numerical.mip import MIPSolverException
    55     cdef Osi_interface OSI
     163            self.current_sol = self.current_sol + 1
     164               
     165            # If we already called CPXMIPOPT during the latest
     166            # iteration.
     167            if self.current_sol >= 0:
     168                status = CPXpopulate (self.env, self.lp)
     169                check(status)
    56170
    57     OSI = Osi_interface()
     171            # Are we trying to read more solutions than we have
     172            # computed ?
     173            if CPXgetsolnpoolnumsolns (self.env, self.lp) == self.current_sol:
     174                from sage.numerical.mip import MIPSolverException
     175                raise MIPSolverException("CPLEX: No (or no more) solution available")
    58176
    59     return_value = OSI.osi_solve(self, <c_OsiSolverInterface *> si, objective_only, True)
    60     del_OsiCpxSolverInterface(si)
     177        cdef double obj
     178        status = CPXgetobjval(self.env, self.lp, &obj)
     179        check(status)
    61180
    62     return return_value
     181        return round(obj, 8)
     182   
     183    def save_solution(self, LP):
     184        r"""
     185        Copies the solution from the CPLEX LP to the
     186        ``MixedIntegerLinearProgram`` object.
     187
     188        INPUT:
     189
     190        - ``LP`` -- The ``MixedIntegerLinearProgram`` which is to
     191          store the current solution contained in ``self``.
     192
     193
     194        EXAMPLE::
     195
     196            sage: from sage.numerical.mip_cplex import get_CPX_instance    # optional - CPLEX
     197            sage: p = MixedIntegerLinearProgram()
     198            sage: v = p.new_variable()
     199            sage: p.add_constraint(v[1] + v[2] == 1)
     200            sage: p.set_binary(v)
     201            sage: p.set_objective(2*v[1] + v[2])
     202            sage: CPX = get_CPX_instance(p)                                 # optional - CPLEX
     203            sage: CPX.compute_next_solution(True)                           # optional - CPLEX
     204            2.0
     205            sage: CPX.save_solution(p)                                      # optional - CPLEX
     206            sage: p.get_values(v[1]), p.get_values(v[2])                    # optional - CPLEX
     207            (1, 0)
     208        """
     209   
     210        from itertools import izip
     211
     212        cdef double * assignment = <double*> sage_malloc(len(LP._variables)*sizeof(double))
     213
     214        status = CPXgetsolnpoolx (self.env, self.lp, self.current_sol, assignment, 0, len(LP._variables)-1)
     215        check(status)
     216
     217        for ((x,id),type) in izip(LP._variables.iteritems(),LP._variables_type):
     218            LP._values[x] = assignment[id] if type == REAL else int(round(assignment[id]))
     219
     220        sage_free(assignment)
     221
     222    def __cinit__(self, LP,  int log, bool objective_only):
     223        r"""
     224        Constructor for the class.
     225
     226        EXAMPLE::
     227
     228            sage: from sage.numerical.mip_cplex import get_CPX_instance   # optional - CPLEX
     229            sage: p = MixedIntegerLinearProgram()
     230            sage: v = p.new_variable()
     231            sage: p.add_constraint(v[1] + v[2] == 1)
     232            sage: p.set_binary(v)
     233            sage: p.set_objective(2*v[1] + v[2])
     234            sage: CPX = get_CPX_instance(p)                                # optional - CPLEX
     235            sage: CPX.compute_next_solution(True)                          # optional - CPLEX
     236            2.0
     237            sage: CPX.save_solution(p)                                     # optional - CPLEX
     238            sage: p.get_values(v[1]), p.get_values(v[2])                   # optional - CPLEX
     239            (1, 0)
     240        """
     241        self.current_sol = -1
     242        self._mixed = False
     243        n_cols = len(LP._variables_type);
     244   
     245        cdef int i,j
     246   
     247        from itertools import izip
     248       
     249        # Defining the objective function
     250        cdef double *objective
     251        objective = <double *> sage_malloc( n_cols * sizeof(double))
     252        memset(objective, 0, n_cols*sizeof(double))
     253        for i, coeff in izip(LP._objective_i, LP._objective_values):
     254            objective[i] = coeff
     255   
     256        # Defining upper/lower bounds on constraints
     257        cdef double * constraints_bounds
     258        cdef char * constraints_sense
     259   
     260        constraints_bounds = <double *>  sage_malloc( len(LP._constraints_bounds_min) * sizeof(double) )
     261        constraints_sense = <char *>  sage_malloc( len(LP._constraints_bounds_min) * sizeof(char) )
     262   
     263        j = 0
     264        for m, M in izip(LP._constraints_bounds_min, LP._constraints_bounds_max):
     265            if m == None:
     266                constraints_bounds[j] = M
     267                constraints_sense[j] = 'L'
     268            elif M == None:
     269                constraints_bounds[j] = m
     270                constraints_sense[j] = 'G'
     271            elif m == M:
     272                constraints_bounds[j] = m
     273                constraints_sense[j] = 'E'
     274
     275            j = j+1
     276   
     277        # Defining the matrix of constraints
     278        cdef double * matrix_values
     279        cdef int * matrix_j
     280        cdef double v
     281        cdef int* matrix_beg
     282        matrix_values = <double *> sage_malloc( len(LP._constraints_matrix_values) * sizeof(double) )
     283        matrix_j = <int *> sage_malloc( len(LP._constraints_matrix_j) * sizeof(int) )
     284   
     285        for i,v in enumerate(LP._constraints_matrix_values):
     286            matrix_values[i] = v
     287   
     288        for i,j in enumerate(LP._constraints_matrix_j):
     289            matrix_j[i] = j
     290
     291        # Sequence of beginnings
     292        matrix_beg = <int*> sage_malloc( len(LP._constraints_bounds_min)*sizeof(int) )
     293        j = 0
     294        cdef int prev
     295        prev = 0
     296        matrix_beg[0] = 0
     297        for curr,i in enumerate(LP._constraints_matrix_i):
     298            if i != prev:
     299                j = j+1
     300                matrix_beg[j] = curr
     301                prev = i
     302   
     303        # Types of variables
     304        cdef char * variables_types
     305        variables_types = <char*> malloc( len(LP._variables) * sizeof(char) )
     306   
     307        self._mixed = False
     308        for i,j in enumerate(LP._variables_type):
     309            if j == INTEGER:
     310                self._mixed = True
     311                variables_types[i] = 'I'
     312            elif j == BINARY:
     313                self._mixed = True
     314                variables_types[i] = 'B'
     315            else:
     316                variables_types[i] = 'C'
     317   
     318        # Bounds on variables
     319   
     320        cdef double * variables_ub
     321        cdef double * variables_lb
     322        variables_ub = <double*> malloc( len(LP._variables) * sizeof(double) )
     323        variables_lb = <double*> malloc( len(LP._variables) * sizeof(double) )
     324   
     325        i = 0
     326        for m, M in izip(LP._variables_bounds_min, LP._variables_bounds_max):
     327            if m == None:
     328                variables_lb[i] = -CPX_INFBOUND
     329            else:
     330                variables_lb[i] = m
     331   
     332            if M == None:
     333                variables_lb[i] = CPX_INFBOUND
     334            else:
     335                variables_lb[i] = M
     336   
     337            i = i + 1
     338   
     339        # Defining the CPLEX LP object
     340        cdef int status
     341   
     342        self.env = CPXopenCPLEX (&status)
     343        check(status)
     344   
     345        if log == 0:
     346            status = CPXsetintparam (self.env, CPX_PARAM_SCRIND, 0)
     347            check(status)
     348        else:
     349            status = CPXsetintparam (self.env, CPX_PARAM_SCRIND, CPX_ON)
     350            check(status)
     351   
     352        cdef char * tmp = "There Once Was A French Fry"
     353        self.lp = CPXcreateprob (self.env, &status, tmp);
     354        check(status)
     355
     356        # Adding the variables and the objective
     357        status = CPXnewcols(self.env, self.lp, len(LP._variables), objective, NULL, NULL, variables_types, NULL)
     358        check(status)
     359   
     360   
     361        # Adding the constraints
     362        status = CPXaddrows (self.env, self.lp, 0, len(LP._constraints_bounds_min),
     363                             len(LP._constraints_matrix_i),
     364                             constraints_bounds, constraints_sense, matrix_beg, matrix_j, matrix_values,
     365                             NULL, NULL);
     366
     367        check(status)
     368
     369        # Maximization/Minimization ?
     370        if LP._maximization:
     371            CPXchgobjsen(self.env, self.lp, CPX_MAX)
     372        else:
     373            CPXchgobjsen(self.env, self.lp, CPX_MIN)
     374
     375    def __dealloc__(self):
     376        r"""
     377        Destructor for the class
     378        """
     379        CPXcloseCPLEX(self.env)
     380
     381cdef check(number):
     382    r"""
     383    Given a number, raises the corresponding exception or does nothing
     384    if ``number == 0``.
     385
     386    - ``number`` (integer) -- number corresponding to the error. If
     387      this number is unknown, the message contained in the raised
     388      exception will mention it.
     389    """
     390
     391    # Below 1000 are 0 (no error), and some quality reports (but the
     392    # ERR* codes are above 1000)
     393    if number > 1000:
     394        from sage.numerical.mip import MIPSolverException
     395        default = "Error reported by the solver (unknown error number : "+str(number)+")"
     396        raise MIPSolverException("CPLEX: "+errors.get(number,default))
     397
     398# Error codes
     399#
     400# Todo : when common error codes are returned, rewrite the message to
     401# be more meaningful
     402
     403errors = {
     404    1001 : "CPXERR_NO_MEMORY",
     405    1002 : "CPXERR_NO_ENVIRONMENT",
     406    1003 : "CPXERR_BAD_ARGUMENT",
     407    1004 : "CPXERR_NULL_POINTER",
     408    1006 : "CPXERR_CALLBACK",
     409    1009 : "CPXERR_NO_PROBLEM",
     410    1012 : "CPXERR_LIMITS_TOO_BIG",
     411    1013 : "CPXERR_BAD_PARAM_NUM",
     412    1014 : "CPXERR_PARAM_TOO_SMALL",
     413    1015 : "CPXERR_PARAM_TOO_BIG",
     414    1016 : "CPXERR_RESTRICTED_VERSION",
     415    1017 : "CPXERR_NOT_FOR_MIP",
     416    1018 : "CPXERR_NOT_FOR_QP",
     417    1019 : "CPXERR_CHILD_OF_CHILD",
     418    1020 : "CPXERR_TOO_MANY_THREADS",
     419    1021 : "CPXERR_CANT_CLOSE_CHILD",
     420    1022 : "CPXERR_BAD_PROB_TYPE",
     421    1023 : "CPXERR_NOT_ONE_PROBLEM",
     422    1024 : "CPXERR_NOT_MILPCLASS",
     423    1026 : "CPXERR_STR_PARAM_TOO_LONG",
     424    1027 : "CPXERR_DECOMPRESSION",
     425    1028 : "CPXERR_BAD_PARAM_NAME",
     426    1029 : "CPXERR_NOT_MIQPCLASS",
     427    1031 : "CPXERR_NOT_FOR_QCP",
     428    1051 : "CPXERR_MSG_NO_CHANNEL",
     429    1052 : "CPXERR_MSG_NO_FILEPTR",
     430    1053 : "CPXERR_MSG_NO_FUNCTION",
     431    1101 : "CPXERR_PRESLV_INForUNBD",
     432    1103 : "CPXERR_PRESLV_NO_PROB",
     433    1106 : "CPXERR_PRESLV_ABORT",
     434    1107 : "CPXERR_PRESLV_BASIS_MEM",
     435    1108 : "CPXERR_PRESLV_COPYSOS",
     436    1109 : "CPXERR_PRESLV_COPYORDER",
     437    1110 : "CPXERR_PRESLV_SOLN_MIP",
     438    1111 : "CPXERR_PRESLV_SOLN_QP",
     439    1112 : "CPXERR_PRESLV_START_LP",
     440    1114 : "CPXERR_PRESLV_FAIL_BASIS",
     441    1115 : "CPXERR_PRESLV_NO_BASIS",
     442    1117 : "CPXERR_PRESLV_INF",
     443    1118 : "CPXERR_PRESLV_UNBD",
     444    1119 : "CPXERR_PRESLV_DUAL",
     445    1120 : "CPXERR_PRESLV_UNCRUSHFORM",
     446    1121 : "CPXERR_PRESLV_CRUSHFORM",
     447    1122 : "CPXERR_PRESLV_BAD_PARAM",
     448    1123 : "CPXERR_PRESLV_TIME_LIM",
     449    1200 : "CPXERR_INDEX_RANGE",
     450    1201 : "CPXERR_COL_INDEX_RANGE",
     451    1203 : "CPXERR_ROW_INDEX_RANGE",
     452    1205 : "CPXERR_INDEX_RANGE_LOW",
     453    1206 : "CPXERR_INDEX_RANGE_HIGH",
     454    1207 : "CPXERR_NEGATIVE_SURPLUS",
     455    1208 : "CPXERR_ARRAY_TOO_LONG",
     456    1209 : "CPXERR_NAME_CREATION",
     457    1210 : "CPXERR_NAME_NOT_FOUND",
     458    1211 : "CPXERR_NO_RHS_IN_OBJ",
     459    1215 : "CPXERR_BAD_SENSE",
     460    1216 : "CPXERR_NO_RNGVAL",
     461    1217 : "CPXERR_NO_SOLN",
     462    1219 : "CPXERR_NO_NAMES",
     463    1221 : "CPXERR_NOT_FIXED",
     464    1222 : "CPXERR_DUP_ENTRY",
     465    1223 : "CPXERR_NO_BARRIER_SOLN",
     466    1224 : "CPXERR_NULL_NAME",
     467    1225 : "CPXERR_NAN",
     468    1226 : "CPXERR_ARRAY_NOT_ASCENDING",
     469    1227 : "CPXERR_COUNT_RANGE",
     470    1228 : "CPXERR_COUNT_OVERLAP",
     471    1229 : "CPXERR_BAD_LUB",
     472    1230 : "CPXERR_NODE_INDEX_RANGE",
     473    1231 : "CPXERR_ARC_INDEX_RANGE",
     474    1232 : "CPXERR_NO_DUAL_SOLN",
     475    1233 : "CPXERR_DBL_MAX",
     476    1234 : "CPXERR_THREAD_FAILED",
     477    1251 : "CPXERR_INDEX_NOT_BASIC",
     478    1252 : "CPXERR_NEED_OPT_SOLN",
     479    1253 : "CPXERR_BAD_STATUS",
     480    1254 : "CPXERR_NOT_UNBOUNDED",
     481    1255 : "CPXERR_SBASE_INCOMPAT",
     482    1256 : "CPXERR_SINGULAR",
     483    1257 : "CPXERR_PRIIND",
     484    1258 : "CPXERR_NO_LU_FACTOR",
     485    1260 : "CPXERR_NO_SENSIT",
     486    1261 : "CPXERR_NO_BASIC_SOLN",
     487    1262 : "CPXERR_NO_BASIS",
     488    1263 : "CPXERR_ABORT_STRONGBRANCH",
     489    1264 : "CPXERR_NO_NORMS",
     490    1265 : "CPXERR_NOT_DUAL_UNBOUNDED",
     491    1266 : "CPXERR_TILIM_STRONGBRANCH",
     492    1267 : "CPXERR_BAD_PIVOT",
     493    1268 : "CPXERR_TILIM_CONDITION_NO",
     494    1292 : "CPXERR_BAD_METHOD",
     495    1421 : "CPXERR_NO_FILENAME",
     496    1422 : "CPXERR_FAIL_OPEN_WRITE",
     497    1423 : "CPXERR_FAIL_OPEN_READ",
     498    1424 : "CPXERR_BAD_FILETYPE",
     499    1425 : "CPXERR_XMLPARSE",
     500    1431 : "CPXERR_TOO_MANY_ROWS",
     501    1432 : "CPXERR_TOO_MANY_COLS",
     502    1433 : "CPXERR_TOO_MANY_COEFFS",
     503    1434 : "CPXERR_BAD_NUMBER",
     504    1435 : "CPXERR_BAD_EXPO_RANGE",
     505    1436 : "CPXERR_NO_OBJ_SENSE",
     506    1437 : "CPXERR_QCP_SENSE_FILE",
     507    1438 : "CPXERR_BAD_LAZY_UCUT",
     508    1439 : "CPXERR_BAD_INDCONSTR",
     509    1441 : "CPXERR_NO_NAME_SECTION",
     510    1442 : "CPXERR_BAD_SOS_TYPE",
     511    1443 : "CPXERR_COL_ROW_REPEATS",
     512    1444 : "CPXERR_RIM_ROW_REPEATS",
     513    1445 : "CPXERR_ROW_REPEATS",
     514    1446 : "CPXERR_COL_REPEATS",
     515    1447 : "CPXERR_RIM_REPEATS",
     516    1448 : "CPXERR_ROW_UNKNOWN",
     517    1449 : "CPXERR_COL_UNKNOWN",
     518    1453 : "CPXERR_NO_ROW_SENSE",
     519    1454 : "CPXERR_EXTRA_FX_BOUND",
     520    1455 : "CPXERR_EXTRA_FR_BOUND",
     521    1456 : "CPXERR_EXTRA_BV_BOUND",
     522    1457 : "CPXERR_BAD_BOUND_TYPE",
     523    1458 : "CPXERR_UP_BOUND_REPEATS",
     524    1459 : "CPXERR_LO_BOUND_REPEATS",
     525    1460 : "CPXERR_NO_BOUND_TYPE",
     526    1461 : "CPXERR_NO_QMATRIX_SECTION",
     527    1462 : "CPXERR_BAD_SECTION_ENDATA",
     528    1463 : "CPXERR_INT_TOO_BIG_INPUT",
     529    1464 : "CPXERR_NAME_TOO_LONG",
     530    1465 : "CPXERR_LINE_TOO_LONG",
     531    1471 : "CPXERR_NO_ROWS_SECTION",
     532    1472 : "CPXERR_NO_COLUMNS_SECTION",
     533    1473 : "CPXERR_BAD_SECTION_BOUNDS",
     534    1474 : "CPXERR_RANGE_SECTION_ORDER",
     535    1475 : "CPXERR_BAD_SECTION_QMATRIX",
     536    1476 : "CPXERR_NO_OBJECTIVE",
     537    1477 : "CPXERR_ROW_REPEAT_PRINT",
     538    1478 : "CPXERR_COL_REPEAT_PRINT",
     539    1479 : "CPXERR_RIMNZ_REPEATS",
     540    1480 : "CPXERR_EXTRA_INTORG",
     541    1481 : "CPXERR_EXTRA_INTEND",
     542    1482 : "CPXERR_EXTRA_SOSORG",
     543    1483 : "CPXERR_EXTRA_SOSEND",
     544    1484 : "CPXERR_TOO_MANY_RIMS",
     545    1485 : "CPXERR_TOO_MANY_RIMNZ",
     546    1486 : "CPXERR_NO_ROW_NAME",
     547    1487 : "CPXERR_BAD_OBJ_SENSE",
     548    1550 : "CPXERR_BAS_FILE_SHORT",
     549    1551 : "CPXERR_BAD_INDICATOR",
     550    1552 : "CPXERR_NO_ENDATA",
     551    1553 : "CPXERR_FILE_ENTRIES",
     552    1554 : "CPXERR_SBASE_ILLEGAL",
     553    1555 : "CPXERR_BAS_FILE_SIZE",
     554    1556 : "CPXERR_NO_VECTOR_SOLN",
     555    1560 : "CPXERR_NOT_SAV_FILE",
     556    1561 : "CPXERR_SAV_FILE_DATA",
     557    1562 : "CPXERR_SAV_FILE_WRITE",
     558    1563 : "CPXERR_FILE_FORMAT",
     559    1602 : "CPXERR_ADJ_SIGNS",
     560    1603 : "CPXERR_RHS_IN_OBJ",
     561    1604 : "CPXERR_ADJ_SIGN_SENSE",
     562    1605 : "CPXERR_QUAD_IN_ROW",
     563    1606 : "CPXERR_ADJ_SIGN_QUAD",
     564    1607 : "CPXERR_NO_OPERATOR",
     565    1608 : "CPXERR_NO_OP_OR_SENSE",
     566    1609 : "CPXERR_NO_ID_FIRST",
     567    1610 : "CPXERR_NO_RHS_COEFF",
     568    1611 : "CPXERR_NO_NUMBER_FIRST",
     569    1612 : "CPXERR_NO_QUAD_EXP",
     570    1613 : "CPXERR_QUAD_EXP_NOT_2",
     571    1614 : "CPXERR_NO_QP_OPERATOR",
     572    1615 : "CPXERR_NO_NUMBER",
     573    1616 : "CPXERR_NO_ID",
     574    1617 : "CPXERR_BAD_ID",
     575    1618 : "CPXERR_BAD_EXPONENT",
     576    1619 : "CPXERR_Q_DIVISOR",
     577    1621 : "CPXERR_NO_BOUND_SENSE",
     578    1622 : "CPXERR_BAD_BOUND_SENSE",
     579    1623 : "CPXERR_NO_NUMBER_BOUND",
     580    1627 : "CPXERR_NO_SOS_SEPARATOR",
     581    1650 : "CPXERR_INVALID_NUMBER",
     582    1660 : "CPXERR_PRM_DATA",
     583    1661 : "CPXERR_PRM_HEADER",
     584    1719 : "CPXERR_NO_CONFLICT",
     585    1720 : "CPXERR_CONFLICT_UNSTABLE",
     586    1801 : "CPXERR_WORK_FILE_OPEN",
     587    1802 : "CPXERR_WORK_FILE_READ",
     588    1803 : "CPXERR_WORK_FILE_WRITE",
     589    1804 : "CPXERR_IN_INFOCALLBACK",
     590    1805 : "CPXERR_MIPSEARCH_WITH_CALLBACKS",
     591    1806 : "CPXERR_LP_NOT_IN_ENVIRONMENT",
     592    1807 : "CPXERR_PARAM_INCOMPATIBLE",
     593    32000 : "CPXERR_LICENSE_MIN",
     594    32201 : "CPXERR_ILOG_LICENSE",
     595    32301 : "CPXERR_NO_MIP_LIC",
     596    32302 : "CPXERR_NO_BARRIER_LIC",
     597    32305 : "CPXERR_NO_MIQP_LIC",
     598    32018 : "CPXERR_BADLDWID",
     599    32023 : "CPXERR_BADPRODUCT",
     600    32024 : "CPXERR_ALGNOTLICENSED",
     601    32999 : "CPXERR_LICENSE_MAX",
     602    1701 : "CPXERR_IIS_NO_INFO",
     603    1702 : "CPXERR_IIS_NO_SOLN",
     604    1703 : "CPXERR_IIS_FEAS",
     605    1704 : "CPXERR_IIS_NOT_INFEAS",
     606    1705 : "CPXERR_IIS_OPT_INFEAS",
     607    1706 : "CPXERR_IIS_DEFAULT",
     608    1707 : "CPXERR_IIS_NO_BASIC",
     609    1709 : "CPXERR_IIS_NO_LOAD",
     610    1710 : "CPXERR_IIS_SUB_OBJ_LIM",
     611    1711 : "CPXERR_IIS_SUB_IT_LIM",
     612    1712 : "CPXERR_IIS_SUB_TIME_LIM",
     613    1713 : "CPXERR_IIS_NUM_BEST",
     614    1714 : "CPXERR_IIS_SUB_ABORT",
     615    3003 : "CPXERR_NOT_MIP",
     616    3006 : "CPXERR_BAD_PRIORITY",
     617    3007 : "CPXERR_ORDER_BAD_DIRECTION",
     618    3009 : "CPXERR_ARRAY_BAD_SOS_TYPE",
     619    3010 : "CPXERR_UNIQUE_WEIGHTS",
     620    3012 : "CPXERR_BAD_DIRECTION",
     621    3015 : "CPXERR_NO_SOS",
     622    3016 : "CPXERR_NO_ORDER",
     623    3018 : "CPXERR_INT_TOO_BIG",
     624    3019 : "CPXERR_SUBPROB_SOLVE",
     625    3020 : "CPXERR_NO_MIPSTART",
     626    3021 : "CPXERR_BAD_CTYPE",
     627    3023 : "CPXERR_NO_INT_X",
     628    3024 : "CPXERR_NO_SOLNPOOL",
     629    3301 : "CPXERR_MISS_SOS_TYPE",
     630    3412 : "CPXERR_NO_TREE",
     631    3413 : "CPXERR_TREE_MEMORY_LIMIT",
     632    3414 : "CPXERR_FILTER_VARIABLE_TYPE",
     633    3504 : "CPXERR_NODE_ON_DISK",
     634    3601 : "CPXERR_PTHREAD_MUTEX_INIT",
     635    3603 : "CPXERR_PTHREAD_CREATE",
     636    1212 : "CPXERR_UNSUPPORTED_CONSTRAINT_TYPE",
     637    1213 : "CPXERR_ILL_DEFINED_PWL",
     638    1530 : "CPXERR_NET_DATA",
     639    1531 : "CPXERR_NOT_MIN_COST_FLOW",
     640    1532 : "CPXERR_BAD_ROW_ID",
     641    1537 : "CPXERR_BAD_CHAR",
     642    1538 : "CPXERR_NET_FILE_SHORT",
     643    5002 : "CPXERR_Q_NOT_POS_DEF",
     644    5004 : "CPXERR_NOT_QP",
     645    5011 : "CPXERR_Q_DUP_ENTRY",
     646    5012 : "CPXERR_Q_NOT_SYMMETRIC",
     647    5014 : "CPXERR_Q_NOT_INDEF",
     648    6002 : "CPXERR_QCP_SENSE"
     649    }
     650   
  • new file sage/numerical/mip_osi_cplex.pxd

    diff -r 12663152c470 -r 74cf4208d81e sage/numerical/mip_osi_cplex.pxd
    - +  
     1cdef extern from *:
     2    ctypedef double* const_double_ptr "const double*"
     3
     4cdef extern from "../../local/include/coin/CoinPackedVector.hpp":
     5     ctypedef struct c_CoinPackedVector "CoinPackedVector":
     6         void insert(float, float)
     7     c_CoinPackedVector *new_c_CoinPackedVector "new CoinPackedVector" ()
     8     void del_CoinPackedVector "delete" (c_CoinPackedVector *)
     9cdef extern from "../../local/include/coin/CoinPackedMatrix.hpp":
     10     ctypedef struct c_CoinPackedMatrix "CoinPackedMatrix":
     11         void setDimensions(int, int)
     12         void appendRow(c_CoinPackedVector)
     13     c_CoinPackedMatrix *new_c_CoinPackedMatrix "new CoinPackedMatrix" (bool, double, double)
     14     void del_CoinPackedMatrix "delete" (c_CoinPackedMatrix *)
     15
     16cdef extern from "../../local/include/coin/OsiCpxSolverInterface.hpp":
     17     ctypedef struct c_OsiCpxSolverInterface "OsiCpxSolverInterface":
     18         double getInfinity()
     19         void loadProblem(c_CoinPackedMatrix, const_double_ptr, const_double_ptr, const_double_ptr, const_double_ptr, const_double_ptr)
     20         void assignProblem(c_CoinPackedMatrix *, const_double_ptr, const_double_ptr, const_double_ptr, const_double_ptr, const_double_ptr)
     21         void writeMps(char *, char *, double)
     22         void initialSolve()
     23         void branchAndBound()
     24         void readMps(string)
     25         float getObjValue()
     26         double * getColSolution()
     27         void setObjSense (double )
     28         void setLogLevel(int)
     29         void setInteger(int)
     30         void setContinuous(int)
     31         int isAbandoned ()
     32         int isProvenOptimal ()
     33         int isProvenPrimalInfeasible ()
     34         int isProvenDualInfeasible ()
     35         int isPrimalObjectiveLimitReached ()
     36         int isDualObjectiveLimitReached ()
     37         int isIterationLimitReached ()
     38         void setMaximumSolutions(int)
     39         int getMaximumSolutions()
     40     c_OsiCpxSolverInterface *new_c_OsiCpxSolverInterface "new OsiCpxSolverInterface" ()
     41     void del_OsiCpxSolverInterface "delete" (c_OsiCpxSolverInterface *)
     42
     43
     44
     45from sage.numerical.osi_interface cimport Osi_interface
     46from sage.numerical.osi_interface cimport c_OsiSolverInterface
  • new file sage/numerical/mip_osi_cplex.pyx

    diff -r 12663152c470 -r 74cf4208d81e sage/numerical/mip_osi_cplex.pyx
    - +  
     1include '../../../../devel/sage/sage/ext/stdsage.pxi'
     2
     3cdef int BINARY = 1
     4cdef int REAL = -1
     5cdef int INTEGER = 0
     6
     7
     8
     9def solve_cplex(self,log=0,objective_only=False):
     10    r"""
     11    Solves the ``MixedIntegerLinearProgram`` using CPLEX
     12    *Use ``solve()`` instead*
     13
     14    INPUT:
     15   
     16    - ``log`` (integer) -- level of verbosity during the
     17      solving process. Set ``log=3`` for maximal verbosity and
     18      ``log=0`` for no verbosity at all.
     19
     20    - ``objective_only`` (boolean) -- Indicates whether the
     21      values corresponding to an optimal assignment of the
     22      variables should be computed. Setting ``objective_only``
     23      to ``True`` saves some time on the computation when
     24      this information is not needed.
     25
     26    OUTPUT:
     27
     28    This function returns the optimal value of the objective
     29    function given by CPLEX.
     30
     31    EXAMPLE:
     32
     33    Solving a simple Linear Program using CPLEX as a solver
     34    (Computation of a maximum stable set in Petersen's graph)::
     35
     36        sage: from sage.numerical.mip_osi_cplex import solve_cplex     # optional - CPLEX
     37        sage: g = graphs.PetersenGraph()
     38        sage: p = MixedIntegerLinearProgram(maximization=True)
     39        sage: b = p.new_variable()
     40        sage: p.set_objective(sum([b[v] for v in g]))
     41        sage: for (u,v) in g.edges(labels=None):
     42        ...       p.add_constraint(b[u] + b[v], max=1)
     43        sage: p.set_binary(b)
     44        sage: solve_cplex(p,objective_only=True)     # optional - CPLEX
     45        4.0
     46    """
     47
     48
     49   
     50    # Creates the solver interfaces
     51    cdef c_OsiCpxSolverInterface* si
     52    si = new_c_OsiCpxSolverInterface();
     53
     54    from sage.numerical.mip import MIPSolverException
     55    cdef Osi_interface OSI
     56
     57    OSI = Osi_interface()
     58
     59    return_value = OSI.osi_solve(self, <c_OsiSolverInterface *> si, objective_only, True)
     60    del_OsiCpxSolverInterface(si)
     61
     62    return return_value