# Ticket #7012: trac_7012.patch

File trac_7012.patch, 34.0 KB (added by ncohen, 11 years ago)
• ## sage/numerical/knapsack.py

```# HG changeset patch
# User Nathann Cohen <nathann.cohen@gmail.com>
# Date 1254129856 25200
# Node ID 654a9e739eb27b7233b0230a597831d597f87c94
# Parent  50100c42b09396988e53fbc2ec0c48a36956c83e
Numerical.mip Class : functions renamed, typos, several docstring fixes, bugfixes...

diff -r 50100c42b093 -r 654a9e739eb2 sage/numerical/knapsack.py```
 a if reals: seq=[(x,1) for x in seq] from sage.numerical.mip import MIP p=MIP(sense=1) present=p.newvar() p.setobj(sum([present[i]*seq[i][1] for i in range(len(seq))])) p.addconstraint(sum([present[i]*seq[i][0] for i in range(len(seq))]),max=max) from sage.numerical.mip import MixedIntegerLinearProgram p=MixedIntegerLinearProgram(sense=1) present=p.new_variable() p.set_objective(sum([present[i]*seq[i][1] for i in range(len(seq))])) p.add_constraint(sum([present[i]*seq[i][0] for i in range(len(seq))]),max=max) if binary: p.setbinary(present) p.set_binary(present) else: p.setinteger(present) p.set_integer(present) if value_only: return p.solve(objective_only=True)
• ## sage/numerical/mip.pyx

