Ticket #12823: trac_12823_rolls_all_into_one.patch

File trac_12823_rolls_all_into_one.patch, 41.7 KB (added by ncohen, 7 years ago)
  • sage/numerical/backends/coin_backend.pxd

    # HG changeset patch
    # User John Perry <john.perry@usm.edu>
    # Date 1334463142 18000
    # Node ID 322bcdc6e94fb5b06c7e191590768eed2897520c
    # Parent  bbe42450c96129ac7023194143a935484e79a5a1
    Allow constants for objective function & deletion of rows in MixedIntegerLinearProgram
    
    diff --git a/sage/numerical/backends/coin_backend.pxd b/sage/numerical/backends/coin_backend.pxd
    a b  
    119119        double * getColLower()
    120120        double * getColUpper()
    121121
    122         # add row
     122        # add, delete rows
    123123        void addRow(CoinPackedVectorBase & vec, double rowlb, double rowub)
     124        void deleteRows(int num, int *)
    124125
    125126        # io
    126127        void writeMps(char *filename, char *extension, double objSense)
     
    180181    cdef OsiSolverInterface * si
    181182    cdef CbcModel * model
    182183    cdef int log_level
    183     cdef double obj_value
    184184
    185185    cdef list col_names, row_names
    186186    cdef str prob_name
  • sage/numerical/backends/coin_backend.pyx

    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.0
     49
    4850    def __dealloc__(self):
    4951        r"""
    5052        Destructor function
     
    301303        else:
    302304            return self.si.getObjCoefficients()[variable]
    303305
    304     cpdef set_objective(self, list coeff):
     306    cpdef set_objective(self, list coeff, double d = 0.0):
    305307        r"""
    306308        Sets the objective function.
    307309
     
    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` by default)
     316
    313317        EXAMPLE::
    314318
    315319            sage: from sage.numerical.backends.generic_backend import get_solver
     
    319323            sage: p.set_objective([1, 1, 2, 1, 3])                   # optional - Coin
    320324            sage: map(lambda x :p.objective_coefficient(x), range(5))  # optional - Coin
    321325            [1.0, 1.0, 2.0, 1.0, 3.0]
     326
     327        Constants in the objective function are respected::
     328
     329            sage: p = MixedIntegerLinearProgram(solver='Coin')  # optional - Coin
     330            sage: x,y = p[0], p[1]                              # optional - Coin
     331            sage: p.add_constraint(2*x + 3*y, max = 6)          # optional - Coin
     332            sage: p.add_constraint(3*x + 2*y, max = 6)          # optional - Coin
     333            sage: p.set_objective(x + y + 7)                    # optional - Coin
     334            sage: p.set_integer(x); p.set_integer(y)            # optional - Coin
     335            sage: p.solve()                                     # optional - Coin
     336            9.0
    322337        """
    323338
    324339        cdef int i
     
    326341        for i,v in enumerate(coeff):
    327342            self.si.setObjCoeff(i, v)
    328343
     344        self.obj_constant_term = d
     345
    329346    cpdef set_verbosity(self, int level):
    330347        r"""
    331348        Sets the log (verbosity) level
     
    344361
    345362        self.model.setLogLevel(level)
    346363
     364    cpdef remove_constraint(self, int i):
     365        r"""
     366        Remove a constraint from self.
     367
     368        INPUT:
     369
     370        - ``i`` -- index of the constraint to remove
     371
     372        EXAMPLE::
     373
     374            sage: p = MixedIntegerLinearProgram(solver='Coin') # optional - Coin
     375            sage: x,y = p[0], p[1]                             # optional - Coin
     376            sage: p.add_constraint(2*x + 3*y, max = 6)         # optional - Coin
     377            sage: p.add_constraint(3*x + 2*y, max = 6)         # optional - Coin
     378            sage: p.set_objective(x + y + 7)                   # optional - Coin
     379            sage: p.set_integer(x); p.set_integer(y)           # optional - Coin
     380            sage: p.solve()                                    # optional - Coin
     381            9.0
     382            sage: p.remove_constraint(0)                       # optional - Coin
     383            sage: p.solve()                                    # optional - Coin
     384            10.0
     385            sage: p.get_values([x,y])                          # optional - Coin
     386            [0.0, 3.0]
     387
     388        TESTS:
     389
     390        Removing fancy constraints does not make Sage crash::
     391
     392            sage: MixedIntegerLinearProgram(solver='Coin').remove_constraint(-2)  # optional - Coin
     393            Traceback (most recent call last):
     394            ...
     395            ValueError: The constraint's index i must satisfy 0 <= i < number_of_constraints
     396        """
     397        cdef int rows [1]
     398
     399        if i < 0 or i >= self.si.getNumRows():
     400            raise ValueError("The constraint's index i must satisfy 0 <= i < number_of_constraints")
     401        rows[0] = i
     402        self.si.deleteRows(1,rows)
     403
     404    cpdef remove_constraints(self, constraints):
     405        r"""
     406        Remove several constraints.
     407
     408        INPUT:
     409
     410        - ``constraints`` -- an interable containing the indices of the rows to remove
     411
     412        EXAMPLE::
     413
     414            sage: p = MixedIntegerLinearProgram(solver='Coin') # optional - Coin
     415            sage: x,y = p[0], p[1]                             # optional - Coin
     416            sage: p.add_constraint(2*x + 3*y, max = 6)         # optional - Coin
     417            sage: p.add_constraint(3*x + 2*y, max = 6)         # optional - Coin
     418            sage: p.set_objective(x + y + 7)                   # optional - Coin
     419            sage: p.set_integer(x); p.set_integer(y)           # optional - Coin
     420            sage: p.solve()                                    # optional - Coin
     421            9.0
     422            sage: p.get_values(x)                              # optional - Coin
     423            2.0...
     424            sage: p.get_values(y)                              # optional - Coin
     425            0.0...
     426            sage: p.remove_constraints([0])                    # optional - Coin
     427            sage: p.solve()                                    # optional - Coin
     428            10.0
     429            sage: p.get_values([x,y])                          # optional - Coin
     430            [0.0, 3.0]
     431
     432        TESTS:
     433
     434        Removing fancy constraints do not make Sage crash::
     435
     436            sage: MixedIntegerLinearProgram(solver='Coin').remove_constraints([0, -2])  # optional - Coin
     437            Traceback (most recent call last):
     438            ...
     439            ValueError: The constraint's index i must satisfy 0 <= i < number_of_constraints
     440        """
     441        cdef int i, c
     442        cdef int m = len(constraints)
     443        cdef int * rows = <int *>sage_malloc(m * sizeof(int *))
     444        cdef int nrows = self.si.getNumRows()
     445
     446        for i in xrange(m):
     447
     448            c = constraints[i]
     449            if c < 0 or c >= nrows:
     450                sage_free(rows)
     451                raise ValueError("The constraint's index i must satisfy 0 <= i < number_of_constraints")
     452
     453            rows[i] = c
     454
     455        self.si.deleteRows(m,rows)
     456        sage_free(rows)
    347457
    348458    cpdef add_linear_constraints(self, int number, lower_bound, upper_bound, names = None):
    349459        """
     
    685795            sage: p.get_variable_value(1)                          # optional - Coin
    686796            1.5
    687797        """
    688         return self.model.solver().getObjValue()
     798        return self.model.solver().getObjValue() + self.obj_constant_term
    689799
    690800    cpdef double get_variable_value(self, int variable):
    691801        r"""
     
    10441154        p.si = self.si.clone(1)
    10451155        p.row_names = copy(self.row_names)
    10461156        p.col_names = copy(self.col_names)
     1157        p.obj_constant_term = self.obj_constant_term
    10471158        # Maybe I should copy this, not sure -- seems complicated, though
    10481159        p.prob_name = self.prob_name
    10491160
  • 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.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` by default)
     354
    351355        EXAMPLE::
    352356
    353357            sage: from sage.numerical.backends.generic_backend import get_solver
     
    357361            sage: p.set_objective([1, 1, 2, 1, 3])                   # optional - CPLEX
    358362            sage: map(lambda x :p.objective_coefficient(x), range(5))  # optional - CPLEX
    359363            [1.0, 1.0, 2.0, 1.0, 3.0]
     364
     365        Constants in the objective function are respected::
     366
     367            sage: p = MixedIntegerLinearProgram(solver='CPLEX') # optional - CPLEX
     368            sage: x,y = p[0], p[1]                              # optional - CPLEX
     369            sage: p.add_constraint(2*x + 3*y, max = 6)          # optional - CPLEX
     370            sage: p.add_constraint(3*x + 2*y, max = 6)          # optional - CPLEX
     371            sage: p.set_objective(x + y + 7)                    # optional - CPLEX
     372            sage: p.set_integer(x); p.set_integer(y)            # optional - CPLEX
     373            sage: p.solve()                                     # optional - CPLEX
     374            9.0
    360375        """
    361376
    362377        cdef int status
     
    374389        sage_free(c_coeff)
    375390        sage_free(c_indices)
    376391
     392        self.obj_constant_term = d
     393
    377394
    378395    cpdef set_verbosity(self, int level):
    379396        r"""
     
    399416            status = CPXsetintparam (self.env, CPX_PARAM_SCRIND, CPX_ON)
    400417            check(status)
    401418
     419    cpdef remove_constraint(self, int i):
     420        r"""
     421        Remove a constraint from self.
     422
     423        INPUT:
     424
     425        - ``i`` -- index of the constraint to remove
     426
     427        EXAMPLE::
     428
     429            sage: p = MixedIntegerLinearProgram(solver='CPLEX')# optional - CPLEX
     430            sage: x,y = p[0], p[1]                             # optional - CPLEX
     431            sage: p.add_constraint(2*x + 3*y, max = 6)         # optional - CPLEX
     432            sage: p.add_constraint(3*x + 2*y, max = 6)         # optional - CPLEX
     433            sage: p.set_objective(x + y + 7)                   # optional - CPLEX
     434            sage: p.set_integer(x); p.set_integer(y)           # optional - CPLEX
     435            sage: p.solve()                                    # optional - CPLEX
     436            9.0
     437            sage: p.remove_constraint(0)                       # optional - CPLEX
     438            sage: p.solve()                                    # optional - CPLEX
     439            10.0
     440            sage: p.get_values([x,y])                          # optional - CPLEX
     441            [0.0, 3.0]
     442        """
     443        cdef int status
     444        status = CPXdelrows(self.env, self.lp, i, i)
     445        check(status)
     446
    402447    cpdef add_linear_constraints(self, int number, lower_bound, upper_bound, names = None):
    403448        """
    404449        Add ``'number`` linear constraints.
     
    856901        status = CPXgetobjval (self.env, self.lp, &value)
    857902        check(status)
    858903
    859         return value
     904        return value + self.obj_constant_term
    860905
    861906
    862907    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  
    1111    cpdef set_variable_type(self, int variable, int vtype)
    1212    cpdef set_sense(self, int sense)
    1313    cpdef objective_coefficient(self, int variable, coeff=*)
    14     cpdef set_objective(self, list coeff)
     14    cpdef set_objective(self, list coeff, double d=*)
    1515    cpdef set_verbosity(self, int level)
    1616    cpdef add_linear_constraint(self, constraints, lower_bound, upper_bound, name=*)
     17    cpdef remove_constraint(self, int)
     18    cpdef remove_constraints(self, constraints)
    1719    cpdef add_col(self, list indices, list coeffs)
    1820    cpdef add_linear_constraints(self, int number, lower_bound, upper_bound, names=*)
    1921    cpdef int solve(self) except -1
     
    3739    cpdef variable_lower_bound(self, int index, value = *)
    3840    cpdef solver_parameter(self, name, value=*)
    3941
     42    cdef double obj_constant_term
     43
    4044cpdef 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  
    197197        """
    198198        raise NotImplementedError()
    199199
    200     cpdef  set_objective(self, list coeff):
     200    cpdef  set_objective(self, list coeff, double d = 0.0):
    201201        """
    202202        Set the objective function.
    203203
     
    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` by default)
     210
    209211        EXAMPLE::
    210212
    211213            sage: from sage.numerical.backends.generic_backend import get_solver
     
    215217            sage: p.set_objective([1, 1, 2, 1, 3])                   # optional - Nonexistent_LP_solver
    216218            sage: map(lambda x :p.objective_coefficient(x), range(5))  # optional - Nonexistent_LP_solver
    217219            [1.0, 1.0, 2.0, 1.0, 3.0]
     220
     221        Constants in the objective function are respected::
     222
     223            sage: p = MixedIntegerLinearProgram(solver='Nonexistent_LP_solver') # optional - Nonexistent_LP_solver
     224            sage: x,y = p[0], p[1]                              # optional - Nonexistent_LP_solver
     225            sage: p.add_constraint(2*x + 3*y, max = 6)          # optional - Nonexistent_LP_solver
     226            sage: p.add_constraint(3*x + 2*y, max = 6)          # optional - Nonexistent_LP_solver
     227            sage: p.set_objective(x + y + 7)                    # optional - Nonexistent_LP_solver
     228            sage: p.set_integer(x); p.set_integer(y)            # optional - Nonexistent_LP_solver
     229            sage: p.solve()                                     # optional - Nonexistent_LP_solver
     230            9.0
    218231        """
    219232        raise NotImplementedError()
    220233
     
    234247        """
    235248        raise NotImplementedError()
    236249
     250    cpdef remove_constraint(self, int i):
     251        r"""
     252        Remove a constraint.
     253
     254        INPUT::
     255
     256        - ``i`` -- index of the constraint to remove.
     257        """
     258        raise NotImplementedError()
     259
     260    cpdef remove_constraints(self, constraints):
     261        r"""
     262        Remove several constraints.
     263
     264        INPUT:
     265
     266        - ``constraints`` -- an iterable containing the indices of the rows to remove.
     267        """
     268        if type(constraints) == int: self.remove_constraint(constraints)
     269
     270        cdef int last = self.nrows() + 1
     271
     272        for c in sorted(constraints, reverse=True):
     273            if c != last:
     274                self.remove_constraint(c)
     275                last = c
     276
    237277    cpdef add_linear_constraint(self, coefficients, lower_bound, upper_bound, name=None):
    238278        """
    239279        Add a linear constraint.
  • sage/numerical/backends/glpk_backend.pxd

    diff --git a/sage/numerical/backends/glpk_backend.pxd b/sage/numerical/backends/glpk_backend.pxd
    a b  
    5252     void glp_set_obj_dir(c_glp_prob *, int)
    5353     void glp_add_rows(c_glp_prob *, int)
    5454     void glp_add_cols(c_glp_prob *, int)
     55     void glp_del_rows(c_glp_prob *, int, int *)
    5556     void glp_set_row_name(c_glp_prob *, int, char *)
    5657     void glp_set_col_name(c_glp_prob *, int, char *)
    5758     void glp_set_row_bnds(c_glp_prob *, int, int, double, double)
  • 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.0
    3940
    4041        if maximization:
    4142            self.set_sense(+1)
     
    311312        else:
    312313            glp_set_prob_name(self.lp, name)
    313314
    314     cpdef set_objective(self, list coeff):
     315    cpdef set_objective(self, list coeff, double d = 0.0):
    315316        """
    316317        Set the objective function.
    317318
     
    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` by default)
     325
    323326        EXAMPLE::
    324327
    325328            sage: from sage.numerical.backends.generic_backend import get_solver
     
    335338        for i,v in enumerate(coeff):
    336339            glp_set_obj_coef(self.lp, i+1, v)
    337340
     341        glp_set_obj_coef(self.lp, 0, d)
     342
     343        self.obj_constant_term = d
     344
    338345    cpdef set_verbosity(self, int level):
    339346        """
    340347        Set the verbosity level
     
    363370            self.iocp.msg_lev = GLP_MSG_ALL
    364371            self.smcp.msg_lev = GLP_MSG_ALL
    365372
     373    cpdef remove_constraint(self, int i):
     374        r"""
     375        Remove a constraint from self.
     376
     377        INPUT:
     378
     379        - ``i`` -- index of the constraint to remove
     380
     381        EXAMPLE::
     382
     383            sage: p = MixedIntegerLinearProgram(solver='GLPK')
     384            sage: x,y = p[0], p[1]
     385            sage: p.add_constraint(2*x + 3*y, max = 6)
     386            sage: p.add_constraint(3*x + 2*y, max = 6)
     387            sage: p.set_objective(x + y + 7)
     388            sage: p.set_integer(x); p.set_integer(y)
     389            sage: p.solve()
     390            9.0
     391            sage: p.remove_constraint(0)
     392            sage: p.solve()
     393            10.0
     394
     395        Removing fancy constraints does not make Sage crash::
     396
     397            sage: MixedIntegerLinearProgram(solver = "GLPK").remove_constraint(-2)
     398            Traceback (most recent call last):
     399            ...
     400            ValueError: The constraint's index i must satisfy 0 <= i < number_of_constraints
     401        """
     402        cdef int rows[2]
     403
     404        if i < 0 or i >= glp_get_num_rows(self.lp):
     405            raise ValueError("The constraint's index i must satisfy 0 <= i < number_of_constraints")
     406
     407        rows[1] = i + 1
     408        glp_del_rows(self.lp, 1, rows)
     409
     410    cpdef remove_constraints(self, constraints):
     411        r"""
     412        Remove several constraints.
     413
     414        INPUT:
     415
     416        - ``constraints`` -- an iterable containing the indices of the rows to remove.
     417
     418        EXAMPLE::
     419
     420            sage: p = MixedIntegerLinearProgram(solver='GLPK')
     421            sage: x,y = p[0], p[1]
     422            sage: p.add_constraint(2*x + 3*y, max = 6)
     423            sage: p.add_constraint(3*x + 2*y, max = 6)
     424            sage: p.set_objective(x + y + 7)
     425            sage: p.set_integer(x); p.set_integer(y)
     426            sage: p.solve()
     427            9.0
     428            sage: p.remove_constraints([1])
     429            sage: p.solve()
     430            10.0
     431            sage: p.get_values([x,y])
     432            [3.0, 0.0]
     433
     434        TESTS:
     435
     436        Removing fancy constraints does not make Sage crash::
     437
     438            sage: MixedIntegerLinearProgram(solver= "GLPK").remove_constraints([0, -2])
     439            Traceback (most recent call last):
     440            ...
     441            ValueError: The constraint's index i must satisfy 0 <= i < number_of_constraints
     442        """
     443        cdef int i, c
     444        cdef int m = len(constraints)
     445        cdef int * rows = <int *>sage_malloc((m + 1) * sizeof(int *))
     446        cdef int nrows = glp_get_num_rows(self.lp)
     447
     448        for i in xrange(m):
     449
     450            c = constraints[i]
     451            if c < 0 or c >= nrows:
     452                sage_free(rows)
     453                raise ValueError("The constraint's index i must satisfy 0 <= i < number_of_constraints")
     454
     455            rows[i+1] = c + 1
     456
     457        glp_del_rows(self.lp, m, rows)
     458        sage_free(rows)
     459
    366460    cpdef add_linear_constraint(self, coefficients, lower_bound, upper_bound, name=None):
    367461        """
    368462        Add a linear constraint.
     
    410504            row_i[i+1] = c+1
    411505            row_values[i+1] = v
    412506       
    413         glp_set_mat_row(self.lp, n, len(coefficients), row_i, row_values) 
     507        glp_set_mat_row(self.lp, n, len(coefficients), row_i, row_values)
    414508
    415509        if upper_bound is not None and lower_bound is None:
    416510            glp_set_row_bnds(self.lp, n, GLP_UP, upper_bound, upper_bound)
    417511        elif lower_bound is not None and upper_bound is None:
    418             glp_set_row_bnds(self.lp, n, GLP_LO, lower_bound, lower_bound)           
     512            glp_set_row_bnds(self.lp, n, GLP_LO, lower_bound, lower_bound)
    419513        elif upper_bound is not None and lower_bound is not None:
    420514            if lower_bound == upper_bound:
    421515                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.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` by default)
     434
    432435        EXAMPLE::
    433436
    434437            sage: from sage.numerical.backends.generic_backend import get_solver     # optional - Gurobi
     
    438441            sage: p.set_objective([1, 1, 2, 1, 3])                                   # optional - Gurobi
    439442            sage: map(lambda x :p.objective_coefficient(x), range(5))                # optional - Gurobi
    440443            [1.0, 1.0, 2.0, 1.0, 3.0]
     444
     445        Constants in the objective function are respected::
     446
     447            sage: p = MixedIntegerLinearProgram(solver='Gurobi')# optional - Gurobi
     448            sage: x,y = p[0], p[1]                              # optional - Gurobi
     449            sage: p.add_constraint(2*x + 3*y, max = 6)          # optional - Gurobi
     450            sage: p.add_constraint(3*x + 2*y, max = 6)          # optional - Gurobi
     451            sage: p.set_objective(x + y + 7)                    # optional - Gurobi
     452            sage: p.set_integer(x); p.set_integer(y)            # optional - Gurobi
     453            sage: p.solve()                                     # optional - Gurobi
     454            9.0
    441455        """
    442456        cdef int i = 0
    443457        cdef double value
     
    450464
    451465        check(self.env,GRBupdatemodel(self.model[0]))
    452466
     467        self.obj_constant_term = d
     468
    453469    cpdef set_verbosity(self, int level):
    454470        """
    455471        Set the verbosity level
     
    473489
    474490        check(self.env, error)
    475491
     492    cpdef remove_constraint(self, int i):
     493        r"""
     494        Remove a constraint from self.
     495
     496        INPUT:
     497
     498        - ``i`` -- index of the constraint to remove
     499
     500        EXAMPLE::
     501
     502            sage: p = MixedIntegerLinearProgram(solver='Gurobi')# optional - Gurobi
     503            sage: x,y = p[0], p[1]                             # optional - Gurobi
     504            sage: p.add_constraint(2*x + 3*y, max = 6)         # optional - Gurobi
     505            sage: p.add_constraint(3*x + 2*y, max = 6)         # optional - Gurobi
     506            sage: p.set_objective(x + y + 7)                   # optional - Gurobi
     507            sage: p.set_integer(x); p.set_integer(y)           # optional - Gurobi
     508            sage: p.solve()                                    # optional - Gurobi
     509            9.0
     510            sage: p.remove_constraint(0)                       # optional - Gurobi
     511            sage: p.solve()                                    # optional - Gurobi
     512            10.0
     513            sage: p.get_values([x,y])                          # optional - Gurobi
     514            [0.0, 3.0]
     515        """
     516        cdef int ind[1]
     517        ind[0] = i
     518        cdef int error
     519        error = GRBdelconstrs (self.model[0], 1, ind )
     520        check(self.env, error)
     521
     522        error = GRBupdatemodel(self.model[0])
     523        check(self.env,error)
     524
    476525    cpdef add_linear_constraint(self, coefficients, lower_bound, upper_bound, name=None):
    477526        """
    478527        Add a linear constraint.
     
    745794
    746795        check(self.env,GRBgetdblattr(self.model[0], "ObjVal", <double* >p_value))
    747796
    748         return p_value[0]
     797        return p_value[0] + self.obj_constant_term
    749798
    750799    cpdef double get_variable_value(self, int variable):
    751800        """
  • sage/numerical/mip.pyx

    diff --git a/sage/numerical/mip.pyx b/sage/numerical/mip.pyx
    a b  
    6565    Minimization:
    6666       x_3
    6767    Constraints:
    68       0.0 <= x_0 +x_1 +x_2 -14.0 x_3 <= 0.0
    69       0.0 <= x_1 +2.0 x_2 -8.0 x_3 <= 0.0
    70       0.0 <= 2.0 x_2 -3.0 x_3 <= 0.0
    71       -x_0 +x_1 +x_2 <= 0.0
    72       -x_3 <= -1.0
     68      0.0 <= x_0 + x_1 + x_2 - 14.0 x_3 <= 0.0
     69      0.0 <= x_1 + 2.0 x_2 - 8.0 x_3 <= 0.0
     70      0.0 <= 2.0 x_2 - 3.0 x_3 <= 0.0
     71      - x_0 + x_1 + x_2 <= 0.0
     72      - x_3 <= -1.0
    7373    Variables:
    7474      x_0 is an integer variable (min=0.0, max=+oo)
    7575      x_1 is an integer variable (min=-oo, max=+oo)
     
    334334
    335335        INPUT:
    336336
    337         - ``name`` -- A string representing the name of the 
     337        - ``name`` -- A string representing the name of the
    338338          ``MixedIntegerLinearProgram``.
    339          
     339
    340340        EXAMPLE::
    341341
    342342            sage: p=MixedIntegerLinearProgram()
     
    367367        reals. They can be defined as binary through the parameter
    368368        ``binary=True`` (or integer with ``integer=True``). Lower and
    369369        upper bounds can be defined or re-defined (for instance when you want
    370         some variables to be negative) using ``MixedIntegerLinearProgram`` methods 
     370        some variables to be negative) using ``MixedIntegerLinearProgram`` methods
    371371        ``set_min`` and ``set_max``.
    372372
    373373        INPUT:
     
    380380          to ``True`` to ensure that the variable gets the corresponding
    381381          type. The default type is ``real``.
    382382
    383         - ``name`` (string) -- Associates a name to the variable. This is 
     383        - ``name`` (string) -- Associates a name to the variable. This is
    384384          only useful when exporting the linear program to a file using
    385           ``write_mps`` or ``write_lp``, and has no other effect.         
     385          ``write_mps`` or ``write_lp``, and has no other effect.
    386386
    387387        EXAMPLE::
    388388
     
    422422    cpdef int number_of_constraints(self):
    423423      r"""
    424424      Returns the number of constraints assigned so far.
    425      
     425
    426426      EXAMPLE::
    427427            sage: p = MixedIntegerLinearProgram()
    428428            sage: p.add_constraint(p[0] - p[2], min = 1, max = 4)
     
    431431            2
    432432      """
    433433      return self._backend.nrows()
    434    
     434
    435435    def constraints(self, indices = None):
    436436        r"""
    437437        Returns a list of constraints, as 3-tuples.
     
    550550            sage: p.add_constraint(-3*x[1] + 2*x[2], max=2, name="Constraint_1")
    551551            sage: p.show()
    552552            Maximization:
    553               Hey[1] +Hey[2]
     553              Hey[1] + Hey[2]
    554554            Constraints:
    555               Constraint_1: -3.0 Hey[1] +2.0 Hey[2] <= 2.0
     555              Constraint_1: -3.0 Hey[1] + 2.0 Hey[2] <= 2.0
    556556            Variables:
    557557              Hey[1] is a continuous variable (min=0.0, max=+oo)
    558558              Hey[2] is a continuous variable (min=0.0, max=+oo)
     
    565565            sage: p.add_constraint(-3*x[1] + 2*x[2], max=2)
    566566            sage: p.show()
    567567            Maximization:
    568               x_0 +x_1
     568              x_0 + x_1
    569569            Constraints:
    570               -3.0 x_0 +2.0 x_1 <= 2.0
     570              -3.0 x_0 + 2.0 x_1 <= 2.0
    571571            Variables:
    572572              x_0 is a continuous variable (min=0.0, max=+oo)
    573573              x_1 is a continuous variable (min=0.0, max=+oo)
     
    601601            if c == 0:
    602602                continue
    603603
    604             print (("+" if (not first and c>0) else "") +
    605                    ("" if c == 1 else ("-" if c == -1 else str(c)+" "))+varid_name[i]
     604            print (("+ " if (not first and c>0) else "") +
     605                   ("" if c == 1 else ("- " if c == -1 else str(c)+" "))+varid_name[i]
    606606                   ),
    607607            first = False
    608608
     609        if b.obj_constant_term > 0.0: print "+", b.obj_constant_term
     610        elif b.obj_constant_term < 0.0: print "-", -b.obj_constant_term
     611
    609612        print
    610613
    611614        ##### Constraints
     
    635638                if c == 0:
    636639                    continue
    637640
    638                 print (("+" if (not first and c>0) else "") +
    639                        ("" if c == 1 else ("-" if c == -1 else str(c)+" "))+varid_name[j]
     641                print (("+ " if (not first and c>0) else "") +
     642                       ("" if c == 1 else ("- " if c == -1 else (str(c) + " " if first and c < 0 else ("- " + str(abs(c)) + " " if c < 0 else str(c) + " "))))+varid_name[j]
    640643                       ),
    641644                first = False
    642645
     
    671674
    672675        INPUT:
    673676
    674         - ``filename`` -- The file in which you want the problem 
     677        - ``filename`` -- The file in which you want the problem
    675678          to be written.
    676679
    677680        - ``modern`` -- Lets you choose between Fixed MPS and Free MPS
     
    691694        http://en.wikipedia.org/wiki/MPS_%28format%29
    692695        """
    693696       
    694         self._backend.write_mps(filename, modern)       
     697        self._backend.write_mps(filename, modern)
    695698
    696699    def write_lp(self,filename):
    697700        r"""
     
    701704
    702705        INPUT:
    703706
    704         - ``filename`` -- The file in which you want the problem 
     707        - ``filename`` -- The file in which you want the problem
    705708          to be written.
    706709
    707710        EXAMPLE::
     
    717720        """
    718721
    719722        self._backend.write_lp(filename)
    720        
     723
    721724    def get_values(self, *lists):
    722725        r"""
    723726        Return values found by the previous call to ``solve()``.
     
    749752            sage: p.add_constraint(x[3] + y[2][9] + 2*x[5], max=2)
    750753            sage: p.solve()
    751754            6.0
    752            
     755
    753756        To return  the optimal value of ``y[2][9]``::
    754757
    755758            sage: p.get_values(y[2][9])
    756759            2.0
    757760
    758         To get a dictionary identical to ``x`` containing optimal 
     761        To get a dictionary identical to ``x`` containing optimal
    759762        values for the corresponding variables ::
    760763
    761764            sage: x_sol = p.get_values(x)
     
    852855        else:
    853856            f = {-1 : 0}
    854857
    855         f.pop(-1,0)
     858        cdef double d = f.pop(-1,0.0)
    856859
    857860        for i in range(self._backend.ncols()):
    858             values.append(f.get(i,0))
    859 
    860 
    861         self._backend.set_objective(values)
     861            values.append(f.get(i,0.0))
     862
     863        self._backend.set_objective(values, d)
    862864
    863865    def add_constraint(self, linear_function, max=None, min=None, name=None):
    864866        r"""
     
    945947            Maximization:
    946948            <BLANKLINE>
    947949            Constraints:
    948               -2.0 x_0 -x_1 <= 9.0
     950              -2.0 x_0 - x_1 <= 9.0
    949951            Variables:
    950952              x_0 is a continuous variable (min=0.0, max=+oo)
    951953              x_1 is a continuous variable (min=0.0, max=+oo)
     
    975977            Maximization:
    976978            <BLANKLINE>
    977979            Constraints:
    978               1.0 <= x_0 -x_1
     980              1.0 <= x_0 - x_1
    979981            Variables:
    980982              x_0 is a continuous variable (min=0.0, max=+oo)
    981983              x_1 is a continuous variable (min=0.0, max=+oo)
     
    986988            sage: lp.show()
    987989            Maximization:
    988990            <BLANKLINE>
    989             Constraints: 
    990               1.0 <= x_0 -x_1 
    991             Variables: 
    992               x_0 is a continuous variable (min=0.0, max=+oo) 
    993               x_1 is a continuous variable (min=0.0, max=+oo) 
    994          
    995         But if the constant multiple is negative, we should add it anyway (once):: 
    996          
    997               sage: for each in xrange(10): lp.add_constraint(-2*lp[0]+2*lp[1],min=-2) 
    998               sage: lp.show() 
    999               Maximization: 
    1000               <BLANKLINE> 
    1001               Constraints: 
    1002                 1.0 <= x_0 -x_1 
    1003                 x_0 -x_1 <= 1.0
    1004               Variables: 
    1005                 x_0 is a continuous variable (min=0.0, max=+oo) 
    1006                 x_1 is a continuous variable (min=0.0, max=+oo) 
     991            Constraints:
     992              1.0 <= x_0 - x_1
     993            Variables:
     994              x_0 is a continuous variable (min=0.0, max=+oo)
     995              x_1 is a continuous variable (min=0.0, max=+oo)
     996
     997        But if the constant multiple is negative, we should add it anyway (once)::
     998
     999              sage: for each in xrange(10): lp.add_constraint(-2*lp[0]+2*lp[1],min=-2)
     1000              sage: lp.show()
     1001              Maximization:
     1002              <BLANKLINE>
     1003              Constraints:
     1004                1.0 <= x_0 - x_1
     1005                x_0 - x_1 <= 1.0
     1006              Variables:
     1007                x_0 is a continuous variable (min=0.0, max=+oo)
     1008                x_1 is a continuous variable (min=0.0, max=+oo)
    10071009        """
    10081010        if linear_function is None or linear_function is 0:
    10091011            return None
     
    10551057
    10561058        elif isinstance(linear_function,LinearConstraint):
    10571059            functions = linear_function.constraints
    1058            
     1060
    10591061            if linear_function.equality:
    10601062                self.add_constraint(functions[0] - functions[1], min=0, max=0, name=name)
    10611063
     
    10661068                self.add_constraint(functions[0] - functions[1], max=0, name=name)
    10671069                self.add_constraint(functions[1] - functions[2], max=0, name=name)
    10681070
     1071    def remove_constraint(self, int i):
     1072        r"""
     1073        Removes a constraint from self.
     1074
     1075        INPUT:
     1076
     1077        - ``i`` -- Index of the constraint to remove.
     1078
     1079        EXAMPLE::
     1080
     1081            sage: p = MixedIntegerLinearProgram()
     1082            sage: x, y = p[0], p[1]
     1083            sage: p.add_constraint(x + y, max = 10)
     1084            sage: p.add_constraint(x - y, max = 0)
     1085            sage: p.add_constraint(x, max = 4)
     1086            sage: p.show()
     1087            Maximization:
     1088            <BLANKLINE>
     1089            Constraints:
     1090              x_0 + x_1 <= 10.0
     1091              x_0 - x_1 <= 0.0
     1092              x_0 <= 4.0
     1093            ...
     1094            sage: p.remove_constraint(1)
     1095            sage: p.show()
     1096            Maximization:
     1097            <BLANKLINE>
     1098            Constraints:
     1099              x_0 + x_1 <= 10.0
     1100              x_0 <= 4.0
     1101            ...
     1102            sage: p.number_of_constraints()
     1103            2
     1104        """
     1105        self._backend.remove_constraint(i)
     1106
     1107    def remove_constraints(self, constraints):
     1108        r"""
     1109        Remove several constraints.
     1110
     1111        INPUT:
     1112
     1113        - ``constraints`` -- an iterable containing the indices of the rows to remove.
     1114
     1115        EXAMPLE::
     1116
     1117            sage: p = MixedIntegerLinearProgram()
     1118            sage: x, y = p[0], p[1]
     1119            sage: p.add_constraint(x + y, max = 10)
     1120            sage: p.add_constraint(x - y, max = 0)
     1121            sage: p.add_constraint(x, max = 4)
     1122            sage: p.show()
     1123            Maximization:
     1124            <BLANKLINE>
     1125            Constraints:
     1126              x_0 + x_1 <= 10.0
     1127              x_0 - x_1 <= 0.0
     1128              x_0 <= 4.0
     1129            ...
     1130            sage: p.remove_constraints([0, 1])
     1131            sage: p.show()
     1132            Maximization:
     1133            <BLANKLINE>
     1134            Constraints:
     1135              x_0 <= 4.0
     1136            ...
     1137            sage: p.number_of_constraints()
     1138            1
     1139        """
     1140        self._backend.remove_constraints(constraints)
     1141
    10691142    def set_binary(self, ee):
    10701143        r"""
    10711144        Sets a variable or a ``MIPVariable`` as binary.
     
    11481221
    11491222            sage: p = MixedIntegerLinearProgram()
    11501223            sage: x = p.new_variable()
    1151        
     1224
    11521225        With the following instruction, all the variables
    11531226        from x will be integers::
    11541227
     
    12241297            sage: p.set_real(x)
    12251298            sage: p.set_objective(x[0] + x[1])
    12261299            sage: p.add_constraint(-3*x[0] + 2*x[1], max=2)
    1227        
     1300
    12281301         It is still possible, though, to set one of these
    12291302         variables as binary while keeping the others as they are::
    12301303
     
    12851358        - ``solver`` -- DEPRECATED -- the solver now has to be set
    12861359          when calling the class' constructor
    12871360
    1288         - ``log`` -- integer (default: ``0``) The verbosity level. Indicates
    1289           whether progress should be printed during computation.
     1361        - ``log`` -- integer (default: ``None``) The verbosity level. Indicates
     1362          whether progress should be printed during computation. The solver is
     1363          initialized to report no progress.
    12901364
    12911365        - ``objective_only`` -- Boolean variable.
    12921366
     
    13371411            sage: p.set_binary(b)
    13381412            sage: p.solve(objective_only=True)
    13391413            4.0
     1414 
     1415        Constraints in the objective function are respected:
     1416
     1417            sage: p = MixedIntegerLinearProgram()
     1418            sage: x, y = p[0], p[1]
     1419            sage: p.add_constraint(2*x + 3*y, max = 6)
     1420            sage: p.add_constraint(3*x + 2*y, max = 6)
     1421            sage: p.set_objective(x + y + 7)
     1422            sage: p.set_integer(x); p.set_integer(y)
     1423            sage: p.solve()
     1424            9.0
    13401425        """
    13411426
    13421427        if solver != None:
     
    16251710        # and copy it over
    16261711        self._name = <char*>sage_malloc(len(name)+1)
    16271712        strcpy(self._name, name_c)
    1628        
     1713
    16291714    def __dealloc__(self):
    16301715        if self._name:
    16311716            sage_free(self._name)
     
    16661751
    16671752        else:
    16681753            self._dict[i] = MIPVariable(
    1669                 self._p, 
    1670                 self._vtype, 
    1671                 dim=self._dim-1, 
     1754                self._p,
     1755                self._vtype,
     1756                dim=self._dim-1,
    16721757                name = ("" if not self._hasname
    16731758                        else (str(self._name) + "[" + str(i) + "]")))
    16741759
     
    17591844
    17601845        A linear function is represented as a dictionary. The
    17611846        values are the coefficient of the variable represented
    1762         by the keys ( which are integers ). The key ``-1`` 
     1847        by the keys ( which are integers ). The key ``-1``
    17631848        corresponds to the constant term.
    17641849
    17651850        EXAMPLES:
     
    17871872
    17881873        A linear function is represented as a dictionary. The
    17891874        value are the coefficient of the variable represented
    1790         by the keys ( which are integers ). The key ``-1`` 
     1875        by the keys ( which are integers ). The key ``-1``
    17911876        corresponds to the constant term.
    17921877
    17931878        EXAMPLE::
     
    20232108    - ``L`` a list of ``LinearFunction`` instances.
    20242109
    20252110    .. NOTE::
    2026    
    2027         The use of the regular ``sum`` function is not recommended as it is much less efficient than this one.
     2111
     2112        The use of the regular ``sum`` function is not recommended as it is much less efficient than this one
    20282113
    20292114    EXAMPLES::
    20302115
     
    20382123
    20392124    is much more efficient than::
    20402125
    2041         sage: s = sum([v[i] for i in xrange(90)])   
     2126        sage: s = sum([v[i] for i in xrange(90)])
    20422127
    20432128    """
    20442129
     
    20592144    two linear functions, this class lets the user
    20602145    write ``LinearFunction1 <= LinearFunction2``
    20612146    to define the corresponding constraint, which
    2062     can potentially involve several layers of such 
     2147    can potentially involve several layers of such
    20632148    inequalities (``(A <= B <= C``), or even equalities
    20642149    like ``A == B``.
    20652150
    20662151    This class has no reason to be instanciated by the
    2067     user, and is meant to be used by instances of 
     2152    user, and is meant to be used by instances of
    20682153    MixedIntegerLinearProgram.
    20692154
    20702155    INPUT:
    2071    
     2156
    20722157    - ``c`` -- A ``LinearFunction``
    2073    
     2158
    20742159    EXAMPLE::
    2075    
     2160
    20762161        sage: p = MixedIntegerLinearProgram()
    20772162        sage: b = p.new_variable()
    20782163        sage: b[2]+2*b[3] <= b[8]-5
     
    20842169        Constructor for ``LinearConstraint``
    20852170
    20862171        INPUT:
    2087        
     2172
    20882173        - ``c`` -- A linear function (see ``LinearFunction``).
    2089        
     2174
    20902175        EXAMPLE::
    2091        
     2176
    20922177            sage: p = MixedIntegerLinearProgram()
    20932178            sage: b = p.new_variable()
    20942179            sage: b[2]+2*b[3] <= b[8]-5
     
    21042189    def __repr__(self):
    21052190        r"""
    21062191        Returns a string representation of the constraint.
    2107        
     2192
    21082193        EXAMPLE::
    21092194
    21102195            sage: p = MixedIntegerLinearProgram()
     
    21672252    def __lt__(self, other):
    21682253        r"""
    21692254        Prevents the use of the stricts operators ``<`` and ``>``
    2170        
     2255
    21712256        EXAMPLE::
    21722257
    21732258            sage: p = MixedIntegerLinearProgram()