Ticket #7012: trac_7012-reviewer.patch
File trac_7012-reviewer.patch, 56.0 KB (added by , 11 years ago) |
---|
-
doc/en/reference/numerical.rst
# HG changeset patch # User Minh Van Nguyen <nguyenminh2@gmail.com> # Date 1254398734 25200 # Node ID 365d6bf608b2a6456160d1c49b6b8dabd8cc534e # Parent 87bf97ad64fbe4068336a565c60937adf443d58d trac 7012: reviewer patch diff -r 87bf97ad64fb -r 365d6bf608b2 doc/en/reference/numerical.rst
a b 5 5 :maxdepth: 2 6 6 7 7 sage/numerical/knapsack 8 sage/numerical/mip 8 9 sage/numerical/optimize -
sage/numerical/mip.pyx
diff -r 87bf97ad64fb -r 365d6bf608b2 sage/numerical/mip.pyx
a b 1 include '../ext/stdsage.pxi' 1 r""" 2 Mixed integer linear programming 3 """ 4 5 include "../ext/stdsage.pxi" 2 6 3 7 class MixedIntegerLinearProgram: 4 8 r""" 5 The ``MixedIntegerLinearProgram`` class is the link between SAGE and LP ( Linear Program ) and 6 MIP ( Mixed Integer Program ) Solvers. Cf : http://en.wikipedia.org/wiki/Linear_programming 9 The ``MixedIntegerLinearProgram`` class is the link between Sage, linear 10 programming (LP) and mixed integer programming (MIP) solvers. See the 11 Wikipedia article on 12 `linear programming <http://en.wikipedia.org/wiki/Linear_programming>`_ 13 for further information. A mixed integer program consists of variables, 14 linear constraints on these variables, and an objective function which is 15 to be maximised or minimised under these constraints. An instance of 16 ``MixedIntegerLinearProgram`` also requires the information on the 17 direction of the optimization. 7 18 8 It consists of variables, linear constraints on these variables, and an objective 9 function which is to be maximised or minimised under these constraints. 10 11 An instance of ``MixedIntegerLinearProgram`` also requires the information 12 on the direction of the optimization : 13 14 A ``MixedIntegerLinearProgram`` ( or ``LP`` ) is defined as a maximization 15 if ``sense=1``, and is a minimization if ``sense=-1`` 19 A ``MixedIntegerLinearProgram`` (or ``LP``) is defined as a maximization 20 if ``maximization=True`` and is a minimization if ``maximization=False``. 16 21 17 22 INPUT: 18 19 - ``sense`` : 20 * When set to `1` (default), the ``MixedIntegerLinearProgram`` is defined as a Maximization 21 * When set to `-1`, the ``MixedIntegerLinearProgram`` is defined as a Minimization 22 23 24 - ``maximization`` 25 26 - When set to ``True`` (default), the ``MixedIntegerLinearProgram`` is 27 defined as a maximization. 28 - When set to ``False``, the ``MixedIntegerLinearProgram`` is defined as 29 a minimization. 30 23 31 EXAMPLES:: 24 32 25 sage: ### Computation of a maximum stable set in Petersen's graph ###26 sage: g =graphs.PetersenGraph()27 sage: p =MixedIntegerLinearProgram(sense=1)28 sage: b =p.new_variable()33 sage: ### Computation of a maximum stable set in Petersen's graph 34 sage: g = graphs.PetersenGraph() 35 sage: p = MixedIntegerLinearProgram(maximization=True) 36 sage: b = p.new_variable() 29 37 sage: p.set_objective(sum([b[v] for v in g])) 30 38 sage: for (u,v) in g.edges(labels=None): 31 ... p.add_constraint(b[u] +b[v],max=1)39 ... p.add_constraint(b[u] + b[v], max=1) 32 40 sage: p.set_binary(b) 33 41 sage: p.solve(objective_only=True) # optional - requires Glpk or COIN-OR/CBC 34 42 4.0 35 """ 43 """ 36 44 37 def __init__(self, sense=1):45 def __init__(self, maximization=True): 38 46 r""" 39 Constructor for the ``MixedIntegerLinearProgram`` class 47 Constructor for the ``MixedIntegerLinearProgram`` class. 40 48 41 49 INPUT: 42 43 - ``sense`` : 44 When set to 1, the MixedIntegerLinearProgram is defined as a Maximization 45 When set to -1, the MixedIntegerLinearProgram is defined as a Minimization 50 51 - ``maximization`` 52 53 - When set to ``True`` (default), the ``MixedIntegerLinearProgram`` 54 is defined as a maximization. 55 - When set to ``False``, the ``MixedIntegerLinearProgram`` is 56 defined as a minimization. 46 57 47 58 EXAMPLE:: 48 59 49 sage: p =MixedIntegerLinearProgram(sense=1)60 sage: p = MixedIntegerLinearProgram(maximization=True) 50 61 """ 51 52 62 try: 53 54 self.default_solver="Coin"63 from sage.numerical.mipCoin import solveCoin 64 self.default_solver = "Coin" 55 65 except: 56 try: 57 from sage.numerical.mipGlpk import solveGlpk 58 self.default_solver="GLPK" 59 except: 60 self.default_solver=None 61 66 try: 67 from sage.numerical.mipGlpk import solveGlpk 68 self.default_solver = "GLPK" 69 except: 70 self.default_solver = None 62 71 63 72 from sage.rings.polynomial.infinite_polynomial_ring import InfinitePolynomialRing 64 73 from sage.rings.real_double import RealDoubleField as RR 65 P = InfinitePolynomialRing(RR(), names=('x',)) ;74 P = InfinitePolynomialRing(RR(), names=('x',)) 66 75 (self.x,) = P._first_ngens(1) 67 76 68 77 # number of variables 69 self.count =070 self. sense=sense71 self.objective =None78 self.count = 0 79 self.maximization = maximization 80 self.objective = None 72 81 73 self.variables ={}74 self.constraints =[]75 82 self.variables = {} 83 self.constraints = [] 84 76 85 #constains the min and max bounds on the variables 77 self.min ={}78 self.max ={}86 self.min = {} 87 self.max = {} 79 88 80 89 # constains the variables types 81 self.types ={}90 self.types = {} 82 91 83 #constains the variables' values when solve(objective_only=False) is called 84 self.values={} 85 92 #constains the variables' values when 93 # solve(objective_only=False) is called 94 self.values = {} 95 86 96 # Several constants 87 self.__BINARY =188 self.__REAL =-189 self.__INTEGER =097 self.__BINARY = 1 98 self.__REAL = -1 99 self.__INTEGER = 0 90 100 91 101 def __repr__(self): 92 102 r""" 93 Returns a short description of the MixedIntegerLinearProgram94 103 Returns a short description of the ``MixedIntegerLinearProgram``. 104 95 105 EXAMPLE:: 96 97 sage: p=MixedIntegerLinearProgram()98 sage: v=p.new_variable()99 sage: p.add_constraint(v[1]+v[2],max=2)100 sage: print p101 Mixed Integer Program ( maximization, 2 variables, 1 constraints )106 107 sage: p = MixedIntegerLinearProgram() 108 sage: v = p.new_variable() 109 sage: p.add_constraint(v[1] + v[2], max=2) 110 sage: print p 111 Mixed Integer Program ( maximization, 2 variables, 1 constraints ) 102 112 """ 103 return "Mixed Integer Program ( "+("maximization" if self.sense==1 else "minimization")+", "+str(len(self.variables))+" variables, "+str(len(self.constraints))+" constraints )" 113 return "Mixed Integer Program ( " + \ 114 ( "maximization" if self.maximization else "minimization" ) + \ 115 ", " + str(len(self.variables)) + " variables, " + \ 116 str(len(self.constraints)) + " constraints )" 104 117 105 def new_variable(self, vtype=-1,dim=1):118 def new_variable(self, vtype=-1, dim=1): 106 119 r""" 107 120 Returns an instance of ``MIPVariable`` associated 108 121 to the current instance of ``MixedIntegerLinearProgram``. 109 110 A new variable ``x`` is defined by :::111 122 112 sage: p=MixedIntegerLinearProgram() 113 sage: x=p.new_variable() 123 A new variable ``x`` is defined by:: 124 125 sage: p = MixedIntegerLinearProgram() 126 sage: x = p.new_variable() 114 127 115 128 It behaves exactly as a usual dictionary would. It can use any key 116 argument you may like, as ``x[5]`` or ``x["b"]``, and has methods 117 ``items()`` and ``keys()`` 118 129 argument you may like, as ``x[5]`` or ``x["b"]``, and has methods 130 ``items()`` and ``keys()``. 131 119 132 Any of its fields exists, and is uniquely defined. 120 133 121 134 INPUT: 122 135 123 - ``dim`` ( integer ) : Defines the dimension of the dictionary 124 If ``x`` has dimension `2`, its fields will 125 be of the form ``x[key1][key2]`` 126 - ``vtype`` ( integer ) : Defines the type of the variables 127 ( default is Real ) 128 136 - ``dim`` (integer) -- Defines the dimension of the dictionary. 137 If ``x`` has dimension `2`, its fields will be of the form 138 ``x[key1][key2]``. 139 - ``vtype`` (integer) -- Defines the type of the variables 140 (default is ``REAL``). 129 141 130 142 EXAMPLE:: 131 143 132 sage: p =MixedIntegerLinearProgram()144 sage: p = MixedIntegerLinearProgram() 133 145 sage: # available types are p.__REAL, p.__INTEGER and p.__BINARY 134 sage: x =p.new_variable(vtype=p.__REAL)135 sage: y =p.new_variable(dim=2)136 sage: p.add_constraint(x[2] +y[3][5],max=2)146 sage: x = p.new_variable(vtype=p.__REAL) 147 sage: y = p.new_variable(dim=2) 148 sage: p.add_constraint(x[2] + y[3][5], max=2) 137 149 """ 138 return MIPVariable(self,vtype,dim=dim) 139 150 return MIPVariable(self, vtype, dim=dim) 140 151 141 def export(self,format="text"): 142 r""" 143 Exports the ``MixedIntegerLinearProgram`` to a string in different formats. 144 145 INPUT: 146 147 - ``format`` : 148 "text" : human-readable format 149 150 sage: p=MixedIntegerLinearProgram() 151 sage: x=p.new_variable() 152 sage: p.set_objective(x[1]+x[2]) 153 sage: p.add_constraint(-3*x[1]+2*x[2],max=2) 154 sage: print p.export(format="text") 155 Maximization : 156 x2 + x1 157 Constraints : 158 2.0*x2 - 3.0*x1 159 Variables : 160 x2 is a real variable (min=0.0,max=+oo) 161 x1 is a real variable (min=0.0,max=+oo) 162 """ 163 if format=="text": 164 value=("Maximization :\n" if self.sense==1 else "Minimization :\n") 165 value=value+" "+(str(self.objective) if self.objective!=None else "Undefined") 166 value=value+"\nConstraints :" 167 for c in self.constraints: 168 value=value+"\n "+str(c["function"]) 169 value=value+"\nVariables :" 170 for v in self.variables.keys(): 171 value=value+"\n "+str(v)+" is" 172 if self.is_integer(v): 173 value=value+" an integer variable" 174 elif self.is_binary(v): 175 value=value+" an boolean variable" 176 else: 177 value=value+" a real variable" 178 value+=" (min="+(str(self.get_min(v)) if self.get_min(v)!= None else "-oo")+",max="+(str(self.get_max(v)) if self.get_max(v)!= None else "+oo")+")" 179 return value 180 181 def get_values(self,*lists): 152 def export(self, format="text"): 182 153 r""" 183 Return values found by the previous call to ``solve()`` 154 Exports the ``MixedIntegerLinearProgram`` to a string in 155 different formats. 184 156 185 157 INPUT: 186 187 - Any instance of ``MIPVariable`` ( or one of its elements ), 158 159 - ``format`` 160 161 - ``"text"`` -- (default) human-readable format 162 163 EXAMPLES:: 164 165 sage: p = MixedIntegerLinearProgram() 166 sage: x = p.new_variable() 167 sage: p.set_objective(x[1] + x[2]) 168 sage: p.add_constraint(-3*x[1] + 2*x[2], max=2) 169 sage: print p.export(format="text") 170 Maximization: 171 x2 + x1 172 Constraints: 173 2.0*x2 - 3.0*x1 174 Variables: 175 x2 is a real variable (min=0.0, max=+oo) 176 x1 is a real variable (min=0.0, max=+oo) 177 """ 178 if format == "text": 179 value = ( "Maximization:\n" 180 if self.maximization 181 else "Minimization:\n" ) 182 value += " " + ( str(self.objective) 183 if self.objective != None 184 else "Undefined" ) 185 value += "\nConstraints:" 186 for c in self.constraints: 187 value += "\n " + str(c["function"]) 188 value += "\nVariables:" 189 for v in self.variables.keys(): 190 value += "\n " + str(v) + " is" 191 if self.is_integer(v): 192 value += " an integer variable" 193 elif self.is_binary(v): 194 value += " an boolean variable" 195 else: 196 value += " a real variable" 197 value += " (min=" + \ 198 ( str(self.get_min(v)) 199 if self.get_min(v) != None 200 else "-oo" ) + \ 201 ", max=" + \ 202 ( str(self.get_max(v)) 203 if self.get_max(v) != None 204 else "+oo" ) + \ 205 ")" 206 return value 207 else: 208 raise ValueError("Only human-readable format is currently defined.") 209 210 def get_values(self, *lists): 211 r""" 212 Return values found by the previous call to ``solve()``. 213 214 INPUT: 215 216 - Any instance of ``MIPVariable`` (or one of its elements), 188 217 or lists of them. 189 218 190 219 OUTPUT: 191 220 192 221 - Each instance of ``MIPVariable`` is replaced by a dictionary 193 containing the numerical values found for each194 corresponding variable in the instance222 containing the numerical values found for each 223 corresponding variable in the instance. 195 224 - Each element of an instance of a ``MIPVariable`` is replaced 196 225 by its corresponding numerical value. 197 226 198 227 EXAMPLE:: 199 228 200 sage: p =MixedIntegerLinearProgram()201 sage: x =p.new_variable()202 sage: y =p.new_variable(dim=2)203 sage: p.set_objective(x[3] +y[2][9]+x[5])204 sage: p.add_constraint(x[3] +y[2][9]+2*x[5],max=2)229 sage: p = MixedIntegerLinearProgram() 230 sage: x = p.new_variable() 231 sage: y = p.new_variable(dim=2) 232 sage: p.set_objective(x[3] + y[2][9] + x[5]) 233 sage: p.add_constraint(x[3] + y[2][9] + 2*x[5], max=2) 205 234 sage: p.solve() # optional - requires Glpk or COIN-OR/CBC 206 235 2.0 207 236 sage: # … … 212 241 sage: # Returns a dictionary identical to x 213 242 sage: # containing values for the corresponding 214 243 sage: # variables 215 sage: x_sol =p.get_values(x)244 sage: x_sol = p.get_values(x) 216 245 sage: x_sol.keys() 217 246 [3, 5] 218 247 sage: # 219 248 sage: # Obviously, it also works with 220 249 sage: # variables of higher dimension 221 sage: y_sol =p.get_values(y)222 sage: # 250 sage: y_sol = p.get_values(y) 251 sage: # 223 252 sage: # We could also have tried : 224 sage: [x_sol, y_sol]=p.get_values(x,y)253 sage: [x_sol, y_sol] = p.get_values(x, y) 225 254 sage: # Or 226 sage: [x_sol, y_sol]=p.get_values([x,y])255 sage: [x_sol, y_sol] = p.get_values([x, y]) 227 256 """ 228 229 val=[] 257 val = [] 230 258 for l in lists: 231 if isinstance(l, MIPVariable):232 if l.depth() ==1:233 c ={}259 if isinstance(l, MIPVariable): 260 if l.depth() == 1: 261 c = {} 234 262 for (k,v) in l.items(): 235 c[k] =self.values[v] if self.values.has_key(v) else None263 c[k] = self.values[v] if self.values.has_key(v) else None 236 264 val.append(c) 237 265 else: 238 c ={}266 c = {} 239 267 for (k,v) in l.items(): 240 c[k] =self.get_values(v)241 val.append(c) 242 elif isinstance(l, list):243 if len(l) ==1:268 c[k] = self.get_values(v) 269 val.append(c) 270 elif isinstance(l, list): 271 if len(l) == 1: 244 272 val.append([self.get_values(l[0])]) 245 273 else: 246 c =[]274 c = [] 247 275 [c.append(self.get_values(ll)) for ll in l] 248 276 val.append(c) 249 277 elif self.variables.has_key(l): 250 278 val.append(self.values[l]) 251 if len(lists) ==1:279 if len(lists) == 1: 252 280 return val[0] 253 281 else: 254 282 return val 255 256 257 283 258 284 def show(self): 259 285 r""" 260 Prints the ``MixedIntegerLinearProgram`` in a human-readable way286 Prints the ``MixedIntegerLinearProgram`` in a human-readable format. 261 287 262 288 EXAMPLE:: 263 289 264 sage: p=MixedIntegerLinearProgram()265 sage: x=p.new_variable()266 sage: p.set_objective(x[1]+x[2])267 sage: p.add_constraint(-3*x[1]+2*x[2],max=2)268 sage: p.show()269 Maximization:270 x2 + x1271 Constraints:272 2.0*x2 - 3.0*x1273 Variables:274 x2 is a real variable (min=0.0,max=+oo)275 x1 is a real variable (min=0.0,max=+oo)290 sage: p = MixedIntegerLinearProgram() 291 sage: x = p.new_variable() 292 sage: p.set_objective(x[1] + x[2]) 293 sage: p.add_constraint(-3*x[1] + 2*x[2], max=2) 294 sage: p.show() 295 Maximization: 296 x2 + x1 297 Constraints: 298 2.0*x2 - 3.0*x1 299 Variables: 300 x2 is a real variable (min=0.0, max=+oo) 301 x1 is a real variable (min=0.0, max=+oo) 276 302 """ 277 303 print self.export(format="text") 278 304 279 305 def set_objective(self,obj): 280 306 r""" 281 307 Sets the objective of the ``MixedIntegerLinearProgram``. 282 308 283 309 INPUT: 284 285 - ``obj`` : A linear function to be optimized286 310 287 EXAMPLE:: 288 289 This code solves the following Linear Program : 290 291 Maximize: 311 - ``obj`` -- A linear function to be optimized. 312 313 EXAMPLE: 314 315 Let's solve the following linear program:: 316 317 Maximize: 292 318 x + 5 * y 293 Constraints:319 Constraints: 294 320 x + 0.2 y <= 4 295 1.5 * x + 3 * y <=4296 Variables:297 x is Real ( min = 0, max = None)298 y is Real ( min = 0, max = None)321 1.5 * x + 3 * y <= 4 322 Variables: 323 x is Real (min = 0, max = None) 324 y is Real (min = 0, max = None) 299 325 300 sage: p=MixedIntegerLinearProgram(sense=1) 301 sage: x=p.new_variable() 302 sage: p.set_objective(x[1]+5*x[2]) 303 sage: p.add_constraint(x[1]+0.2*x[2],max=4) 304 sage: p.add_constraint(1.5*x[1]+3*x[2],max=4) 305 sage: p.solve() # optional - requires Glpk or COIN-OR/CBC 306 6.6666666666666661 307 326 This linear program can be solved as follows:: 327 328 sage: p = MixedIntegerLinearProgram(maximization=True) 329 sage: x = p.new_variable() 330 sage: p.set_objective(x[1] + 5*x[2]) 331 sage: p.add_constraint(x[1] + 0.2*x[2], max=4) 332 sage: p.add_constraint(1.5*x[1]+3*x[2], max=4) 333 sage: p.solve() # optional - requires Glpk or COIN-OR/CBC 334 6.6666666666666661 308 335 """ 309 336 self.objective=obj 310 337 311 def add_constraint(self, linear_function,max=None,min=None):338 def add_constraint(self, linear_function, max=None, min=None): 312 339 r""" 313 Adds a constraint to the ``MixedIntegerLinearProgram`` 314 315 INPUT : 316 317 - ``consraint`` : : A linear function 318 - ``max`` : An upper bound on the constraint ( set to ``None`` by default ) 319 - ``min`` : A lower bound on the constraint 320 321 EXAMPLE:: 322 323 This code solves the following Linear Program : 324 325 Maximize: 326 x + 5 * y 327 Constraints: 328 x + 0.2 y <= 4 329 1.5 * x + 3 * y <=4 330 Variables: 331 x is Real ( min = 0, max = None ) 332 y is Real ( min = 0, max = None ) 333 334 sage: p=MixedIntegerLinearProgram(sense=1) 335 sage: x=p.new_variable() 336 sage: p.set_objective(x[1]+5*x[2]) 337 sage: p.add_constraint(x[1]+0.2*x[2],max=4) 338 sage: p.add_constraint(1.5*x[1]+3*x[2],max=4) 339 sage: p.solve() # optional - requires Glpk or COIN-OR/CBC 340 6.6666666666666661 341 """ 342 343 max=float(max) if max!=None else None 344 min=float(min) if min!=None else None 345 self.constraints.append({"function":linear_function,"min":min, "max":max,"card":len(linear_function.variables())}) 346 347 def set_binary(self,e): 348 r""" 349 Sets a variable or a ``MIPVariable`` as binary 340 Adds a constraint to the ``MixedIntegerLinearProgram``. 350 341 351 342 INPUT: 352 343 353 - ``e`` : An instance of ``MIPVariable`` or one of 354 its elements 344 - ``consraint`` -- A linear function. 345 - ``max`` -- An upper bound on the constraint (set to ``None`` 346 by default). 347 - ``min`` -- A lower bound on the constraint. 348 349 EXAMPLE: 350 351 Consider the following linear program:: 352 353 Maximize: 354 x + 5 * y 355 Constraints: 356 x + 0.2 y <= 4 357 1.5 * x + 3 * y <= 4 358 Variables: 359 x is Real (min = 0, max = None) 360 y is Real (min = 0, max = None) 361 362 This linear program can be solved as follows:: 363 364 sage: p = MixedIntegerLinearProgram(maximization=True) 365 sage: x = p.new_variable() 366 sage: p.set_objective(x[1] + 5*x[2]) 367 sage: p.add_constraint(x[1] + 0.2*x[2], max=4) 368 sage: p.add_constraint(1.5*x[1] + 3*x[2], max=4) 369 sage: p.solve() # optional - requires Glpk or COIN-OR/CBC 370 6.6666666666666661 371 """ 372 max = float(max) if max != None else None 373 min = float(min) if min != None else None 374 self.constraints.append({ 375 "function": linear_function, 376 "min": min, 377 "max": max, 378 "card": len(linear_function.variables()) }) 379 380 def set_binary(self, e): 381 r""" 382 Sets a variable or a ``MIPVariable`` as binary. 383 384 INPUT: 385 386 - ``e`` -- An instance of ``MIPVariable`` or one of 387 its elements. 355 388 356 389 EXAMPLE:: 357 390 358 sage: p=MixedIntegerLinearProgram()359 sage: x=p.new_variable()360 sage: # With the following instruction, all the variables361 sage: # from x will be binary362 sage: p.set_binary(x)363 sage: p.set_objective(x[0]+x[1])364 sage: p.add_constraint(-3*x[0]+2*x[1],max=2)365 sage: #366 sage: # It is still possible, though, to set one of these367 sage: # variable as real while keeping the others as they are368 sage: p.set_real(x[3])391 sage: p = MixedIntegerLinearProgram() 392 sage: x = p.new_variable() 393 sage: # With the following instruction, all the variables 394 sage: # from x will be binary. 395 sage: p.set_binary(x) 396 sage: p.set_objective(x[0] + x[1]) 397 sage: p.add_constraint(-3*x[0] + 2*x[1], max=2) 398 sage: # 399 sage: # It is still possible, though, to set one of these 400 sage: # variables as real while keeping the others as they are. 401 sage: p.set_real(x[3]) 369 402 """ 370 if isinstance(e, MIPVariable):371 e.vtype =self.__BINARY372 if e.depth() ==1:403 if isinstance(e, MIPVariable): 404 e.vtype = self.__BINARY 405 if e.depth() == 1: 373 406 for v in e.values(): 374 self.types[v] =self.__BINARY407 self.types[v] = self.__BINARY 375 408 else: 376 409 for v in e.keys(): 377 410 self.set_binary(e[v]) 378 elif self.variables.has_key(e): 379 self.types[e] =self.__BINARY411 elif self.variables.has_key(e): 412 self.types[e] = self.__BINARY 380 413 else: 381 raise Exception("Wrong kind of variable..")414 raise ValueError("e must be an instance of MIPVariable or one of its elements.") 382 415 383 def is_binary(self, e):416 def is_binary(self, e): 384 417 r""" 385 Tests whether the variable is binary. 386 387 ( Variables are real by default ) 418 Tests whether the variable ``e`` is binary. Variables are real by 419 default. 388 420 389 421 INPUT: 390 422 391 - ``e`` : a variable ( not a ``MIPVariable``, but one of its elements !)423 - ``e`` -- A variable (not a ``MIPVariable``, but one of its elements.) 392 424 393 425 OUTPUT: 394 426 395 ``True`` if the variable is binary, ``False`` otherwise427 ``True`` if the variable ``e`` is binary; ``False`` otherwise. 396 428 397 429 EXAMPLE:: 398 430 399 sage: p =MixedIntegerLinearProgram()400 sage: v =p.new_variable()431 sage: p = MixedIntegerLinearProgram() 432 sage: v = p.new_variable() 401 433 sage: p.set_objective(v[1]) 402 434 sage: p.is_binary(v[1]) 403 435 False 404 sage: p.set_binary(v[1]) 436 sage: p.set_binary(v[1]) 405 437 sage: p.is_binary(v[1]) 406 438 True 407 439 """ 408 # Returns an exception if the variable does not exist. .409 # For ex emple if the userstries to find out the type of410 # a MIPVariable or anything else 440 # Returns an exception if the variable does not exist. 441 # For example if the user tries to find out the type of 442 # a MIPVariable or anything else. 411 443 self.variables[e] 412 413 if self.types.has_key(e) and self.types[e]==self.__BINARY: 444 if self.types.has_key(e) and self.types[e] == self.__BINARY: 414 445 return True 415 446 return False 416 447 417 def set_integer(self, e):448 def set_integer(self, e): 418 449 r""" 419 Sets a variable or a ``MIPVariable`` as integer 450 Sets a variable or a ``MIPVariable`` as integer. 420 451 421 452 INPUT: 422 453 423 - ``e`` : An instance of ``MIPVariable`` or one of 424 its elements 425 454 - ``e`` -- An instance of ``MIPVariable`` or one of 455 its elements. 426 456 427 457 EXAMPLE:: 428 458 429 sage: p=MixedIntegerLinearProgram() 430 sage: x=p.new_variable() 431 sage: # With the following instruction, all the variables 432 sage: # from x will be integers 433 sage: p.set_integer(x) 434 sage: p.set_objective(x[0]+x[1]) 435 sage: p.add_constraint(-3*x[0]+2*x[1],max=2) 436 sage: # 437 sage: # It is still possible, though, to set one of these 438 sage: # variable as real while keeping the others as they are 439 sage: p.set_real(x[3]) 440 459 sage: p = MixedIntegerLinearProgram() 460 sage: x = p.new_variable() 461 sage: # With the following instruction, all the variables 462 sage: # from x will be integers 463 sage: p.set_integer(x) 464 sage: p.set_objective(x[0] + x[1]) 465 sage: p.add_constraint(-3*x[0] + 2*x[1], max=2) 466 sage: # 467 sage: # It is still possible, though, to set one of these 468 sage: # variables as real while keeping the others as they are. 469 sage: p.set_real(x[3]) 441 470 """ 442 if isinstance(e, MIPVariable):443 e.vtype =self.__INTEGER444 if e.depth() ==1:471 if isinstance(e, MIPVariable): 472 e.vtype = self.__INTEGER 473 if e.depth() == 1: 445 474 for v in e.values(): 446 self.types[v] =self.__INTEGER475 self.types[v] = self.__INTEGER 447 476 else: 448 477 for v in e.keys(): 449 478 self.set_integer(e[v]) 450 elif self.variables.has_key(e): 451 self.types[e] =self.__INTEGER479 elif self.variables.has_key(e): 480 self.types[e] = self.__INTEGER 452 481 else: 453 raise Exception("Wrong kind of variable..")482 raise ValueError("e must be an instance of MIPVariable or one of its elements.") 454 483 455 def is_integer(self, e):484 def is_integer(self, e): 456 485 r""" 457 Tests whether the variable is integer. 458 459 ( Variables are real by default ) 486 Tests whether the variable is an integer. Variables are real by 487 default. 460 488 461 489 INPUT: 462 490 463 - ``e`` : a variable ( not a ``MIPVariable``, but one of its elements !)491 - ``e`` -- A variable (not a ``MIPVariable``, but one of its elements.) 464 492 465 493 OUTPUT: 466 494 467 ``True`` if the variable is integer, ``False`` otherwise495 ``True`` if the variable ``e`` is an integer; ``False`` otherwise. 468 496 469 497 EXAMPLE:: 470 498 471 sage: p =MixedIntegerLinearProgram()472 sage: v =p.new_variable()499 sage: p = MixedIntegerLinearProgram() 500 sage: v = p.new_variable() 473 501 sage: p.set_objective(v[1]) 474 502 sage: p.is_integer(v[1]) 475 503 False 476 sage: p.set_integer(v[1]) 504 sage: p.set_integer(v[1]) 477 505 sage: p.is_integer(v[1]) 478 506 True 479 507 """ 480 # Returns an exception if the variable does not exist. .481 # For ex emple if the userstries to find out the type of482 # a MIPVariable or anything else 508 # Returns an exception if the variable does not exist. 509 # For example if the user tries to find out the type of 510 # a MIPVariable or anything else. 483 511 self.variables[e] 484 485 if self.types.has_key(e) and self.types[e]==self.__INTEGER: 512 if self.types.has_key(e) and self.types[e] == self.__INTEGER: 486 513 return True 487 514 return False 488 515 489 516 def set_real(self,e): 490 517 r""" 491 Sets a variable or a ``MIPVariable`` as real 518 Sets a variable or a ``MIPVariable`` as real. 492 519 493 520 INPUT: 494 521 495 - ``e`` :An instance of ``MIPVariable`` or one of496 its elements522 - ``e`` -- An instance of ``MIPVariable`` or one of 523 its elements. 497 524 498 525 EXAMPLE:: 499 526 500 sage: p=MixedIntegerLinearProgram()501 sage: x=p.new_variable()502 sage: # With the following instruction, all the variables503 sage: # from x will be real ( they are by default, though )504 sage: p.set_real(x)505 sage: p.set_objective(x[0]+x[1])506 sage: p.add_constraint(-3*x[0]+2*x[1],max=2)507 sage: #508 sage: # It is still possible, though, to set one of these509 sage: # variable as binary while keeping the others as they are510 sage: p.set_binary(x[3])527 sage: p = MixedIntegerLinearProgram() 528 sage: x = p.new_variable() 529 sage: # With the following instruction, all the variables 530 sage: # from x will be real (they are by default, though). 531 sage: p.set_real(x) 532 sage: p.set_objective(x[0] + x[1]) 533 sage: p.add_constraint(-3*x[0] + 2*x[1], max=2) 534 sage: # 535 sage: # It is still possible, though, to set one of these 536 sage: # variables as binary while keeping the others as they are. 537 sage: p.set_binary(x[3]) 511 538 """ 512 if isinstance(e, MIPVariable):513 e.vtype =self.__REAL514 if e.depth() ==1:539 if isinstance(e, MIPVariable): 540 e.vtype = self.__REAL 541 if e.depth() == 1: 515 542 for v in e.values(): 516 self.types[v] =self.__REAL543 self.types[v] = self.__REAL 517 544 else: 518 545 for v in e.keys(): 519 546 self.set_real(e[v]) 520 elif self.variables.has_key(e): 521 self.types[e] =self.__REAL547 elif self.variables.has_key(e): 548 self.types[e] = self.__REAL 522 549 else: 523 raise Exception("Wrong kind of variable..")550 raise ValueError("e must be an instance of MIPVariable or one of its elements.") 524 551 525 526 def is_real(self,e): 552 def is_real(self, e): 527 553 r""" 528 Tests whether the variable is real. 529 530 ( Variables are real by default ) 554 Tests whether the variable is real. Variables are real by default. 531 555 532 556 INPUT: 533 557 534 - ``e`` : a variable ( not a ``MIPVariable``, but one of its elements !)558 - ``e`` -- A variable (not a ``MIPVariable``, but one of its elements.) 535 559 536 560 OUTPUT: 537 561 538 ``True`` if the variable is real , ``False`` otherwise562 ``True`` if the variable is real; ``False`` otherwise. 539 563 540 564 EXAMPLE:: 541 565 542 sage: p =MixedIntegerLinearProgram()543 sage: v =p.new_variable()566 sage: p = MixedIntegerLinearProgram() 567 sage: v = p.new_variable() 544 568 sage: p.set_objective(v[1]) 545 569 sage: p.is_real(v[1]) 546 570 True 547 571 sage: p.set_binary(v[1]) 548 572 sage: p.is_real(v[1]) 549 573 False 550 sage: p.set_real(v[1]) 574 sage: p.set_real(v[1]) 551 575 sage: p.is_real(v[1]) 552 576 True 553 577 """ 554 555 # Returns an exception if the variable does not exist.. 556 # For exemple if the users tries to find out the type of 557 # a MIPVariable or anything else 578 # Returns an exception if the variable does not exist. 579 # For example if the user tries to find out the type of 580 # a MIPVariable or anything else. 558 581 self.variables[e] 559 560 if (not self.types.has_key(e)) or self.types[e]==self.__REAL: 582 if (not self.types.has_key(e)) or self.types[e] == self.__REAL: 561 583 return True 562 584 return False 563 585 564 565 def solve(self,solver=None,log=False,objective_only=False): 586 def solve(self, solver=None, log=False, objective_only=False): 566 587 r""" 567 Solves the MixedIntegerLinearProgram. 568 569 INPUT : 570 - ``solver`` : 571 3 solvers should be available through this class : 572 - GLPK ( ``solver="GLPK"`` ) 573 http://www.gnu.org/software/glpk/ 574 575 - COIN Branch and Cut ( ``solver="Coin"`` ) 576 COIN-OR http://www.coin-or.org/ 577 If the spkg is installed 578 579 - CPLEX ( ``solver="CPLEX"`` ) 580 http://www.ilog.com/products/cplex/ 581 Not Implemented Yet 582 583 ``solver`` should then be equal to one of ``"GLPK"``, 584 ``"Coin"``, ``"CPLEX"``, or ``None``. 585 If ``solver=None`` ( default ), the default solver is used 586 ( Coin if available, GLPK otherwise ) 587 588 - ``log`` : This boolean variable indicates whether progress should be printed 589 during the computations. 590 591 - ``objective_only`` : Boolean variable 592 * When set to ``True``, only the objective function is returned 593 * When set to ``False`` (default), the optimal 594 numerical values are stored ( takes computational 595 time ) 596 597 OUTPUT : 598 599 The optimal value taken by the objective function 600 601 EXAMPLE : 602 603 This code solves the following Linear Program : 604 605 Maximize: 606 x + 5 * y 607 Constraints: 608 x + 0.2 y <= 4 609 1.5 * x + 3 * y <=4 610 Variables: 611 x is Real ( min = 0, max = None ) 612 y is Real ( min = 0, max = None ) 613 614 :: 615 616 sage: p=MixedIntegerLinearProgram(sense=1) 617 sage: x=p.new_variable() 618 sage: p.set_objective(x[1]+5*x[2]) 619 sage: p.add_constraint(x[1]+0.2*x[2],max=4) 620 sage: p.add_constraint(1.5*x[1]+3*x[2],max=4) 621 sage: p.solve() # optional - requires Glpk or COIN-OR/CBC 622 6.6666666666666661 623 sage: p.get_values(x) # optional - requires Glpk or COIN-OR/CBC 624 {1: 0.0, 2: 1.3333333333333333} 625 626 sage: ### Computation of a maximum stable set in Petersen's graph ### 627 sage: g=graphs.PetersenGraph() 628 sage: p=MixedIntegerLinearProgram(sense=1) 629 sage: b=p.new_variable() 630 sage: p.set_objective(sum([b[v] for v in g])) 631 sage: for (u,v) in g.edges(labels=None): 632 ... p.add_constraint(b[u]+b[v],max=1) 633 sage: p.set_binary(b) 634 sage: p.solve(objective_only=True) # optional - requires Glpk or COIN-OR/CBC 635 4.0 636 """ 637 638 if self.objective==None: 639 raise Exception("No objective function has been defined !") 640 641 if solver==None: 642 solver=self.default_solver 643 644 if solver==None: 645 raise Exception("There does not seem to be any solver installed...\n Please visit http://www.sagemath.org/doc/tutorial/tour_LP.html for more informations") 646 elif solver=="Coin": 647 try: 648 from sage.numerical.mipCoin import solveCoin 649 except: 650 raise NotImplementedError("Coin/CBC is not installed and cannot be used to solve this MixedIntegerLinearProgram\n To install it, you can type in Sage : sage: install_package('cbc')") 651 return solveCoin(self,log=log,objective_only=objective_only) 652 653 elif solver=="GLPK": 654 try: 655 from sage.numerical.mipGlpk import solveGlpk 656 except: 657 raise NotImplementedError("GLPK is not installed and cannot be used to solve this MixedIntegerLinearProgram\n To install it, you can type in Sage : sage: install_package('glpk')") 658 return solveGlpk(self,log=log,objective_only=objective_only) 659 elif solver=="CPLEX": 660 raise NotImplementedError("The support for CPLEX is not written yet... We're seriously thinking about it, though ;-)") 661 else: 662 raise NotImplementedError("solver should be set to 'GLPK', 'Coin', 'CPLEX' or None (in which case the default one is used).") 663 664 665 def _NormalForm(self,exp): 666 r""" 667 Returns a dictionary built from the linear function 588 Solves the ``MixedIntegerLinearProgram``. 668 589 669 590 INPUT: 670 591 671 - ``exp`` : The expression representing a linear function 592 - ``solver`` -- 3 solvers should be available through this class: 593 594 - GLPK (``solver="GLPK"``). See the 595 `GLPK <http://www.gnu.org/software/glpk/>`_ web site. 596 597 - COIN Branch and Cut (``solver="Coin"``). See the 598 `COIN-OR <http://www.coin-or.org>`_ web site. 599 600 - CPLEX (``solver="CPLEX"``). See the 601 `CPLEX <http://www.ilog.com/products/cplex/>`_ web site. 602 An interface to CPLEX is not yet implemented. 603 604 ``solver`` should then be equal to one of ``"GLPK"``, ``"Coin"``, 605 ``"CPLEX"``, or ``None``. If ``solver=None`` (default), the default 606 solver is used (COIN if available, GLPK otherwise). 607 608 - ``log`` -- This boolean variable indicates whether progress should 609 be printed during the computations. 610 611 - ``objective_only`` -- Boolean variable. 612 613 - When set to ``True``, only the objective function is returned. 614 - When set to ``False`` (default), the optimal numerical values 615 are stored (takes computational time). 672 616 673 617 OUTPUT: 674 618 675 A dictionary whose keys are the id of the variables, and whose 676 values are their coefficients. 677 The value corresponding to key `-1` is the constant coefficient 619 The optimal value taken by the objective function. 620 621 EXAMPLES: 622 623 Consider the following linear program:: 624 625 Maximize: 626 x + 5 * y 627 Constraints: 628 x + 0.2 y <= 4 629 1.5 * x + 3 * y <= 4 630 Variables: 631 x is Real (min = 0, max = None) 632 y is Real (min = 0, max = None) 633 634 This linear program can be solved as follows:: 635 636 sage: p = MixedIntegerLinearProgram(maximization=True) 637 sage: x = p.new_variable() 638 sage: p.set_objective(x[1] + 5*x[2]) 639 sage: p.add_constraint(x[1] + 0.2*x[2], max=4) 640 sage: p.add_constraint(1.5*x[1] + 3*x[2], max=4) 641 sage: p.solve() # optional - requires Glpk or COIN-OR/CBC 642 6.6666666666666661 643 sage: p.get_values(x) # optional - requires Glpk or COIN-OR/CBC 644 {1: 0.0, 2: 1.3333333333333333} 645 646 sage: ### Computation of a maximum stable set in Petersen's graph 647 sage: g = graphs.PetersenGraph() 648 sage: p = MixedIntegerLinearProgram(maximization=True) 649 sage: b = p.new_variable() 650 sage: p.set_objective(sum([b[v] for v in g])) 651 sage: for (u,v) in g.edges(labels=None): 652 ... p.add_constraint(b[u] + b[v], max=1) 653 sage: p.set_binary(b) 654 sage: p.solve(objective_only=True) # optional - requires Glpk or COIN-OR/CBC 655 4.0 656 """ 657 if self.objective == None: 658 raise ValueError("No objective function has been defined.") 659 660 if solver == None: 661 solver = self.default_solver 662 663 if solver == None: 664 raise ValueError("There does not seem to be any solver installed. Please visit http://www.sagemath.org/doc/tutorial/tour_LP.html for more informations.") 665 elif solver == "Coin": 666 try: 667 from sage.numerical.mipCoin import solveCoin 668 except: 669 raise NotImplementedError("Coin/CBC is not installed and cannot be used to solve this MixedIntegerLinearProgram. To install it, you can type in Sage: install_package('cbc')") 670 return solveCoin(self, log=log, objective_only=objective_only) 671 elif solver == "GLPK": 672 try: 673 from sage.numerical.mipGlpk import solveGlpk 674 except: 675 raise NotImplementedError("GLPK is not installed and cannot be used to solve this MixedIntegerLinearProgram. To install it, you can type in Sage: install_package('glpk')") 676 return solveGlpk(self, log=log, objective_only=objective_only) 677 elif solver == "CPLEX": 678 raise NotImplementedError("The support for CPLEX is not implemented yet.") 679 else: 680 raise NotImplementedError("'solver' should be set to 'GLPK', 'Coin', 'CPLEX' or None (in which case the default one is used).") 681 682 def _NormalForm(self, exp): 683 r""" 684 Returns a dictionary built from the linear function. 685 686 INPUT: 687 688 - ``exp`` -- The expression representing a linear function. 689 690 OUTPUT: 691 692 A dictionary whose keys are the IDs of the variables and whose 693 values are their coefficients. The value corresponding to key 694 `-1` is the constant coefficient. 678 695 679 696 EXAMPLE:: 680 697 681 sage: p =MixedIntegerLinearProgram()682 sage: v =p.new_variable()683 sage: p._NormalForm(v[0] +v[1])698 sage: p = MixedIntegerLinearProgram() 699 sage: v = p.new_variable() 700 sage: p._NormalForm(v[0] + v[1]) 684 701 {1: 1.0, 2: 1.0, -1: 0.0} 685 702 """ 686 d=dict(zip([self.variables[v] for v in exp.variables()],exp.coefficients())) 687 d[-1]=exp.constant_coefficient() 703 d = dict( zip([self.variables[v] for v in exp.variables()], 704 exp.coefficients()) ) 705 d[-1] = exp.constant_coefficient() 688 706 return d 689 707 690 def _add_element_to_ring(self, vtype):708 def _add_element_to_ring(self, vtype): 691 709 r""" 692 Creates a new variable from the main ``InfinitePolynomialRing`` 710 Creates a new variable from the main ``InfinitePolynomialRing``. 711 712 INPUT: 713 714 - ``vtype`` (integer) -- Defines the type of the variables 715 (default is ``REAL``). 693 716 694 717 OUTPUT: 695 718 696 - The newly created variable 719 - The newly created variable. 697 720 698 721 EXAMPLE:: 699 722 700 sage: p =MixedIntegerLinearProgram()701 sage: v =p.new_variable()723 sage: p = MixedIntegerLinearProgram() 724 sage: v = p.new_variable() 702 725 sage: p.count 703 726 0 704 727 sage: p._add_element_to_ring(p.__REAL) … … 706 729 sage: p.count 707 730 1 708 731 """ 709 self.count +=1710 v =self.x[self.count]711 self.variables[v] =self.count712 self.types[v] =vtype713 self.min[v] =0.0732 self.count += 1 733 v = self.x[self.count] 734 self.variables[v] = self.count 735 self.types[v] = vtype 736 self.min[v] = 0.0 714 737 return v 715 738 716 def set_min(self, v,min):739 def set_min(self, v, min): 717 740 r""" 718 Sets the minimum value of a variable 741 Sets the minimum value of a variable. 719 742 720 INPUT 743 INPUT: 721 744 722 - ``v`` : a variable ( not a ``MIPVariable``, but one of its elements ! ) 723 - ``min`` : the minimum value the variable can take 724 when ``min=None``, the variable has no lower bound 745 - ``v`` -- a variable (not a ``MIPVariable``, but one of its 746 elements). 747 - ``min`` -- the minimum value the variable can take. 748 When ``min=None``, the variable has no lower bound. 725 749 726 750 EXAMPLE:: 727 751 728 sage: p =MixedIntegerLinearProgram()729 sage: v =p.new_variable()752 sage: p = MixedIntegerLinearProgram() 753 sage: v = p.new_variable() 730 754 sage: p.set_objective(v[1]) 731 755 sage: p.get_min(v[1]) 732 756 0.0 … … 734 758 sage: p.get_min(v[1]) 735 759 6.0 736 760 """ 737 self.min[v] =min761 self.min[v] = min 738 762 739 def set_max(self, v,max):763 def set_max(self, v, max): 740 764 r""" 741 Sets the maximum value of a variable 765 Sets the maximum value of a variable. 742 766 743 767 INPUT 744 768 745 - ``v`` : a variable ( not a ``MIPVariable``, but one of its elements ! ) 746 - ``max`` : the maximum value the variable can take 747 when ``max=None``, the variable has no upper bound 769 - ``v`` -- a variable (not a ``MIPVariable``, but one of its 770 elements). 771 - ``max`` -- the maximum value the variable can take. 772 When ``max=None``, the variable has no upper bound. 748 773 749 774 EXAMPLE:: 750 775 751 sage: p =MixedIntegerLinearProgram()752 sage: v =p.new_variable()776 sage: p = MixedIntegerLinearProgram() 777 sage: v = p.new_variable() 753 778 sage: p.set_objective(v[1]) 754 779 sage: p.get_max(v[1]) 755 780 sage: p.set_max(v[1],6) 756 781 sage: p.get_max(v[1]) 757 782 6.0 758 783 """ 759 self.max[v] =max784 self.max[v] = max 760 785 786 def get_min(self, v): 787 r""" 788 Returns the minimum value of a variable. 761 789 762 def get_min(self,v): 763 r""" 764 Returns the minimum value of a variable 790 INPUT: 765 791 766 INPUT792 - ``v`` -- a variable (not a ``MIPVariable``, but one of its elements). 767 793 768 - ``v`` a variable ( not a ``MIPVariable``, but one of its elements ! )794 OUTPUT: 769 795 770 OUTPUT 771 772 Minimum value of the variable, or ``None`` is 773 the variable has no lower bound 796 Minimum value of the variable, or ``None`` if 797 the variable has no lower bound. 774 798 775 799 EXAMPLE:: 776 800 777 sage: p =MixedIntegerLinearProgram()778 sage: v =p.new_variable()801 sage: p = MixedIntegerLinearProgram() 802 sage: v = p.new_variable() 779 803 sage: p.set_objective(v[1]) 780 804 sage: p.get_min(v[1]) 781 805 0.0 … … 785 809 """ 786 810 return float(self.min[v]) if self.min.has_key(v) else None 787 811 788 def get_max(self, v):812 def get_max(self, v): 789 813 r""" 790 Returns the maximum value of a variable 814 Returns the maximum value of a variable. 791 815 792 INPUT 816 INPUT: 793 817 794 - ``v`` a variable ( not a ``MIPVariable``, but one of its elements ! )818 - ``v`` -- a variable (not a ``MIPVariable``, but one of its elements). 795 819 796 OUTPUT 820 OUTPUT: 797 821 798 Maximum value of the variable, or ``None`` i s799 the variable has no upper bound 822 Maximum value of the variable, or ``None`` if 823 the variable has no upper bound. 800 824 801 825 EXAMPLE:: 802 826 803 sage: p =MixedIntegerLinearProgram()804 sage: v =p.new_variable()827 sage: p = MixedIntegerLinearProgram() 828 sage: v = p.new_variable() 805 829 sage: p.set_objective(v[1]) 806 830 sage: p.get_max(v[1]) 807 831 sage: p.set_max(v[1],6) … … 812 836 813 837 class MIPSolverException(Exception): 814 838 r""" 815 Exception raised when the solver fails 839 Exception raised when the solver fails. 816 840 """ 841 817 842 def __init__(self, value): 818 843 r""" 819 Constructor for ``MIPSolverException`` 844 Constructor for ``MIPSolverException``. 820 845 821 ``MIPSolverException`` is the exception raised when the solver fails 846 ``MIPSolverException`` is the exception raised when the solver fails. 822 847 823 848 EXAMPLE:: 824 849 825 850 sage: MIPSolverException("Error") 826 851 MIPSolverException() 827 828 852 """ 829 853 self.value = value 854 830 855 def __str__(self): 831 856 r""" 832 Returns the value of the instance of ``MIPSolverException` `857 Returns the value of the instance of ``MIPSolverException``. 833 858 834 859 EXAMPLE:: 835 860 836 sage: e =MIPSolverException("Error")861 sage: e = MIPSolverException("Error") 837 862 sage: print e 838 863 'Error' 839 864 """ 840 865 return repr(self.value) 841 866 842 867 class MIPVariable: 843 r""" 844 ``MIPVariable`` is a variable used by the class ``MixedIntegerLinearProgram`` 845 """ 846 def __init__(self,p,vtype,dim=1): 847 r""" 848 Constructor for ``MIPVariable`` 868 r""" 869 ``MIPVariable`` is a variable used by the class 870 ``MixedIntegerLinearProgram``. 871 """ 849 872 850 INPUT: 873 def __init__(self, p, vtype, dim=1): 874 r""" 875 Constructor for ``MIPVariable``. 851 876 852 - ``p`` is the instance of ``MixedIntegerLinearProgram`` to which the 853 variable is to be linked. 854 - ``dim`` is the integer defining the definition of the variable 877 INPUT: 855 878 856 For more informations, see method ``MixedIntegerLinearProgram.new_variable`` 879 - ``p`` -- the instance of ``MixedIntegerLinearProgram`` to which the 880 variable is to be linked. 881 - ``vtype`` (integer) -- Defines the type of the variables 882 (default is ``REAL``). 883 - ``dim`` -- the integer defining the definition of the variable. 857 884 858 EXAMPLE:: 885 For more informations, see the method 886 ``MixedIntegerLinearProgram.new_variable``. 887 888 EXAMPLE:: 859 889 860 890 sage: p=MixedIntegerLinearProgram() 861 891 sage: v=p.new_variable() 862 863 864 """ 865 self.dim=dim 866 self.dict={} 867 self.p=p 868 self.vtype=vtype 892 """ 893 self.dim = dim 894 self.dict = {} 895 self.p = p 896 self.vtype = vtype 869 897 870 def __getitem__(self,i):871 872 Returns the symbolic variable corresponding to the key898 def __getitem__(self, i): 899 r""" 900 Returns the symbolic variable corresponding to the key. 873 901 874 875 ( When depth>1, recursively creates the variables )902 Returns the element asked, otherwise creates it. 903 (When depth>1, recursively creates the variables). 876 904 877 905 EXAMPLE:: 878 906 879 sage: p=MixedIntegerLinearProgram() 880 sage: v=p.new_variable() 881 sage: p.set_objective(v[0]+v[1]) 882 sage: v[0] 883 x1 884 """ 885 if self.dict.has_key(i): 886 return self.dict[i] 887 elif self.dim==1: 888 self.dict[i]=self.p._add_element_to_ring(self.vtype) 889 return self.dict[i] 890 else: 891 self.dict[i]=MIPVariable(self.p,self.vtype,dim=self.dim-1) 892 return self.dict[i] 893 def keys(self): 894 r""" 895 Returns the keys already defined in the dictionary 907 sage: p = MixedIntegerLinearProgram() 908 sage: v = p.new_variable() 909 sage: p.set_objective(v[0] + v[1]) 910 sage: v[0] 911 x1 912 """ 913 if self.dict.has_key(i): 914 return self.dict[i] 915 elif self.dim == 1: 916 self.dict[i] = self.p._add_element_to_ring(self.vtype) 917 return self.dict[i] 918 else: 919 self.dict[i] = MIPVariable(self.p, self.vtype, dim=self.dim-1) 920 return self.dict[i] 896 921 897 EXAMPLE:: 922 def keys(self): 923 r""" 924 Returns the keys already defined in the dictionary. 898 925 899 sage: p=MixedIntegerLinearProgram() 900 sage: v=p.new_variable() 901 sage: p.set_objective(v[0]+v[1]) 902 sage: v.keys() 903 [0, 1] 904 """ 905 return self.dict.keys() 906 def items(self): 907 r""" 908 Returns the pairs (keys,value) contained in the dictionary 926 EXAMPLE:: 909 927 910 EXAMPLE:: 928 sage: p = MixedIntegerLinearProgram() 929 sage: v = p.new_variable() 930 sage: p.set_objective(v[0] + v[1]) 931 sage: v.keys() 932 [0, 1] 933 """ 934 return self.dict.keys() 911 935 912 sage: p=MixedIntegerLinearProgram() 913 sage: v=p.new_variable() 914 sage: p.set_objective(v[0]+v[1]) 915 sage: v.items() 916 [(0, x1), (1, x2)] 917 """ 918 return self.dict.items() 919 def depth(self): 920 r""" 921 Returns the current variable's depth 936 def items(self): 937 r""" 938 Returns the pairs (keys,value) contained in the dictionary. 922 939 923 940 EXAMPLE:: 924 941 925 sage: p=MixedIntegerLinearProgram() 926 sage: v=p.new_variable() 927 sage: p.set_objective(v[0]+v[1]) 928 sage: v.depth() 929 1 930 """ 931 return self.dim 932 def values(self): 933 r""" 934 Returns the symbolic variables associated to the current dictionary 942 sage: p = MixedIntegerLinearProgram() 943 sage: v = p.new_variable() 944 sage: p.set_objective(v[0] + v[1]) 945 sage: v.items() 946 [(0, x1), (1, x2)] 947 """ 948 return self.dict.items() 935 949 936 EXAMPLE:: 950 def depth(self): 951 r""" 952 Returns the current variable's depth. 937 953 938 sage: p=MixedIntegerLinearProgram() 939 sage: v=p.new_variable() 940 sage: p.set_objective(v[0]+v[1]) 941 sage: v.values() 942 [x1, x2] 943 """ 944 return self.dict.values() 954 EXAMPLE:: 945 955 956 sage: p = MixedIntegerLinearProgram() 957 sage: v = p.new_variable() 958 sage: p.set_objective(v[0] + v[1]) 959 sage: v.depth() 960 1 961 """ 962 return self.dim 946 963 964 def values(self): 965 r""" 966 Returns the symbolic variables associated to the current dictionary. 967 968 EXAMPLE:: 969 970 sage: p = MixedIntegerLinearProgram() 971 sage: v = p.new_variable() 972 sage: p.set_objective(v[0] + v[1]) 973 sage: v.values() 974 [x1, x2] 975 """ 976 return self.dict.values()