Ticket #12823: trac_12823-cplex_gurobi.patch

File trac_12823-cplex_gurobi.patch, 28.2 KB (added by ncohen, 7 years ago)
  • sage/numerical/backends/coin_backend.pyx

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1334254481 -7200
    # Node ID 3b6ef12acfd12268b6a0fc0629a59731b04667bc
    # Parent  61a26efe5cac55b7d8921598845143d4325737c8
    Allow constants for objective function & deletion of rows in MixedIntegerLinearProgram -- CPLEX/Gurobi
    
    diff --git a/sage/numerical/backends/coin_backend.pyx b/sage/numerical/backends/coin_backend.pyx
    a b  
    4545        else:
    4646            self.set_sense(-1)
    4747
     48        self.obj_constant_term = 0
     49
    4850    def __dealloc__(self):
    4951        r"""
    5052        Destructor function
     
    310312        - ``coeff`` -- a list of real values, whose ith element is the
    311313          coefficient of the ith variable in the objective function.
    312314
     315        - ``d`` (double) -- the constant term in the linear function (set to `0`
     316          by default)
     317
    313318        EXAMPLE::
    314319
    315320            sage: from sage.numerical.backends.generic_backend import get_solver
     
    319324            sage: p.set_objective([1, 1, 2, 1, 3])                   # optional - Coin
    320325            sage: map(lambda x :p.objective_coefficient(x), range(5))  # optional - Coin
    321326            [1.0, 1.0, 2.0, 1.0, 3.0]
     327
     328        Constants in the objective function are respected::
     329
     330            sage: p = MixedIntegerLinearProgram(solver='Coin')  # optional - Coin
     331            sage: x,y = p[0], p[1]                              # optional - Coin
     332            sage: p.add_constraint(2*x + 3*y, max = 6)          # optional - Coin
     333            sage: p.add_constraint(3*x + 2*y, max = 6)          # optional - Coin
     334            sage: p.set_objective(x + y + 7)                    # optional - Coin
     335            sage: p.set_integer(x); p.set_integer(y)            # optional - Coin
     336            sage: p.solve()                                     # optional - Coin
     337            9.0
     338
    322339        """
    323340
    324341        cdef int i
     
    326343        for i,v in enumerate(coeff):
    327344            self.si.setObjCoeff(i, v)
    328345
    329         self.obj_value = d
     346        self.obj_constant_term = d
    330347
    331348    cpdef set_verbosity(self, int level):
    332349        r"""
     
    354371
    355372        - ``i`` -- index of the constraint to remove
    356373
    357         WARN::
    358 
    359             Coin numbers constraints starting at 0, not at 1. If your program has
    360             ``n`` constraints and you ask it to remove constraint ``n``, IT WILL CRASH!
    361 
    362374        EXAMPLE::
    363375
    364             sage: p = MixedIntegerLinearProgram(solver='Coin')
    365             sage: x,y = p[0], p[1]
    366             sage: p.add_constraint(2*x + 3*y, max = 6)
    367             sage: p.add_constraint(3*x + 2*y, max = 6)
    368             sage: p.set_objective(x + y + 7)
    369             sage: p.set_integer(x); p.set_integer(y)
    370             sage: p.solve()
     376            sage: p = MixedIntegerLinearProgram(solver='Coin') # optional - Coin
     377            sage: x,y = p[0], p[1]                             # optional - Coin
     378            sage: p.add_constraint(2*x + 3*y, max = 6)         # optional - Coin
     379            sage: p.add_constraint(3*x + 2*y, max = 6)         # optional - Coin
     380            sage: p.set_objective(x + y + 7)                   # optional - Coin
     381            sage: p.set_integer(x); p.set_integer(y)           # optional - Coin
     382            sage: p.solve()                                    # optional - Coin
    371383            9.0
    372             sage: p.get_values([x,y])
    373             [2.0, 0.0]
    374             sage: p.remove_constraint(0)
    375             sage: p.solve()
     384            sage: p.remove_constraint(0)                       # optional - Coin
     385            sage: p.solve()                                    # optional - Coin
    376386            10.0
    377             sage: p.get_values([x,y])
     387            sage: p.get_values([x,y])                          # optional - Coin
    378388            [0.0, 3.0]
     389
     390        TESTS:
     391
     392        Removing fancy constraints do not make Sage crash::
     393
     394            sage: MixedIntegerLinearProgram(solver='Coin').remove_constraint(-2)  # optional - Coin
     395            Traceback (most recent call last):
     396            ...
     397            ValueError: The constraint's index i must satisfy 0 <= i < number_of_constraints
    379398        """
    380399        cdef int rows[1]
    381400
     401        if i < 0 or i >= self.si.getNumRows():
     402            raise ValueError("The constraint's index i must satisfy 0 <= i < number_of_constraints")
     403
    382404        rows[0] = i
    383405        self.si.deleteRows(1,rows)
    384406
    385407    cpdef remove_constraints(self, constraints):
    386408        r"""
    387409        Remove several constraints.
    388  
     410
    389411        INPUT:
    390  
     412
    391413        - ``constraints`` -- an iterable containing the indices of the rows to remove.
    392414
    393         WARN::
    394 
    395             Coin numbers constraints starting at 0, not at 1. If your program has
    396             ``n`` constraints and you ask it to remove constraint ``n``, IT WILL CRASH!
    397 
    398415        EXAMPLE::
    399416
    400             sage: p = MixedIntegerLinearProgram(solver='Coin')
    401             sage: x,y = p[0], p[1]
    402             sage: p.add_constraint(2*x + 3*y, max = 6)
    403             sage: p.add_constraint(3*x + 2*y, max = 6)
    404             sage: p.set_objective(x + y + 7)
    405             sage: p.set_integer(x); p.set_integer(y)
    406             sage: p.solve()
     417            sage: p = MixedIntegerLinearProgram(solver='Coin')  # optional - Coin
     418            sage: x,y = p[0], p[1]                              # optional - Coin
     419            sage: p.add_constraint(2*x + 3*y, max = 6)          # optional - Coin
     420            sage: p.add_constraint(3*x + 2*y, max = 6)          # optional - Coin
     421            sage: p.set_objective(x + y + 7)                    # optional - Coin
     422            sage: p.set_integer(x); p.set_integer(y)            # optional - Coin
     423            sage: p.solve()                                     # optional - Coin
    407424            9.0
    408             sage: p.get_values([x,y])
    409             [2.0, 0.0]
    410             sage: p.remove_constraints([0])
    411             sage: p.solve()
     425            sage: p.get_values(x)                               # optional - Coin
     426            2.0...
     427            sage: p.get_values(y)                               # optional - Coin
     428            0.0...
     429            sage: p.remove_constraints([0])                     # optional - Coin
     430            sage: p.solve()                                     # optional - Coin
    412431            10.0
    413             sage: p.get_values([x,y])
     432            sage: p.get_values([x,y])                           # optional - Coin
    414433            [0.0, 3.0]
     434
     435        TESTS:
     436
     437        Removing fancy constraints do not make Sage crash::
     438
     439            sage: MixedIntegerLinearProgram(solver='Coin').remove_constraints([0, -2])  # optional - Coin
     440            Traceback (most recent call last):
     441            ...
     442            ValueError: The constraint's index i must satisfy 0 <= i < number_of_constraints
    415443        """
    416444        cdef int i
     445        cdef int c
    417446        cdef int m = len(constraints)
    418447        cdef int * rows = <int *>sage_malloc(m * sizeof(int *))
     448        cdef int nrows = self.si.getNumRows()
    419449
    420         for i in xrange(m): rows[i] = constraints[i]
     450        for i in range(len(constraints)):
     451
     452            c = constraints[i]
     453            if c < 0 or c >= nrows:
     454                sage_free(rows)
     455                raise ValueError("The constraint's index i must satisfy 0 <= i < number_of_constraints")
     456
     457            rows[i] = c
     458
    421459        self.si.deleteRows(m, rows)
    422460        sage_free(rows)
    423461
     
    761799            sage: p.get_variable_value(1)                          # optional - Coin
    762800            1.5
    763801        """
    764         return self.model.solver().getObjValue() + self.obj_value
     802        return self.model.solver().getObjValue() + self.obj_constant_term
    765803
    766804    cpdef double get_variable_value(self, int variable):
    767805        r"""
     
    11201158        p.si = self.si.clone(1)
    11211159        p.row_names = copy(self.row_names)
    11221160        p.col_names = copy(self.col_names)
    1123         p.obj_value = self.obj_value
     1161        p.obj_constant_term = self.obj_constant_term
    11241162        # Maybe I should copy this, not sure -- seems complicated, though
    11251163        p.prob_name = self.prob_name
    11261164
  • sage/numerical/backends/cplex_backend.pxd

    diff --git a/sage/numerical/backends/cplex_backend.pxd b/sage/numerical/backends/cplex_backend.pxd
    a b  
    3636                   double *rmatval, char **colname,
    3737                   char **rowname)
    3838
     39     # Remove constraints
     40     int CPXdelrows(c_cpxlp * env, c_cpxlp * lp, int begin, int end)
     41
    3942     # Solve MILP
    4043     int CPXmipopt (c_cpxlp * env, c_cpxlp * lp)
    4144
  • sage/numerical/backends/cplex_backend.pyx

    diff --git a/sage/numerical/backends/cplex_backend.pyx b/sage/numerical/backends/cplex_backend.pyx
    a b  
    3434        else:
    3535            self.set_sense(-1)
    3636
     37        self.obj_constant_term = 0
     38
    3739    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:
    3840        """
    3941        Add a variable.
     
    339341            check(status)
    340342
    341343
    342     cpdef set_objective(self, list coeff):
     344    cpdef set_objective(self, list coeff, double d = 0.0):
    343345        r"""
    344346        Sets the objective function.
    345347
     
    348350        - ``coeff`` -- a list of real values, whose ith element is the
    349351          coefficient of the ith variable in the objective function.
    350352
     353        - ``d`` (double) -- the constant term in the linear function (set to `0`
     354          by default)
     355
    351356        EXAMPLE::
    352357
    353358            sage: from sage.numerical.backends.generic_backend import get_solver
     
    357362            sage: p.set_objective([1, 1, 2, 1, 3])                   # optional - CPLEX
    358363            sage: map(lambda x :p.objective_coefficient(x), range(5))  # optional - CPLEX
    359364            [1.0, 1.0, 2.0, 1.0, 3.0]
     365
     366        Constants in the objective function are respected::
     367
     368            sage: p = MixedIntegerLinearProgram(solver='CPLEX') # optional - CPLEX
     369            sage: x,y = p[0], p[1]                              # optional - CPLEX
     370            sage: p.add_constraint(2*x + 3*y, max = 6)          # optional - CPLEX
     371            sage: p.add_constraint(3*x + 2*y, max = 6)          # optional - CPLEX
     372            sage: p.set_objective(x + y + 7)                    # optional - CPLEX
     373            sage: p.set_integer(x); p.set_integer(y)            # optional - CPLEX
     374            sage: p.solve()                                     # optional - CPLEX
     375            9.0
    360376        """
    361377
    362378        cdef int status
    363379        cdef int n = self.ncols()
    364380        cdef double * c_coeff = <double *> sage_malloc(n * sizeof(double))
    365381        cdef int * c_indices = <int *> sage_malloc(n * sizeof(int))
    366        
     382
    367383        for i,v in enumerate(coeff):
    368384            c_coeff[i] = v
    369385            c_indices[i] = i
     
    371387        status = CPXchgobj(self.env, self.lp, n, c_indices, c_coeff)
    372388        check(status)
    373389
     390        self.obj_constant_term = d
     391
    374392
    375393    cpdef set_verbosity(self, int level):
    376394        r"""
     
    396414            status = CPXsetintparam (self.env, CPX_PARAM_SCRIND, CPX_ON)
    397415            check(status)
    398416
     417    cpdef remove_constraint(self, int i):
     418        r"""
     419        Remove a constraint from self.
     420
     421        INPUT:
     422
     423        - ``i`` -- index of the constraint to remove
     424
     425        EXAMPLE::
     426
     427            sage: p = MixedIntegerLinearProgram(solver='CPLEX')# optional - CPLEX
     428            sage: x,y = p[0], p[1]                             # optional - CPLEX
     429            sage: p.add_constraint(2*x + 3*y, max = 6)         # optional - CPLEX
     430            sage: p.add_constraint(3*x + 2*y, max = 6)         # optional - CPLEX
     431            sage: p.set_objective(x + y + 7)                   # optional - CPLEX
     432            sage: p.set_integer(x); p.set_integer(y)           # optional - CPLEX
     433            sage: p.solve()                                    # optional - CPLEX
     434            9.0
     435            sage: p.remove_constraint(0)                       # optional - CPLEX
     436            sage: p.solve()                                    # optional - CPLEX
     437            10.0
     438            sage: p.get_values([x,y])                          # optional - CPLEX
     439            [0.0, 3.0]
     440        """
     441        cdef int status
     442        status = CPXdelrows(self.env, self.lp, i, i)
     443        check(status)
     444
    399445    cpdef add_linear_constraints(self, int number, lower_bound, upper_bound, names = None):
    400446        """
    401447        Add ``'number`` linear constraints.
     
    843889        status = CPXgetobjval (self.env, self.lp, &value)
    844890        check(status)
    845891
    846         return value
     892        return value + self.obj_constant_term
    847893
    848894
    849895    cpdef double get_variable_value(self, int variable):
  • sage/numerical/backends/generic_backend.pxd

    diff --git a/sage/numerical/backends/generic_backend.pxd b/sage/numerical/backends/generic_backend.pxd
    a b  
    3939    cpdef variable_lower_bound(self, int index, value = *)
    4040    cpdef solver_parameter(self, name, value=*)
    4141
    42     cdef double obj_value
     42    cdef double obj_constant_term
    4343
    4444cpdef GenericBackend get_solver(constraint_generation = ?, solver = ?)
  • sage/numerical/backends/generic_backend.pyx

    diff --git a/sage/numerical/backends/generic_backend.pyx b/sage/numerical/backends/generic_backend.pyx
    a b  
    206206        - ``coeff`` -- a list of real values, whose ith element is the
    207207          coefficient of the ith variable in the objective function.
    208208
     209        - ``d`` (double) -- the constant term in the linear function (set to `0`
     210          by default)
     211
    209212        EXAMPLE::
    210213
    211214            sage: from sage.numerical.backends.generic_backend import get_solver
     
    215218            sage: p.set_objective([1, 1, 2, 1, 3])                   # optional - Nonexistent_LP_solver
    216219            sage: map(lambda x :p.objective_coefficient(x), range(5))  # optional - Nonexistent_LP_solver
    217220            [1.0, 1.0, 2.0, 1.0, 3.0]
     221
     222        Constants in the objective function are respected::
     223
     224            sage: p = MixedIntegerLinearProgram(solver='Nonexistent_LP_solver') # optional - Nonexistent_LP_solver
     225            sage: x,y = p[0], p[1]                              # optional - Nonexistent_LP_solver
     226            sage: p.add_constraint(2*x + 3*y, max = 6)          # optional - Nonexistent_LP_solver
     227            sage: p.add_constraint(3*x + 2*y, max = 6)          # optional - Nonexistent_LP_solver
     228            sage: p.set_objective(x + y + 7)                    # optional - Nonexistent_LP_solver
     229            sage: p.set_integer(x); p.set_integer(y)            # optional - Nonexistent_LP_solver
     230            sage: p.solve()                                     # optional - Nonexistent_LP_solver
     231            9.0
     232
    218233        """
    219234        raise NotImplementedError()
    220235
  • sage/numerical/backends/glpk_backend.pyx

    diff --git a/sage/numerical/backends/glpk_backend.pyx b/sage/numerical/backends/glpk_backend.pyx
    a b  
    3636        glp_init_iocp(self.iocp)
    3737        self.iocp.presolve = GLP_ON
    3838        self.set_verbosity(0)
     39        self.obj_constant_term = 0
    3940
    4041        if maximization:
    4142            self.set_sense(+1)
     
    320321        - ``coeff`` - a list of real values, whose ith element is the
    321322          coefficient of the ith variable in the objective function.
    322323
     324        - ``d`` (double) -- the constant term in the linear function (set to `0`
     325          by default)
     326
    323327        EXAMPLE::
    324328
    325329            sage: from sage.numerical.backends.generic_backend import get_solver
     
    337341
    338342        glp_set_obj_coef(self.lp, 0, d)
    339343
    340         self.obj_value = d
     344        self.obj_constant_term = d
    341345
    342346    cpdef set_verbosity(self, int level):
    343347        """
     
    385389            sage: p.set_integer(x); p.set_integer(y)
    386390            sage: p.solve()
    387391            9.0
    388             sage: p.get_values([x,y])
    389             [1.0, 1.0]
    390392            sage: p.remove_constraint(1)
    391393            sage: p.solve()
    392394            10.0
    393             sage: p.get_values([x,y])
    394             [0.0, 3.0]
     395
     396        Removing fancy constraints do not make Sage crash::
     397
     398            sage: MixedIntegerLinearProgram(solver = "GLPK").remove_constraint(-2)
     399            Traceback (most recent call last):
     400            ...
     401            ValueError: The constraint's index i must satisfy 0 <= i < number_of_constraints
    395402        """
    396403        cdef int rows[2]
    397404
    398         rows[1] = i
     405        if i < 0 or i >= glp_get_num_rows(self.lp):
     406            raise ValueError("The constraint's index i must satisfy 0 <= i < number_of_constraints")
     407
     408        rows[1] = i+1
    399409        glp_del_rows(self.lp, 1, rows)
    400410
    401411    cpdef remove_constraints(self, constraints):
    402412        r"""
    403413        Remove several constraints.
    404  
     414
    405415        INPUT:
    406  
     416
    407417        - ``constraints`` -- an iterable containing the indices of the rows to remove.
    408418
    409         WARN::
    410 
    411             GLPK numbers constraints starting at 1, not at 0. If you ask GLPK to
    412             remove constraint 0, IT WILL CRASH!
    413 
    414         Note that if names have been assigned to constraints,
    415         the names of constraints that are not deleted will shift.
    416 
    417419        EXAMPLE::
    418420
    419421            sage: p = MixedIntegerLinearProgram(solver='GLPK')
     
    424426            sage: p.set_integer(x); p.set_integer(y)
    425427            sage: p.solve()
    426428            9.0
    427             sage: p.get_values([x,y])
    428             [1.0, 1.0]
    429429            sage: p.remove_constraints([1])
    430430            sage: p.solve()
    431431            10.0
    432432            sage: p.get_values([x,y])
    433             [0.0, 3.0]
     433            [3.0, 0.0]
     434
     435        TESTS:
     436
     437        Removing fancy constraints do not make Sage crash::
     438
     439            sage: MixedIntegerLinearProgram(solver= "GLPK").remove_constraints([0, -2])
     440            Traceback (most recent call last):
     441            ...
     442            ValueError: The constraint's index i must satisfy 0 <= i < number_of_constraints
    434443        """
    435444        cdef int i
     445        cdef int c
    436446        cdef int m = len(constraints)
    437447        cdef int * rows = <int *>sage_malloc((m + 1) * sizeof(int *))
     448        cdef int nrows = glp_get_num_rows(self.lp)
    438449
    439         for i in xrange(m): rows[i + 1] = constraints[i]
     450        for i in range(len(constraints)):
     451
     452            c = constraints[i]
     453            if c < 0 or c >= nrows:
     454                sage_free(rows)
     455                raise ValueError("The constraint's index i must satisfy 0 <= i < number_of_constraints")
     456
     457            rows[i+1] = c + 1
     458
    440459        glp_del_rows(self.lp, m, rows)
    441460        sage_free(rows)
    442461
     
    455474        - ``upper_bound`` - an upper bound, either a real value or ``None``
    456475
    457476        - ``name`` - an optional name for this row (default: ``None``)
    458  
     477
    459478        EXAMPLE::
    460479
    461480            sage: from sage.numerical.backends.generic_backend import get_solver
     
    486505        for i,(c,v) in enumerate(coefficients):
    487506            row_i[i+1] = c+1
    488507            row_values[i+1] = v
    489        
    490         glp_set_mat_row(self.lp, n, len(coefficients), row_i, row_values) 
     508
     509        glp_set_mat_row(self.lp, n, len(coefficients), row_i, row_values)
    491510
    492511        if upper_bound is not None and lower_bound is None:
    493512            glp_set_row_bnds(self.lp, n, GLP_UP, upper_bound, upper_bound)
    494513        elif lower_bound is not None and upper_bound is None:
    495             glp_set_row_bnds(self.lp, n, GLP_LO, lower_bound, lower_bound)           
     514            glp_set_row_bnds(self.lp, n, GLP_LO, lower_bound, lower_bound)
    496515        elif upper_bound is not None and lower_bound is not None:
    497516            if lower_bound == upper_bound:
    498517                glp_set_row_bnds(self.lp, n, GLP_FX, lower_bound, upper_bound)
  • sage/numerical/backends/gurobi_backend.pxd

    diff --git a/sage/numerical/backends/gurobi_backend.pxd b/sage/numerical/backends/gurobi_backend.pxd
    a b  
    3030
    3131
    3232     int GRBaddconstr(GRBmodel *model, int numnz, int *cind, double *cval, char sense, double rhs, char *constrnames)
     33
     34     int GRBdelconstrs (GRBmodel *model, int numdel, int * ind )
    3335     int GRBaddrangeconstr(GRBmodel *model, int numnz, int *cind, double *cval, double lower, double upper, char *constrnames)
    3436
    3537
  • sage/numerical/backends/gurobi_backend.pyx

    diff --git a/sage/numerical/backends/gurobi_backend.pyx b/sage/numerical/backends/gurobi_backend.pyx
    a b  
    6868        self.set_sense(1 if maximization else -1)
    6969
    7070        self.set_verbosity(0)
     71        self.obj_constant_term = 0
    7172
    7273
    7374
     
    420421
    421422            return value
    422423
    423     cpdef set_objective(self, list coeff):
     424    cpdef set_objective(self, list coeff, double d = 0.0):
    424425        """
    425426        Set the objective function.
    426427
     
    429430        - ``coeff`` - a list of real values, whose ith element is the
    430431          coefficient of the ith variable in the objective function.
    431432
     433        - ``d`` (double) -- the constant term in the linear function (set to `0`
     434          by default)
     435
    432436        EXAMPLE::
    433437
    434438            sage: from sage.numerical.backends.generic_backend import get_solver     # optional - Gurobi
     
    438442            sage: p.set_objective([1, 1, 2, 1, 3])                                   # optional - Gurobi
    439443            sage: map(lambda x :p.objective_coefficient(x), range(5))                # optional - Gurobi
    440444            [1.0, 1.0, 2.0, 1.0, 3.0]
     445
     446        Constants in the objective function are respected::
     447
     448            sage: p = MixedIntegerLinearProgram(solver='Gurobi')# optional - Gurobi
     449            sage: x,y = p[0], p[1]                              # optional - Gurobi
     450            sage: p.add_constraint(2*x + 3*y, max = 6)          # optional - Gurobi
     451            sage: p.add_constraint(3*x + 2*y, max = 6)          # optional - Gurobi
     452            sage: p.set_objective(x + y + 7)                    # optional - Gurobi
     453            sage: p.set_integer(x); p.set_integer(y)            # optional - Gurobi
     454            sage: p.solve()                                     # optional - Gurobi
     455            9.0
     456
    441457        """
    442458        cdef int i = 0
    443459        cdef double value
     
    450466
    451467        check(self.env,GRBupdatemodel(self.model[0]))
    452468
     469        self.obj_constant_term = d
     470
    453471    cpdef set_verbosity(self, int level):
    454472        """
    455473        Set the verbosity level
     
    473491
    474492        check(self.env, error)
    475493
     494    cpdef remove_constraint(self, int i):
     495        r"""
     496        Remove a constraint from self.
     497
     498        INPUT:
     499
     500        - ``i`` -- index of the constraint to remove
     501
     502        EXAMPLE::
     503
     504            sage: p = MixedIntegerLinearProgram(solver='Gurobi')# optional - Gurobi
     505            sage: x,y = p[0], p[1]                             # optional - Gurobi
     506            sage: p.add_constraint(2*x + 3*y, max = 6)         # optional - Gurobi
     507            sage: p.add_constraint(3*x + 2*y, max = 6)         # optional - Gurobi
     508            sage: p.set_objective(x + y + 7)                   # optional - Gurobi
     509            sage: p.set_integer(x); p.set_integer(y)           # optional - Gurobi
     510            sage: p.solve()                                    # optional - Gurobi
     511            9.0
     512            sage: p.remove_constraint(0)                       # optional - Gurobi
     513            sage: p.solve()                                    # optional - Gurobi
     514            10.0
     515            sage: p.get_values([x,y])                          # optional - Gurobi
     516            [0.0, 3.0]
     517        """
     518        cdef int ind[1]
     519        ind[0] = i
     520        cdef int error
     521        error = GRBdelconstrs (self.model[0], 1, ind )
     522        check(self.env, error)
     523
     524        error = GRBupdatemodel(self.model[0])
     525        check(self.env,error)
     526
    476527    cpdef add_linear_constraint(self, coefficients, lower_bound, upper_bound, name=None):
    477528        """
    478529        Add a linear constraint.
     
    745796
    746797        check(self.env,GRBgetdblattr(self.model[0], "ObjVal", <double* >p_value))
    747798
    748         return p_value[0]
     799        return p_value[0] + self.obj_constant_term
    749800
    750801    cpdef double get_variable_value(self, int variable):
    751802        """
  • sage/numerical/mip.pyx

    diff --git a/sage/numerical/mip.pyx b/sage/numerical/mip.pyx
    a b  
    420420    cpdef int number_of_constraints(self):
    421421      r"""
    422422      Returns the number of constraints assigned so far.
    423      
     423
    424424      EXAMPLE::
    425425            sage: p = MixedIntegerLinearProgram()
    426426            sage: p.add_constraint(p[0] - p[2], min = 1, max = 4)
     
    429429            2
    430430      """
    431431      return self._backend.nrows()
    432    
     432
    433433    def constraints(self, indices = None):
    434434        r"""
    435435        Returns a list of constraints, as 3-tuples.
     
    604604                   ),
    605605            first = False
    606606
    607         if   b.obj_value > 0.0: print "+", b.obj_value
    608         elif b.obj_value < 0.0: print "-", -b.obj_value
     607        if   b.obj_constant_term > 0.0: print "+", b.obj_constant_term
     608        elif b.obj_constant_term < 0.0: print "-", -b.obj_constant_term
    609609
    610610        print
    611611
     
    10561056
    10571057        elif isinstance(linear_function,LinearConstraint):
    10581058            functions = linear_function.constraints
    1059            
     1059
    10601060            if linear_function.equality:
    10611061                self.add_constraint(functions[0] - functions[1], min=0, max=0, name=name)
    10621062
     
    10811081            sage: x, y = p[0], p[1]
    10821082            sage: p.add_constraint(x + y, max = 10)
    10831083            sage: p.add_constraint(x - y, max = 0)
    1084             sage: p.add_constraint(x - y, max = 0)
    10851084            sage: p.add_constraint(x, max = 4)
    1086             sage: p.remove_constraint(2)
     1085            sage: p.show()
     1086            Maximization:
     1087            <BLANKLINE>
     1088            Constraints:
     1089            x_0 + x_1 <= 10.0
     1090            x_0 - x_1 <= 0.0
     1091            x_0 <= 4.0
     1092            ...
     1093            sage: p.remove_constraint(1)
    10871094            sage: p.show()
    10881095            Maximization:
    10891096            <BLANKLINE>
    10901097            Constraints:
    10911098              x_0 + x_1 <= 10.0
    1092               x_0 - x_1 <= 0.0
    10931099              x_0 <= 4.0
    10941100            ...
    10951101            sage: p.number_of_constraints()
    1096             3
    1097 
    1098         WARN::
    1099 
    1100             Whether the first constraint is numbered 0 or 1 depends on the backend.
    1101             For GLPK, the first constraint has index 1; for Coin, it has index 0.
    1102             This is why the example above adds the same constraint twice,
    1103             and tries to remove on of its copies. Whether it removes the first
    1104             or the second depends on the backend.
    1105             Since supplying an invalid number WILL CAUSE A CRASH, please be careful!
     1102            2
    11061103        """
    11071104        self._backend.remove_constraint(i)
    11081105
    11091106    def remove_constraints(self, constraints):
    11101107        """
    11111108        Remove several constraints.
    1112  
     1109
    11131110        INPUT:
    1114  
     1111
    11151112        - ``constraints`` -- an iterable containing the indices of the rows to remove.
    1116  
     1113
    11171114        Behavior may depend on the solver chosen.
    11181115
    11191116        EXAMPLE::
     
    11221119            sage: x, y = p[0], p[1]
    11231120            sage: p.add_constraint(x + y, max = 10)
    11241121            sage: p.add_constraint(x - y, max = 0)
    1125             sage: p.add_constraint(x - y, max = 0)
    11261122            sage: p.add_constraint(x, max = 4)
    1127             sage: p.remove_constraints([2])
    11281123            sage: p.show()
    11291124            Maximization:
    11301125            <BLANKLINE>
    11311126            Constraints:
    1132               x_0 + x_1 <= 10.0
    1133               x_0 - x_1 <= 0.0
     1127            x_0 + x_1 <= 10.0
     1128            x_0 - x_1 <= 0.0
     1129            x_0 <= 4.0
     1130            ...
     1131            sage: p.remove_constraints([0, 1])
     1132            sage: p.show()
     1133            Maximization:
     1134            <BLANKLINE>
     1135            Constraints:
    11341136              x_0 <= 4.0
    11351137            ...
    11361138            sage: p.number_of_constraints()
    1137             3
    1138 
    1139         WARN::
    1140 
    1141             Whether the first constraint is numbered 0 or 1 depends on the backend.
    1142             For GLPK, the first constraint has index 1; for Coin, it has index 0.
    1143             This is why the example above adds the same constraint twice,
    1144             and tries to remove on of its copies. Whether it removes the first
    1145             or the second depends on the backend.
    1146             Since supplying an invalid number WILL CAUSE A CRASH, please be careful!
    1147 
     1139            1
    11481140        """
    11491141        self._backend.remove_constraints(constraints)
    11501142