Ticket #12823: trac_12823_rolls_all_into_one.patch
File trac_12823_rolls_all_into_one.patch, 41.7 KB (added by , 9 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 119 119 double * getColLower() 120 120 double * getColUpper() 121 121 122 # add row122 # add, delete rows 123 123 void addRow(CoinPackedVectorBase & vec, double rowlb, double rowub) 124 void deleteRows(int num, int *) 124 125 125 126 # io 126 127 void writeMps(char *filename, char *extension, double objSense) … … 180 181 cdef OsiSolverInterface * si 181 182 cdef CbcModel * model 182 183 cdef int log_level 183 cdef double obj_value184 184 185 185 cdef list col_names, row_names 186 186 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 45 45 else: 46 46 self.set_sense(-1) 47 47 48 self.obj_constant_term = 0.0 49 48 50 def __dealloc__(self): 49 51 r""" 50 52 Destructor function … … 301 303 else: 302 304 return self.si.getObjCoefficients()[variable] 303 305 304 cpdef set_objective(self, list coeff ):306 cpdef set_objective(self, list coeff, double d = 0.0): 305 307 r""" 306 308 Sets the objective function. 307 309 … … 310 312 - ``coeff`` -- a list of real values, whose ith element is the 311 313 coefficient of the ith variable in the objective function. 312 314 315 - ``d`` (double) -- the constant term in the linear function (set to `0` by default) 316 313 317 EXAMPLE:: 314 318 315 319 sage: from sage.numerical.backends.generic_backend import get_solver … … 319 323 sage: p.set_objective([1, 1, 2, 1, 3]) # optional - Coin 320 324 sage: map(lambda x :p.objective_coefficient(x), range(5)) # optional - Coin 321 325 [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 322 337 """ 323 338 324 339 cdef int i … … 326 341 for i,v in enumerate(coeff): 327 342 self.si.setObjCoeff(i, v) 328 343 344 self.obj_constant_term = d 345 329 346 cpdef set_verbosity(self, int level): 330 347 r""" 331 348 Sets the log (verbosity) level … … 344 361 345 362 self.model.setLogLevel(level) 346 363 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) 347 457 348 458 cpdef add_linear_constraints(self, int number, lower_bound, upper_bound, names = None): 349 459 """ … … 685 795 sage: p.get_variable_value(1) # optional - Coin 686 796 1.5 687 797 """ 688 return self.model.solver().getObjValue() 798 return self.model.solver().getObjValue() + self.obj_constant_term 689 799 690 800 cpdef double get_variable_value(self, int variable): 691 801 r""" … … 1044 1154 p.si = self.si.clone(1) 1045 1155 p.row_names = copy(self.row_names) 1046 1156 p.col_names = copy(self.col_names) 1157 p.obj_constant_term = self.obj_constant_term 1047 1158 # Maybe I should copy this, not sure -- seems complicated, though 1048 1159 p.prob_name = self.prob_name 1049 1160 -
sage/numerical/backends/cplex_backend.pxd
diff --git a/sage/numerical/backends/cplex_backend.pxd b/sage/numerical/backends/cplex_backend.pxd
a b 36 36 double *rmatval, char **colname, 37 37 char **rowname) 38 38 39 # Remove constraints 40 int CPXdelrows(c_cpxlp * env, c_cpxlp * lp, int begin, int end) 41 39 42 # Solve MILP 40 43 int CPXmipopt (c_cpxlp * env, c_cpxlp * lp) 41 44 -
sage/numerical/backends/cplex_backend.pyx
diff --git a/sage/numerical/backends/cplex_backend.pyx b/sage/numerical/backends/cplex_backend.pyx
a b 34 34 else: 35 35 self.set_sense(-1) 36 36 37 self.obj_constant_term = 0.0 38 37 39 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: 38 40 """ 39 41 Add a variable. … … 339 341 check(status) 340 342 341 343 342 cpdef set_objective(self, list coeff ):344 cpdef set_objective(self, list coeff, double d = 0.0): 343 345 r""" 344 346 Sets the objective function. 345 347 … … 348 350 - ``coeff`` -- a list of real values, whose ith element is the 349 351 coefficient of the ith variable in the objective function. 350 352 353 - ``d`` (double) -- the constant term in the linear function (set to `0` by default) 354 351 355 EXAMPLE:: 352 356 353 357 sage: from sage.numerical.backends.generic_backend import get_solver … … 357 361 sage: p.set_objective([1, 1, 2, 1, 3]) # optional - CPLEX 358 362 sage: map(lambda x :p.objective_coefficient(x), range(5)) # optional - CPLEX 359 363 [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 360 375 """ 361 376 362 377 cdef int status … … 374 389 sage_free(c_coeff) 375 390 sage_free(c_indices) 376 391 392 self.obj_constant_term = d 393 377 394 378 395 cpdef set_verbosity(self, int level): 379 396 r""" … … 399 416 status = CPXsetintparam (self.env, CPX_PARAM_SCRIND, CPX_ON) 400 417 check(status) 401 418 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 402 447 cpdef add_linear_constraints(self, int number, lower_bound, upper_bound, names = None): 403 448 """ 404 449 Add ``'number`` linear constraints. … … 856 901 status = CPXgetobjval (self.env, self.lp, &value) 857 902 check(status) 858 903 859 return value 904 return value + self.obj_constant_term 860 905 861 906 862 907 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 11 11 cpdef set_variable_type(self, int variable, int vtype) 12 12 cpdef set_sense(self, int sense) 13 13 cpdef objective_coefficient(self, int variable, coeff=*) 14 cpdef set_objective(self, list coeff )14 cpdef set_objective(self, list coeff, double d=*) 15 15 cpdef set_verbosity(self, int level) 16 16 cpdef add_linear_constraint(self, constraints, lower_bound, upper_bound, name=*) 17 cpdef remove_constraint(self, int) 18 cpdef remove_constraints(self, constraints) 17 19 cpdef add_col(self, list indices, list coeffs) 18 20 cpdef add_linear_constraints(self, int number, lower_bound, upper_bound, names=*) 19 21 cpdef int solve(self) except -1 … … 37 39 cpdef variable_lower_bound(self, int index, value = *) 38 40 cpdef solver_parameter(self, name, value=*) 39 41 42 cdef double obj_constant_term 43 40 44 cpdef 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 197 197 """ 198 198 raise NotImplementedError() 199 199 200 cpdef set_objective(self, list coeff ):200 cpdef set_objective(self, list coeff, double d = 0.0): 201 201 """ 202 202 Set the objective function. 203 203 … … 206 206 - ``coeff`` -- a list of real values, whose ith element is the 207 207 coefficient of the ith variable in the objective function. 208 208 209 - ``d`` (double) -- the constant term in the linear function (set to `0` by default) 210 209 211 EXAMPLE:: 210 212 211 213 sage: from sage.numerical.backends.generic_backend import get_solver … … 215 217 sage: p.set_objective([1, 1, 2, 1, 3]) # optional - Nonexistent_LP_solver 216 218 sage: map(lambda x :p.objective_coefficient(x), range(5)) # optional - Nonexistent_LP_solver 217 219 [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 218 231 """ 219 232 raise NotImplementedError() 220 233 … … 234 247 """ 235 248 raise NotImplementedError() 236 249 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 237 277 cpdef add_linear_constraint(self, coefficients, lower_bound, upper_bound, name=None): 238 278 """ 239 279 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 52 52 void glp_set_obj_dir(c_glp_prob *, int) 53 53 void glp_add_rows(c_glp_prob *, int) 54 54 void glp_add_cols(c_glp_prob *, int) 55 void glp_del_rows(c_glp_prob *, int, int *) 55 56 void glp_set_row_name(c_glp_prob *, int, char *) 56 57 void glp_set_col_name(c_glp_prob *, int, char *) 57 58 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 36 36 glp_init_iocp(self.iocp) 37 37 self.iocp.presolve = GLP_ON 38 38 self.set_verbosity(0) 39 self.obj_constant_term = 0.0 39 40 40 41 if maximization: 41 42 self.set_sense(+1) … … 311 312 else: 312 313 glp_set_prob_name(self.lp, name) 313 314 314 cpdef set_objective(self, list coeff ):315 cpdef set_objective(self, list coeff, double d = 0.0): 315 316 """ 316 317 Set the objective function. 317 318 … … 320 321 - ``coeff`` - a list of real values, whose ith element is the 321 322 coefficient of the ith variable in the objective function. 322 323 324 - ``d`` (double) -- the constant term in the linear function (set to `0` by default) 325 323 326 EXAMPLE:: 324 327 325 328 sage: from sage.numerical.backends.generic_backend import get_solver … … 335 338 for i,v in enumerate(coeff): 336 339 glp_set_obj_coef(self.lp, i+1, v) 337 340 341 glp_set_obj_coef(self.lp, 0, d) 342 343 self.obj_constant_term = d 344 338 345 cpdef set_verbosity(self, int level): 339 346 """ 340 347 Set the verbosity level … … 363 370 self.iocp.msg_lev = GLP_MSG_ALL 364 371 self.smcp.msg_lev = GLP_MSG_ALL 365 372 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 366 460 cpdef add_linear_constraint(self, coefficients, lower_bound, upper_bound, name=None): 367 461 """ 368 462 Add a linear constraint. … … 410 504 row_i[i+1] = c+1 411 505 row_values[i+1] = v 412 506 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) 414 508 415 509 if upper_bound is not None and lower_bound is None: 416 510 glp_set_row_bnds(self.lp, n, GLP_UP, upper_bound, upper_bound) 417 511 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) 419 513 elif upper_bound is not None and lower_bound is not None: 420 514 if lower_bound == upper_bound: 421 515 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 30 30 31 31 32 32 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 ) 33 35 int GRBaddrangeconstr(GRBmodel *model, int numnz, int *cind, double *cval, double lower, double upper, char *constrnames) 34 36 35 37 -
sage/numerical/backends/gurobi_backend.pyx
diff --git a/sage/numerical/backends/gurobi_backend.pyx b/sage/numerical/backends/gurobi_backend.pyx
a b 68 68 self.set_sense(1 if maximization else -1) 69 69 70 70 self.set_verbosity(0) 71 self.obj_constant_term = 0.0 71 72 72 73 73 74 … … 420 421 421 422 return value 422 423 423 cpdef set_objective(self, list coeff ):424 cpdef set_objective(self, list coeff, double d = 0.0): 424 425 """ 425 426 Set the objective function. 426 427 … … 429 430 - ``coeff`` - a list of real values, whose ith element is the 430 431 coefficient of the ith variable in the objective function. 431 432 433 - ``d`` (double) -- the constant term in the linear function (set to `0` by default) 434 432 435 EXAMPLE:: 433 436 434 437 sage: from sage.numerical.backends.generic_backend import get_solver # optional - Gurobi … … 438 441 sage: p.set_objective([1, 1, 2, 1, 3]) # optional - Gurobi 439 442 sage: map(lambda x :p.objective_coefficient(x), range(5)) # optional - Gurobi 440 443 [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 441 455 """ 442 456 cdef int i = 0 443 457 cdef double value … … 450 464 451 465 check(self.env,GRBupdatemodel(self.model[0])) 452 466 467 self.obj_constant_term = d 468 453 469 cpdef set_verbosity(self, int level): 454 470 """ 455 471 Set the verbosity level … … 473 489 474 490 check(self.env, error) 475 491 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 476 525 cpdef add_linear_constraint(self, coefficients, lower_bound, upper_bound, name=None): 477 526 """ 478 527 Add a linear constraint. … … 745 794 746 795 check(self.env,GRBgetdblattr(self.model[0], "ObjVal", <double* >p_value)) 747 796 748 return p_value[0] 797 return p_value[0] + self.obj_constant_term 749 798 750 799 cpdef double get_variable_value(self, int variable): 751 800 """ -
sage/numerical/mip.pyx
diff --git a/sage/numerical/mip.pyx b/sage/numerical/mip.pyx
a b 65 65 Minimization: 66 66 x_3 67 67 Constraints: 68 0.0 <= x_0 + x_1 +x_2 -14.0 x_3 <= 0.069 0.0 <= x_1 + 2.0 x_2 -8.0 x_3 <= 0.070 0.0 <= 2.0 x_2 - 3.0 x_3 <= 0.071 - x_0 +x_1 +x_2 <= 0.072 - x_3 <= -1.068 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 73 73 Variables: 74 74 x_0 is an integer variable (min=0.0, max=+oo) 75 75 x_1 is an integer variable (min=-oo, max=+oo) … … 334 334 335 335 INPUT: 336 336 337 - ``name`` -- A string representing the name of the 337 - ``name`` -- A string representing the name of the 338 338 ``MixedIntegerLinearProgram``. 339 339 340 340 EXAMPLE:: 341 341 342 342 sage: p=MixedIntegerLinearProgram() … … 367 367 reals. They can be defined as binary through the parameter 368 368 ``binary=True`` (or integer with ``integer=True``). Lower and 369 369 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 371 371 ``set_min`` and ``set_max``. 372 372 373 373 INPUT: … … 380 380 to ``True`` to ensure that the variable gets the corresponding 381 381 type. The default type is ``real``. 382 382 383 - ``name`` (string) -- Associates a name to the variable. This is 383 - ``name`` (string) -- Associates a name to the variable. This is 384 384 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. 386 386 387 387 EXAMPLE:: 388 388 … … 422 422 cpdef int number_of_constraints(self): 423 423 r""" 424 424 Returns the number of constraints assigned so far. 425 425 426 426 EXAMPLE:: 427 427 sage: p = MixedIntegerLinearProgram() 428 428 sage: p.add_constraint(p[0] - p[2], min = 1, max = 4) … … 431 431 2 432 432 """ 433 433 return self._backend.nrows() 434 434 435 435 def constraints(self, indices = None): 436 436 r""" 437 437 Returns a list of constraints, as 3-tuples. … … 550 550 sage: p.add_constraint(-3*x[1] + 2*x[2], max=2, name="Constraint_1") 551 551 sage: p.show() 552 552 Maximization: 553 Hey[1] + Hey[2]553 Hey[1] + Hey[2] 554 554 Constraints: 555 Constraint_1: -3.0 Hey[1] + 2.0 Hey[2] <= 2.0555 Constraint_1: -3.0 Hey[1] + 2.0 Hey[2] <= 2.0 556 556 Variables: 557 557 Hey[1] is a continuous variable (min=0.0, max=+oo) 558 558 Hey[2] is a continuous variable (min=0.0, max=+oo) … … 565 565 sage: p.add_constraint(-3*x[1] + 2*x[2], max=2) 566 566 sage: p.show() 567 567 Maximization: 568 x_0 + x_1568 x_0 + x_1 569 569 Constraints: 570 -3.0 x_0 + 2.0 x_1 <= 2.0570 -3.0 x_0 + 2.0 x_1 <= 2.0 571 571 Variables: 572 572 x_0 is a continuous variable (min=0.0, max=+oo) 573 573 x_1 is a continuous variable (min=0.0, max=+oo) … … 601 601 if c == 0: 602 602 continue 603 603 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] 606 606 ), 607 607 first = False 608 608 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 609 612 print 610 613 611 614 ##### Constraints … … 635 638 if c == 0: 636 639 continue 637 640 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] 640 643 ), 641 644 first = False 642 645 … … 671 674 672 675 INPUT: 673 676 674 - ``filename`` -- The file in which you want the problem 677 - ``filename`` -- The file in which you want the problem 675 678 to be written. 676 679 677 680 - ``modern`` -- Lets you choose between Fixed MPS and Free MPS … … 691 694 http://en.wikipedia.org/wiki/MPS_%28format%29 692 695 """ 693 696 694 self._backend.write_mps(filename, modern) 697 self._backend.write_mps(filename, modern) 695 698 696 699 def write_lp(self,filename): 697 700 r""" … … 701 704 702 705 INPUT: 703 706 704 - ``filename`` -- The file in which you want the problem 707 - ``filename`` -- The file in which you want the problem 705 708 to be written. 706 709 707 710 EXAMPLE:: … … 717 720 """ 718 721 719 722 self._backend.write_lp(filename) 720 723 721 724 def get_values(self, *lists): 722 725 r""" 723 726 Return values found by the previous call to ``solve()``. … … 749 752 sage: p.add_constraint(x[3] + y[2][9] + 2*x[5], max=2) 750 753 sage: p.solve() 751 754 6.0 752 755 753 756 To return the optimal value of ``y[2][9]``:: 754 757 755 758 sage: p.get_values(y[2][9]) 756 759 2.0 757 760 758 To get a dictionary identical to ``x`` containing optimal 761 To get a dictionary identical to ``x`` containing optimal 759 762 values for the corresponding variables :: 760 763 761 764 sage: x_sol = p.get_values(x) … … 852 855 else: 853 856 f = {-1 : 0} 854 857 855 f.pop(-1,0)858 cdef double d = f.pop(-1,0.0) 856 859 857 860 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) 862 864 863 865 def add_constraint(self, linear_function, max=None, min=None, name=None): 864 866 r""" … … 945 947 Maximization: 946 948 <BLANKLINE> 947 949 Constraints: 948 -2.0 x_0 - x_1 <= 9.0950 -2.0 x_0 - x_1 <= 9.0 949 951 Variables: 950 952 x_0 is a continuous variable (min=0.0, max=+oo) 951 953 x_1 is a continuous variable (min=0.0, max=+oo) … … 975 977 Maximization: 976 978 <BLANKLINE> 977 979 Constraints: 978 1.0 <= x_0 - x_1980 1.0 <= x_0 - x_1 979 981 Variables: 980 982 x_0 is a continuous variable (min=0.0, max=+oo) 981 983 x_1 is a continuous variable (min=0.0, max=+oo) … … 986 988 sage: lp.show() 987 989 Maximization: 988 990 <BLANKLINE> 989 Constraints: 990 1.0 <= x_0 - x_1991 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_11003 x_0 - x_1 <= 1.01004 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) 1007 1009 """ 1008 1010 if linear_function is None or linear_function is 0: 1009 1011 return None … … 1055 1057 1056 1058 elif isinstance(linear_function,LinearConstraint): 1057 1059 functions = linear_function.constraints 1058 1060 1059 1061 if linear_function.equality: 1060 1062 self.add_constraint(functions[0] - functions[1], min=0, max=0, name=name) 1061 1063 … … 1066 1068 self.add_constraint(functions[0] - functions[1], max=0, name=name) 1067 1069 self.add_constraint(functions[1] - functions[2], max=0, name=name) 1068 1070 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 1069 1142 def set_binary(self, ee): 1070 1143 r""" 1071 1144 Sets a variable or a ``MIPVariable`` as binary. … … 1148 1221 1149 1222 sage: p = MixedIntegerLinearProgram() 1150 1223 sage: x = p.new_variable() 1151 1224 1152 1225 With the following instruction, all the variables 1153 1226 from x will be integers:: 1154 1227 … … 1224 1297 sage: p.set_real(x) 1225 1298 sage: p.set_objective(x[0] + x[1]) 1226 1299 sage: p.add_constraint(-3*x[0] + 2*x[1], max=2) 1227 1300 1228 1301 It is still possible, though, to set one of these 1229 1302 variables as binary while keeping the others as they are:: 1230 1303 … … 1285 1358 - ``solver`` -- DEPRECATED -- the solver now has to be set 1286 1359 when calling the class' constructor 1287 1360 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. 1290 1364 1291 1365 - ``objective_only`` -- Boolean variable. 1292 1366 … … 1337 1411 sage: p.set_binary(b) 1338 1412 sage: p.solve(objective_only=True) 1339 1413 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 1340 1425 """ 1341 1426 1342 1427 if solver != None: … … 1625 1710 # and copy it over 1626 1711 self._name = <char*>sage_malloc(len(name)+1) 1627 1712 strcpy(self._name, name_c) 1628 1713 1629 1714 def __dealloc__(self): 1630 1715 if self._name: 1631 1716 sage_free(self._name) … … 1666 1751 1667 1752 else: 1668 1753 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, 1672 1757 name = ("" if not self._hasname 1673 1758 else (str(self._name) + "[" + str(i) + "]"))) 1674 1759 … … 1759 1844 1760 1845 A linear function is represented as a dictionary. The 1761 1846 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`` 1763 1848 corresponds to the constant term. 1764 1849 1765 1850 EXAMPLES: … … 1787 1872 1788 1873 A linear function is represented as a dictionary. The 1789 1874 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`` 1791 1876 corresponds to the constant term. 1792 1877 1793 1878 EXAMPLE:: … … 2023 2108 - ``L`` a list of ``LinearFunction`` instances. 2024 2109 2025 2110 .. 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 2028 2113 2029 2114 EXAMPLES:: 2030 2115 … … 2038 2123 2039 2124 is much more efficient than:: 2040 2125 2041 sage: s = sum([v[i] for i in xrange(90)]) 2126 sage: s = sum([v[i] for i in xrange(90)]) 2042 2127 2043 2128 """ 2044 2129 … … 2059 2144 two linear functions, this class lets the user 2060 2145 write ``LinearFunction1 <= LinearFunction2`` 2061 2146 to define the corresponding constraint, which 2062 can potentially involve several layers of such 2147 can potentially involve several layers of such 2063 2148 inequalities (``(A <= B <= C``), or even equalities 2064 2149 like ``A == B``. 2065 2150 2066 2151 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 2068 2153 MixedIntegerLinearProgram. 2069 2154 2070 2155 INPUT: 2071 2156 2072 2157 - ``c`` -- A ``LinearFunction`` 2073 2158 2074 2159 EXAMPLE:: 2075 2160 2076 2161 sage: p = MixedIntegerLinearProgram() 2077 2162 sage: b = p.new_variable() 2078 2163 sage: b[2]+2*b[3] <= b[8]-5 … … 2084 2169 Constructor for ``LinearConstraint`` 2085 2170 2086 2171 INPUT: 2087 2172 2088 2173 - ``c`` -- A linear function (see ``LinearFunction``). 2089 2174 2090 2175 EXAMPLE:: 2091 2176 2092 2177 sage: p = MixedIntegerLinearProgram() 2093 2178 sage: b = p.new_variable() 2094 2179 sage: b[2]+2*b[3] <= b[8]-5 … … 2104 2189 def __repr__(self): 2105 2190 r""" 2106 2191 Returns a string representation of the constraint. 2107 2192 2108 2193 EXAMPLE:: 2109 2194 2110 2195 sage: p = MixedIntegerLinearProgram() … … 2167 2252 def __lt__(self, other): 2168 2253 r""" 2169 2254 Prevents the use of the stricts operators ``<`` and ``>`` 2170 2255 2171 2256 EXAMPLE:: 2172 2257 2173 2258 sage: p = MixedIntegerLinearProgram()