`diff -r 50100c42b093 -r 654a9e739eb2 sage/numerical/mip.pyx`
 a include '../ext/stdsage.pxi' class MIP: class MixedIntegerLinearProgram: r""" The MIP class is the link between SAGE and LP ( Linear Program ) and The ``MixedIntegerLinearProgram`` class is the link between SAGE and LP ( Linear Program ) and MIP ( Mixed Integer Program ) Solvers. Cf : http://en.wikipedia.org/wiki/Linear_programming It consists of variables, linear constraints on these variables, and an objective function which is to be maximised or minimised under these constraints. An instance of ``MIP`` also requires the information An instance of ``MixedIntegerLinearProgram`` also requires the information on the direction of the optimization : A ``MIP`` ( or ``LP`` ) is defined as a maximization A ``MixedIntegerLinearProgram`` ( or ``LP`` ) is defined as a maximization if ``sense=1``, and is a minimization if ``sense=-1`` INPUT: - ``sense'' : * When set to `1` (default), the ``MIP`` is defined as a Maximization * When set to `-1`, the ``MIP`` is defined as a Minimization - ``sense`` : * When set to `1` (default), the ``MixedIntegerLinearProgram`` is defined as a Maximization * When set to `-1`, the ``MixedIntegerLinearProgram`` is defined as a Minimization EXAMPLES:: sage: ### Computation of a maximum stable set in Petersen's graph ### sage: g=graphs.PetersenGraph() sage: p=MIP(sense=1) sage: b=p.newvar() sage: p.setobj(sum([b[v] for v in g])) sage: p=MixedIntegerLinearProgram(sense=1) sage: b=p.new_variable() sage: p.set_objective(sum([b[v] for v in g])) sage: for (u,v) in g.edges(labels=None): ...       p.addconstraint(b[u]+b[v],max=1) sage: p.setbinary(b) ...       p.add_constraint(b[u]+b[v],max=1) sage: p.set_binary(b) sage: p.solve(objective_only=True)     # optional - requires Glpk or COIN-OR/CBC 4.0 """ def __init__(self,sense=1): r""" Constructor for the MIP class Constructor for the ``MixedIntegerLinearProgram`` class INPUT: - ``sense'' : When set to 1, the MIP is defined as a Maximization When set to -1, the MIP is defined as a Minimization - ``sense`` : When set to 1, the MixedIntegerLinearProgram is defined as a Maximization When set to -1, the MixedIntegerLinearProgram is defined as a Minimization EXAMPLE: EXAMPLE:: sage: p=MIP(sense=1) sage: p=MixedIntegerLinearProgram(sense=1) """ try: P = InfinitePolynomialRing(RR(), names=('x',)); (self.x,) = P._first_ngens(1) self.count=[0] # number of variables self.count=0 self.sense=sense self.objective=None self.variables={} self.constraints=[] #constains the min and max bounds on the variables self.min={} self.max={} # constains the variables types self.types={} #constains the variables' values when solve(objective_only=False) is called self.values={} # Several constants self.__BINARY=1 self.__REAL=-1 self.__INTEGER=0 def __repr__(self): r""" Returns a short description of the MIP Returns a short description of the MixedIntegerLinearProgram EXAMPLE: EXAMPLE:: sage: p=MIP() sage: v=p.newvar() sage: p.addconstraint(v[1]+v[2],max=2) sage: p=MixedIntegerLinearProgram() sage: v=p.new_variable() sage: p.add_constraint(v[1]+v[2],max=2) sage: print p Mixed Integer Program ( maximization, 2 variables, 1 constraints ) """ return "Mixed Integer Program ( "+("maximization" if self.sense==1 else "minimization")+", "+str(len(self.variables))+" variables, "+str(len(self.constraints))+" constraints )" def newvar(self,dim=1): def new_variable(self,vtype=-1,dim=1): r""" Returns an instance of ``MIPVariable`` associated to the current instance of ``MIP``. to the current instance of ``MixedIntegerLinearProgram``. A new ``MIP`` variable ``x`` defined by ::: A new variable ``x`` is defined by ::: sage: p=MIP() sage: x=p.newvar() sage: p=MixedIntegerLinearProgram() sage: x=p.new_variable() It behaves exactly as an usual dictionary would. It can use any key It behaves exactly as a usual dictionary would. It can use any key argument you may like, as ``x[5]`` or ``x["b"]``, and has methods ``items()`` and ``keys()`` - ``dim`` ( integer ) : Defines the dimension of the dictionary If ``x`` has dimension `2`, its fields will be of the form ``x[key1][key2]`` - ``vtype`` ( integer ) : Defines the type of the variables ( default is Real ) EXAMPLE:: sage: p=MIP() sage: x=p.newvar() sage: y=p.newvar(dim=2) sage: p.addconstraint(x[2]+y[3][5],max=2) sage: p=MixedIntegerLinearProgram() sage: # available types are p.__REAL, p.__INTEGER and p.__BINARY sage: x=p.new_variable(vtype=p.__REAL) sage: y=p.new_variable(dim=2) sage: p.add_constraint(x[2]+y[3][5],max=2) """ return MIPVariable(self.x,self._addElementToRing,dim=dim) return MIPVariable(self,vtype,dim=dim) def export(self,format="text"): r""" Exports the MIP to a string in different formats. Exports the ``MixedIntegerLinearProgram`` to a string in different formats. INPUT: - ``format'' : - ``format`` : "text" : human-readable format sage: p=MIP() sage: x=p.newvar() sage: p.setobj(x[1]+x[2]) sage: p.addconstraint(-3*x[1]+2*x[2],max=2) sage: p=MixedIntegerLinearProgram() sage: x=p.new_variable() sage: p.set_objective(x[1]+x[2]) sage: p.add_constraint(-3*x[1]+2*x[2],max=2) sage: print p.export(format="text") Maximization : x2 + x1 value=value+"\nVariables :" for v in self.variables.keys(): value=value+"\n  "+str(v)+" is" if self.isinteger(v): if self.is_integer(v): value=value+" an integer variable" elif self.isbinary(v): elif self.is_binary(v): value=value+" an boolean variable" else: value=value+" a real variable" value+=" (min="+(str(self.getmin(v)) if self.getmin(v)!= None else "-oo")+",max="+(str(self.getmax(v)) if self.getmax(v)!= None else "+oo")+")" 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")+")" return value def get_values(self,*lists): EXAMPLE:: sage: p=MIP() sage: x=p.newvar() sage: y=p.newvar(dim=2) sage: p.setobj(x[3]+y[2][9]+x[5]) sage: p.addconstraint(x[3]+y[2][9]+2*x[5],max=2) sage: p=MixedIntegerLinearProgram() sage: x=p.new_variable() sage: y=p.new_variable(dim=2) sage: p.set_objective(x[3]+y[2][9]+x[5]) sage: p.add_constraint(x[3]+y[2][9]+2*x[5],max=2) sage: p.solve() # optional - requires Glpk or COIN-OR/CBC 2.0 sage: # sage: # Returns the optimal value of x[3] sage: p.get_values(x[3]) # optional - requires Glpk or COIN-OR/CBC 0.0 2.0 sage: # sage: # Returns a dictionary identical to x sage: # containing values for the corresponding def show(self): r""" Prints the MIP in a human-readable way Prints the ``MixedIntegerLinearProgram`` in a human-readable way EXAMPLE: EXAMPLE:: sage: p=MIP() sage: x=p.newvar() sage: p.setobj(x[1]+x[2]) sage: p.addconstraint(-3*x[1]+2*x[2],max=2) sage: p=MixedIntegerLinearProgram() sage: x=p.new_variable() sage: p.set_objective(x[1]+x[2]) sage: p.add_constraint(-3*x[1]+2*x[2],max=2) sage: p.show() Maximization : x2 + x1 """ print self.export(format="text") #Ok def setobj(self,obj): def set_objective(self,obj): r""" Sets the objective of the ``MIP``. Sets the objective of the ``MixedIntegerLinearProgram``. INPUT: x is Real ( min = 0, max = None ) y is Real ( min = 0, max = None ) sage: p=MIP(sense=1) sage: x=p.newvar() sage: p.setobj(x[1]+5*x[2]) sage: p.addconstraint(x[1]+0.2*x[2],max=4) sage: p.addconstraint(1.5*x[1]+3*x[2],max=4) sage: p=MixedIntegerLinearProgram(sense=1) sage: x=p.new_variable() sage: p.set_objective(x[1]+5*x[2]) sage: p.add_constraint(x[1]+0.2*x[2],max=4) sage: p.add_constraint(1.5*x[1]+3*x[2],max=4) sage: p.solve()     # optional - requires Glpk or COIN-OR/CBC 6.6666666666666661 """ self.objective=obj def addconstraint(self,linear_function,max=None,min=None): def add_constraint(self,linear_function,max=None,min=None): r""" Adds a constraint to the MIP Adds a constraint to the ``MixedIntegerLinearProgram`` INPUT : x is Real ( min = 0, max = None ) y is Real ( min = 0, max = None ) sage: p=MIP(sense=1) sage: x=p.newvar() sage: p.setobj(x[1]+5*x[2]) sage: p.addconstraint(x[1]+0.2*x[2],max=4) sage: p.addconstraint(1.5*x[1]+3*x[2],max=4) sage: p=MixedIntegerLinearProgram(sense=1) sage: x=p.new_variable() sage: p.set_objective(x[1]+5*x[2]) sage: p.add_constraint(x[1]+0.2*x[2],max=4) sage: p.add_constraint(1.5*x[1]+3*x[2],max=4) sage: p.solve()     # optional - requires Glpk or COIN-OR/CBC 6.6666666666666661 """ min=float(min) if min!=None else None self.constraints.append({"function":linear_function,"min":min, "max":max,"card":len(linear_function.variables())}) def setbinary(self,e): def set_binary(self,e): r""" Sets a variable or a ``MIPVariable`` as binary - ``e`` : An instance of ``MIPVariable`` or one of its elements NOTE: EXAMPLE:: We recommend you to define the types of your variables after your problem has been completely defined ( see example ) EXAMPLE: sage: p=MIP() sage: x=p.newvar() sage: p=MixedIntegerLinearProgram() sage: x=p.new_variable() sage: # With the following instruction, all the variables sage: # from x will be binary sage: p.set_binary(x) sage: p.set_objective(x[0]+x[1]) sage: p.add_constraint(-3*x[0]+2*x[1],max=2) sage: # sage: # The following instruction does absolutely nothing sage: # as none of the variables of x have been used yet sage: p.setbinary(x) sage: p.setobj(x[0]+x[1]) sage: p.addconstraint(-3*x[0]+2*x[1],max=2) sage: # sage: # This instructions sets x[0] and x[1] sage: # as binary variables sage: p.setbinary(x) sage: p.addconstraint(x[3]+x[2],max=2) sage: # sage: # x[3] is not set as binary sage: # as no setbinary(x) has been called sage: # after its first definition sage: # sage: # Now it is done sage: p.setbinary(x[3]) sage: # It is still possible, though, to set one of these sage: # variable as real while keeping the others as they are sage: p.set_real(x[3]) """ if isinstance(e,MIPVariable): e.vtype=self.__BINARY if e.depth()==1: for v in e.values(): self.types[v]=self.__BINARY else: for v in e.keys(): self.setbinary(e[v]) self.set_binary(e[v]) elif self.variables.has_key(e): self.types[e]=self.__BINARY else: raise Exception("Wrong kind of variable..") def isbinary(self,e): def is_binary(self,e): r""" Tests whether the variable is binary. ``True`` if the variable is binary, ``False`` otherwise EXAMPLE: EXAMPLE:: sage: p=MIP() sage: v=p.newvar() sage: p.setobj(v[1]) sage: p.isbinary(v[1]) sage: p=MixedIntegerLinearProgram() sage: v=p.new_variable() sage: p.set_objective(v[1]) sage: p.is_binary(v[1]) False sage: p.setbinary(v[1]) sage: p.isbinary(v[1]) sage: p.set_binary(v[1]) sage: p.is_binary(v[1]) True """ # Returns an exception if the variable does not exist.. return True return False def setinteger(self,e): def set_integer(self,e): r""" Sets a variable or a ``MIPVariable`` as integer - ``e`` : An instance of ``MIPVariable`` or one of its elements NOTE: We recommend you to define the types of your variables after your problem has been completely defined ( see example ) EXAMPLE:: EXAMPLE: sage: p=MixedIntegerLinearProgram() sage: x=p.new_variable() sage: # With the following instruction, all the variables sage: # from x will be integers sage: p.set_integer(x) sage: p.set_objective(x[0]+x[1]) sage: p.add_constraint(-3*x[0]+2*x[1],max=2) sage: # sage: # It is still possible, though, to set one of these sage: # variable as real while keeping the others as they are sage: p.set_real(x[3]) sage: p=MIP() sage: x=p.newvar() sage: # sage: # The following instruction does absolutely nothing sage: # as none of the variables of x have been used yet sage: p.setinteger(x) sage: p.setobj(x[0]+x[1]) sage: p.addconstraint(-3*x[0]+2*x[1],max=2) sage: # sage: # This instructions sets x[0] and x[1] sage: # as integer variables sage: p.setinteger(x) sage: p.addconstraint(x[3]+x[2],max=2) sage: # sage: # x[3] is not set as integer sage: # as no setinteger(x) has been called sage: # after its first definition sage: # sage: # Now it is done sage: p.setinteger(x[3]) """ if isinstance(e,MIPVariable): e.vtype=self.__INTEGER if e.depth()==1: for v in e.values(): self.types[v]=self.__INTEGER else: for v in e.keys(): self.setbinary(e[v]) self.set_integer(e[v]) elif self.variables.has_key(e): self.types[e]=self.__INTEGER else: raise Exception("Wrong kind of variable..") def isinteger(self,e): def is_integer(self,e): r""" Tests whether the variable is integer. ``True`` if the variable is integer, ``False`` otherwise EXAMPLE: EXAMPLE:: sage: p=MIP() sage: v=p.newvar() sage: p.setobj(v[1]) sage: p.isinteger(v[1]) sage: p=MixedIntegerLinearProgram() sage: v=p.new_variable() sage: p.set_objective(v[1]) sage: p.is_integer(v[1]) False sage: p.setinteger(v[1]) sage: p.isinteger(v[1]) sage: p.set_integer(v[1]) sage: p.is_integer(v[1]) True """ # Returns an exception if the variable does not exist.. return True return False def setreal(self,e): def set_real(self,e): r""" Sets a variable or a ``MIPVariable`` as real - ``e`` : An instance of ``MIPVariable`` or one of its elements NOTE: EXAMPLE:: We recommend you to define the types of your variables after your problem has been completely defined ( see example ) EXAMPLE: sage: p=MIP() sage: x=p.newvar() sage: p=MixedIntegerLinearProgram() sage: x=p.new_variable() sage: # With the following instruction, all the variables sage: # from x will be real ( they are by default, though ) sage: p.set_real(x) sage: p.set_objective(x[0]+x[1]) sage: p.add_constraint(-3*x[0]+2*x[1],max=2) sage: # sage: # The following instruction does absolutely nothing sage: # as none of the variables of x have been used yet sage: p.setreal(x) sage: p.setobj(x[0]+x[1]) sage: p.addconstraint(-3*x[0]+2*x[1],max=2) sage: # sage: # This instructions sets x[0] and x[1] sage: # as real variables sage: p.setreal(x) sage: p.addconstraint(x[3]+x[2],max=2) sage: # sage: # x[3] is not set as real sage: # as no setreal(x) has been called sage: # after its first definition sage: # ( even if actually, it is as variables sage: # are real by default ... ) sage: # sage: # Now it is done sage: p.setreal(x[3]) sage: # It is still possible, though, to set one of these sage: # variable as binary while keeping the others as they are sage: p.set_binary(x[3]) """ if isinstance(e,MIPVariable): e.vtype=self.__REAL if e.depth()==1: for v in e.values(): self.types[v]=self.__REAL else: for v in e.keys(): self.setbinary(e[v]) self.set_real(e[v]) elif self.variables.has_key(e): self.types[e]=self.__REAL else: raise Exception("Wrong kind of variable..") def isreal(self,e): def is_real(self,e): r""" Tests whether the variable is real. ``True`` if the variable is real, ``False`` otherwise EXAMPLE: EXAMPLE:: sage: p=MIP() sage: v=p.newvar() sage: p.setobj(v[1]) sage: p.isreal(v[1]) sage: p=MixedIntegerLinearProgram() sage: v=p.new_variable() sage: p.set_objective(v[1]) sage: p.is_real(v[1]) True sage: p.setbinary(v[1]) sage: p.isreal(v[1]) sage: p.set_binary(v[1]) sage: p.is_real(v[1]) False sage: p.setreal(v[1]) sage: p.isreal(v[1]) sage: p.set_real(v[1]) sage: p.is_real(v[1]) True """ def solve(self,solver=None,log=False,objective_only=False): r""" Solves the MIP. Solves the MixedIntegerLinearProgram. INPUT : - ``solver'' : - ``solver`` : 3 solvers should be available through this class : - GLPK ( ``solver="GLPK"`` ) http://www.gnu.org/software/glpk/ Variables: x is Real ( min = 0, max = None ) y is Real ( min = 0, max = None ) :: sage: p=MIP(sense=1) sage: x=p.newvar() sage: p.setobj(x[1]+5*x[2]) sage: p.addconstraint(x[1]+0.2*x[2],max=4) sage: p.addconstraint(1.5*x[1]+3*x[2],max=4) sage: p=MixedIntegerLinearProgram(sense=1) sage: x=p.new_variable() sage: p.set_objective(x[1]+5*x[2]) sage: p.add_constraint(x[1]+0.2*x[2],max=4) sage: p.add_constraint(1.5*x[1]+3*x[2],max=4) sage: p.solve()           # optional - requires Glpk or COIN-OR/CBC 6.6666666666666661 sage: p.get_values(x)     # optional - requires Glpk or COIN-OR/CBC sage: ### Computation of a maximum stable set in Petersen's graph ### sage: g=graphs.PetersenGraph() sage: p=MIP(sense=1) sage: b=p.newvar() sage: p.setobj(sum([b[v] for v in g])) sage: p=MixedIntegerLinearProgram(sense=1) sage: b=p.new_variable() sage: p.set_objective(sum([b[v] for v in g])) sage: for (u,v) in g.edges(labels=None): ...       p.addconstraint(b[u]+b[v],max=1) sage: p.setbinary(b) ...       p.add_constraint(b[u]+b[v],max=1) sage: p.set_binary(b) sage: p.solve(objective_only=True)     # optional - requires Glpk or COIN-OR/CBC 4.0 """ if self.objective==None: try: from sage.numerical.mipCoin import solveCoin except: raise NotImplementedError("Coin/CBC is not installed and cannot be used to solve this MIP\n To install it, you can type in Sage : sage: install_package('cbc')") 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')") return solveCoin(self,log=log,objective_only=objective_only) elif solver=="GLPK": try: from sage.numerical.mipGlpk import solveGlpk except: raise NotImplementedError("GLPK is not installed and cannot be used to solve this MIP\n To install it, you can type in Sage : sage: install_package('glpk')") 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')") return solveGlpk(self,log=log,objective_only=objective_only) elif solver=="CPLEX": raise NotImplementedError("The support for CPLEX is not written yet... We're seriously thinking about it, though ;-)") values are their coefficients. The value corresponding to key `-1` is the constant coefficient EXAMPLE: EXAMPLE:: sage: p=MIP() sage: v=p.newvar() sage: p=MixedIntegerLinearProgram() sage: v=p.new_variable() sage: p._NormalForm(v[0]+v[1]) {1: 1.0, 2: 1.0, -1: 0.0} """ d[-1]=exp.constant_coefficient() return d def _addElementToRing(self): def _add_element_to_ring(self,vtype): r""" Creates a new variable from the main ``InfinitePolynomialRing`` - The newly created variable EXAMPLE: EXAMPLE:: sage: p=MIP() sage: v=p.newvar() sage: p.count[0] sage: p=MixedIntegerLinearProgram() sage: v=p.new_variable() sage: p.count 0 sage: p._addElementToRing() sage: p._add_element_to_ring(p.__REAL) x1 sage: p.count[0] sage: p.count 1 """ self.count[0]+=1 v=self.x[self.count[0]] self.variables[v]=self.count[0] self.types[v]=self.__REAL self.count+=1 v=self.x[self.count] self.variables[v]=self.count self.types[v]=vtype self.min[v]=0.0 return v def setmin(self,v,min): def set_min(self,v,min): r""" Sets the minimum value of a variable EXAMPLE:: sage: p=MIP() sage: v=p.newvar() sage: p.setobj(v[1]) sage: p.getmin(v[1]) sage: p=MixedIntegerLinearProgram() sage: v=p.new_variable() sage: p.set_objective(v[1]) sage: p.get_min(v[1]) 0.0 sage: p.setmin(v[1],6) sage: p.getmin(v[1]) sage: p.set_min(v[1],6) sage: p.get_min(v[1]) 6.0 """ self.min[v]=min def setmax(self,v,max): def set_max(self,v,max): r""" Sets the maximum value of a variable EXAMPLE:: sage: p=MIP() sage: v=p.newvar() sage: p.setobj(v[1]) sage: p.getmax(v[1]) sage: p.setmax(v[1],6) sage: p.getmax(v[1]) sage: p=MixedIntegerLinearProgram() sage: v=p.new_variable() sage: p.set_objective(v[1]) sage: p.get_max(v[1]) sage: p.set_max(v[1],6) sage: p.get_max(v[1]) 6.0 """ self.max[v]=max def getmin(self,v): def get_min(self,v): r""" Returns the minimum value of a variable EXAMPLE:: sage: p=MIP() sage: v=p.newvar() sage: p.setobj(v[1]) sage: p.getmin(v[1]) sage: p=MixedIntegerLinearProgram() sage: v=p.new_variable() sage: p.set_objective(v[1]) sage: p.get_min(v[1]) 0.0 sage: p.setmin(v[1],6) sage: p.getmin(v[1]) sage: p.set_min(v[1],6) sage: p.get_min(v[1]) 6.0 """ return float(self.min[v]) if self.min.has_key(v) else 0.0 def getmax(self,v): return float(self.min[v]) if self.min.has_key(v) else None def get_max(self,v): r""" Returns the maximum value of a variable EXAMPLE:: sage: p=MIP() sage: v=p.newvar() sage: p.setobj(v[1]) sage: p.getmax(v[1]) sage: p.setmax(v[1],6) sage: p.getmax(v[1]) sage: p=MixedIntegerLinearProgram() sage: v=p.new_variable() sage: p.set_objective(v[1]) sage: p.get_max(v[1]) sage: p.set_max(v[1],6) sage: p.get_max(v[1]) 6.0 """ return float(self.max[v]) if self.max.has_key(v) else None ``MIPSolverException`` is the exception raised when the solver fails EXAMPLE: EXAMPLE:: sage: MIPSolverException("Error") MIPSolverException() r""" Returns the value of the instance of ``MIPSolverException` ` EXAMPLE: EXAMPLE:: sage: e=MIPSolverException("Error") sage: print e class MIPVariable: r""" ``MIPVariable`` is a variable used by the class ``MIP`` ``MIPVariable`` is a variable used by the class ``MixedIntegerLinearProgram`` """ def __init__(self,x,f,dim=1): def __init__(self,p,vtype,dim=1): r""" Constructor for ``MIPVariable`` INPUT: - ``x`` is the generator element of an ``InfinitePolynomialRing`` - ``f`` is a function returning a new variable from the parent class - ``p`` is the instance of ``MixedIntegerLinearProgram`` to which the variable is to be linked. - ``dim`` is the integer defining the definition of the variable For more informations, see method ``MIP.newvar`` For more informations, see method ``MixedIntegerLinearProgram.new_variable`` EXAMPLE: EXAMPLE:: sage: p=MIP() sage: v=p.newvar() sage: p=MixedIntegerLinearProgram() sage: v=p.new_variable() """ self.dim=dim self.dict={} self.x=x self.f=f self.p=p self.vtype=vtype def __getitem__(self,i): r""" Returns the element asked, otherwise creates it. ( When depth>1, recursively creates the variables ) EXAMPLE: EXAMPLE:: sage: p=MIP() sage: v=p.newvar() sage: p.setobj(v[0]+v[1]) sage: p=MixedIntegerLinearProgram() sage: v=p.new_variable() sage: p.set_objective(v[0]+v[1]) sage: v[0] x1 """ if self.dict.has_key(i): return self.dict[i] elif self.dim==1: self.dict[i]=self.f() self.dict[i]=self.p._add_element_to_ring(self.vtype) return self.dict[i] else: self.dict[i]=MIPVariable(dim=self.dim-1,x=self.x, f=self.f) self.dict[i]=MIPVariable(self.p,self.vtype,dim=self.dim-1) return self.dict[i] def keys(self): r""" Returns the keys already defined in the dictionary EXAMPLE: EXAMPLE:: sage: p=MIP() sage: v=p.newvar() sage: p.setobj(v[0]+v[1]) sage: p=MixedIntegerLinearProgram() sage: v=p.new_variable() sage: p.set_objective(v[0]+v[1]) sage: v.keys() [0, 1] """ r""" Returns the pairs (keys,value) contained in the dictionary EXAMPLE: EXAMPLE:: sage: p=MIP() sage: v=p.newvar() sage: p.setobj(v[0]+v[1]) sage: p=MixedIntegerLinearProgram() sage: v=p.new_variable() sage: p.set_objective(v[0]+v[1]) sage: v.items() [(0, x1), (1, x2)] """ r""" Returns the current variable's depth EXAMPLE: EXAMPLE:: sage: p=MIP() sage: v=p.newvar() sage: p.setobj(v[0]+v[1]) sage: p=MixedIntegerLinearProgram() sage: v=p.new_variable() sage: p.set_objective(v[0]+v[1]) sage: v.depth() 1 """ r""" Returns the symbolic variables associated to the current dictionary EXAMPLE: EXAMPLE:: sage: p=MIP() sage: v=p.newvar() sage: p.setobj(v[0]+v[1]) sage: p=MixedIntegerLinearProgram() sage: v=p.new_variable() sage: p.set_objective(v[0]+v[1]) sage: v.values() [x1, x2] """