Ticket #7012: trac_7012-flattened.patch

File trac_7012-flattened.patch, 59.3 KB (added by mvngu, 11 years ago)

flattened patch; include rebased patch and reviewer patch

  • doc/en/reference/numerical.rst

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1254129856 25200
    # Node ID 98c624cabaf9c396055c57688d658de97661b850
    # Parent  e334f15125a3faecdecfefc6079a7ba4536955e8
    trac 7012: Numerical.mip Class : functions renamed, typos, several docstring fixes, bugfixes; reviewer patch Minh Van Nguyen <nguyenminh2@gmail.com>
    
    diff -r e334f15125a3 -r 98c624cabaf9 doc/en/reference/numerical.rst
    a b  
    55   :maxdepth: 2
    66
    77   sage/numerical/knapsack
     8   sage/numerical/mip
    89   sage/numerical/optimize
  • sage/numerical/knapsack.py

    diff -r e334f15125a3 -r 98c624cabaf9 sage/numerical/knapsack.py
    a b  
    641641    if reals:
    642642        seq = [(x,1) for x in seq]
    643643
    644     from sage.numerical.mip import MIP
    645     p = MIP(sense=1)
    646     present = p.newvar()
    647     p.setobj(sum([present[i] * seq[i][1] for i in range(len(seq))]))
    648     p.addconstraint(sum([present[i] * seq[i][0] for i in range(len(seq))]), max=max)
     644    from sage.numerical.mip import MixedIntegerLinearProgram
     645    p = MixedIntegerLinearProgram(sense=1)
     646    present = p.new_variable()
     647    p.set_objective(sum([present[i] * seq[i][1] for i in range(len(seq))]))
     648    p.add_constraint(sum([present[i] * seq[i][0] for i in range(len(seq))]), max=max)
    649649
    650650    if binary:
    651         p.setbinary(present)
     651        p.set_binary(present)
    652652    else:
    653         p.setinteger(present)
     653        p.set_integer(present)
    654654
    655655    if value_only:
    656656        return p.solve(objective_only=True)
  • sage/numerical/mip.pyx

    diff -r e334f15125a3 -r 98c624cabaf9 sage/numerical/mip.pyx
    a b  
    1 include '../ext/stdsage.pxi'
     1r"""
     2Mixed integer linear programming
     3"""
    24
    3 class MIP:
     5include "../ext/stdsage.pxi"
     6
     7class MixedIntegerLinearProgram:
    48    r"""
    5     The MIP 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.
    718
    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 ``MIP`` also requires the information
    12     on the direction of the optimization :
    13    
    14     A ``MIP`` ( 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``.
    1621
    1722    INPUT:
    18        
    19         - ``sense'' :
    20                  * When set to `1` (default), the ``MIP`` is defined as a Maximization
    21                  * When set to `-1`, the ``MIP`` 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
    2331    EXAMPLES::
    2432
    25          sage: ### Computation of a maximum stable set in Petersen's graph ###
    26          sage: g=graphs.PetersenGraph()
    27          sage: p=MIP(sense=1)
    28          sage: b=p.newvar()
    29          sage: p.setobj(sum([b[v] for v in g]))
     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()
     37         sage: p.set_objective(sum([b[v] for v in g]))
    3038         sage: for (u,v) in g.edges(labels=None):
    31          ...       p.addconstraint(b[u]+b[v],max=1)
    32          sage: p.setbinary(b)
     39         ...       p.add_constraint(b[u] + b[v], max=1)
     40         sage: p.set_binary(b)
    3341         sage: p.solve(objective_only=True)     # optional - requires Glpk or COIN-OR/CBC
    3442         4.0
    35     """       
     43    """
    3644
    37     def __init__(self,sense=1):
     45    def __init__(self, maximization=True):
    3846        r"""
    39         Constructor for the MIP class
     47        Constructor for the ``MixedIntegerLinearProgram`` class.
    4048
    4149        INPUT:
    42        
    43         - ``sense'' :
    44                  When set to 1, the MIP is defined as a Maximization
    45                  When set to -1, the MIP is defined as a Minimization
    4650
    47         EXAMPLE:
     51        - ``maximization``
    4852
    49             sage: p=MIP(sense=1)
     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.
     57
     58        EXAMPLE::
     59
     60            sage: p = MixedIntegerLinearProgram(maximization=True)
    5061        """
    51 
    5262        try:
    53              from sage.numerical.mipCoin import solveCoin
    54              self.default_solver="Coin"
     63            from sage.numerical.mipCoin import solveCoin
     64            self.default_solver = "Coin"
    5565        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
    6271
    6372        from sage.rings.polynomial.infinite_polynomial_ring import InfinitePolynomialRing
    6473        from sage.rings.real_double import RealDoubleField as RR
    65         P = InfinitePolynomialRing(RR(), names=('x',));
     74        P = InfinitePolynomialRing(RR(), names=('x',))
    6675        (self.x,) = P._first_ngens(1)
    6776
    68         self.count=[0]
    69         self.sense=sense
    70         self.objective=None
    71         self.variables={}
    72         self.constraints=[]
    73         self.min={}
    74         self.max={}
    75         self.types={}
    76         self.values={}
    77         self.__BINARY=1
    78         self.__REAL=-1
    79         self.__INTEGER=0
     77        # number of variables
     78        self.count = 0
     79        self.maximization = maximization
     80        self.objective = None
     81
     82        self.variables = {}
     83        self.constraints = []
     84
     85        #constains the min and max bounds on the variables
     86        self.min = {}
     87        self.max = {}
     88
     89        # constains the variables types
     90        self.types = {}
     91
     92        #constains the variables' values when
     93        # solve(objective_only=False) is called
     94        self.values = {}
     95
     96        # Several constants
     97        self.__BINARY = 1
     98        self.__REAL = -1
     99        self.__INTEGER = 0
    80100
    81101    def __repr__(self):
    82102         r"""
    83          Returns a short description of the MIP
    84          
    85          EXAMPLE:
    86          
    87          sage: p=MIP()
    88          sage: v=p.newvar()
    89          sage: p.addconstraint(v[1]+v[2],max=2)
    90          sage: print p
    91          Mixed Integer Program ( maximization, 2 variables, 1 constraints )
     103         Returns a short description of the ``MixedIntegerLinearProgram``.
     104
     105         EXAMPLE::
     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 )
    92112         """
    93          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 )"
    94117
    95     def newvar(self,dim=1):
     118    def new_variable(self, vtype=-1, dim=1):
    96119        r"""
    97120        Returns an instance of ``MIPVariable`` associated
    98         to the current instance of ``MIP``.
    99        
    100         A new ``MIP`` variable ``x`` defined by :::
     121        to the current instance of ``MixedIntegerLinearProgram``.
    101122
    102             sage: p=MIP()
    103             sage: x=p.newvar()
     123        A new variable ``x`` is defined by::
    104124
    105         It behaves exactly as an usual dictionary would. It can use any key
    106         argument you may like, as ``x[5]`` or ``x["b"]``, and has methods
    107         ``items()`` and ``keys()``
    108        
     125            sage: p = MixedIntegerLinearProgram()
     126            sage: x = p.new_variable()
     127
     128        It behaves exactly as a usual dictionary would. It can use any key
     129        argument you may like, as ``x[5]`` or ``x["b"]``, and has methods
     130        ``items()`` and ``keys()``.
     131
    109132        Any of its fields exists, and is uniquely defined.
    110133
    111134        INPUT:
    112135
    113         - ``dim`` ( integer ) : Defines the dimension of the dictionary
    114                       If ``x`` has dimension `2`, its fields will
    115                       be of the form ``x[key1][key2]``
     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``).
    116141
    117142        EXAMPLE::
    118143
    119             sage: p=MIP()
    120             sage: x=p.newvar()
    121             sage: y=p.newvar(dim=2)
    122             sage: p.addconstraint(x[2]+y[3][5],max=2)
     144            sage: p = MixedIntegerLinearProgram()
     145            sage: # available types are p.__REAL, p.__INTEGER and p.__BINARY
     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)
    123149        """
    124         return MIPVariable(self.x,self._addElementToRing,dim=dim)
    125          
     150        return MIPVariable(self, vtype, dim=dim)
    126151
    127     def export(self,format="text"):
    128          r"""
    129          Exports the MIP to a string in different formats.
    130          
    131          INPUT:
    132          
    133          - ``format'' :
    134                    "text" : human-readable format
    135 
    136          sage: p=MIP()
    137          sage: x=p.newvar()
    138          sage: p.setobj(x[1]+x[2])
    139          sage: p.addconstraint(-3*x[1]+2*x[2],max=2)
    140          sage: print p.export(format="text")
    141          Maximization :
    142            x2 + x1
    143          Constraints :
    144            2.0*x2 - 3.0*x1
    145          Variables :
    146            x2 is a real variable (min=0.0,max=+oo)
    147            x1 is a real variable (min=0.0,max=+oo)
    148          """
    149          if format=="text":
    150               value=("Maximization :\n" if self.sense==1 else "Minimization :\n")
    151               value=value+"  "+(str(self.objective) if self.objective!=None else "Undefined")
    152               value=value+"\nConstraints :"
    153               for c in self.constraints:
    154                    value=value+"\n  "+str(c["function"])
    155               value=value+"\nVariables :"
    156               for v in self.variables.keys():
    157                    value=value+"\n  "+str(v)+" is"
    158                    if self.isinteger(v):
    159                        value=value+" an integer variable"
    160                    elif self.isbinary(v):
    161                        value=value+" an boolean variable"                       
    162                    else:
    163                        value=value+" a real variable"
    164                    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")+")"
    165               return value
    166 
    167     def get_values(self,*lists):
     152    def export(self, format="text"):
    168153        r"""
    169         Return values found by the previous call to ``solve()``
     154        Exports the ``MixedIntegerLinearProgram`` to a string in
     155        different formats.
    170156
    171157        INPUT:
    172        
    173         - 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),
    174217          or lists of them.
    175218
    176219        OUTPUT:
    177220
    178221        - Each instance of ``MIPVariable`` is replaced by a dictionary
    179            containing the numerical values found for each
    180            corresponding variable in the instance
     222          containing the numerical values found for each
     223          corresponding variable in the instance.
    181224        - Each element of an instance of a ``MIPVariable`` is replaced
    182            by its corresponding numerical value.
     225          by its corresponding numerical value.
    183226
    184227        EXAMPLE::
    185228
    186             sage: p=MIP()
    187             sage: x=p.newvar()
    188             sage: y=p.newvar(dim=2)
    189             sage: p.setobj(x[3]+y[2][9]+x[5])
    190             sage: p.addconstraint(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)
    191234            sage: p.solve() # optional - requires Glpk or COIN-OR/CBC
    192235            2.0
    193236            sage: #
    194237            sage: # Returns the optimal value of x[3]
    195238            sage: p.get_values(x[3]) # optional - requires Glpk or COIN-OR/CBC
    196             0.0
     239            2.0
    197240            sage: #
    198241            sage: # Returns a dictionary identical to x
    199242            sage: # containing values for the corresponding
    200243            sage: # variables
    201             sage: x_sol=p.get_values(x)
     244            sage: x_sol = p.get_values(x)
    202245            sage: x_sol.keys()
    203246            [3, 5]
    204247            sage: #
    205248            sage: # Obviously, it also works with
    206249            sage: # variables of higher dimension
    207             sage: y_sol=p.get_values(y)
    208             sage: # 
     250            sage: y_sol = p.get_values(y)
     251            sage: #
    209252            sage: # We could also have tried :
    210             sage: [x_sol,y_sol]=p.get_values(x,y)
     253            sage: [x_sol, y_sol] = p.get_values(x, y)
    211254            sage: # Or
    212             sage: [x_sol,y_sol]=p.get_values([x,y])
     255            sage: [x_sol, y_sol] = p.get_values([x, y])
    213256        """
    214 
    215         val=[]
     257        val = []
    216258        for l in lists:
    217             if isinstance(l,MIPVariable):
    218                 if l.depth()==1:
    219                     c={}
     259            if isinstance(l, MIPVariable):
     260                if l.depth() == 1:
     261                    c = {}
    220262                    for (k,v) in l.items():
    221                         c[k]=self.values[v] if self.values.has_key(v) else None
     263                        c[k] = self.values[v] if self.values.has_key(v) else None
    222264                    val.append(c)
    223265                else:
    224                     c={}
     266                    c = {}
    225267                    for (k,v) in l.items():
    226                         c[k]=self.get_values(v)
    227                     val.append(c)                   
    228             elif isinstance(l,list):
    229                 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:
    230272                    val.append([self.get_values(l[0])])
    231273                else:
    232                     c=[]
     274                    c = []
    233275                    [c.append(self.get_values(ll)) for ll in l]
    234276                    val.append(c)
    235277            elif self.variables.has_key(l):
    236278                val.append(self.values[l])
    237         if len(lists)==1:
     279        if len(lists) == 1:
    238280            return val[0]
    239281        else:
    240282            return val
    241                
    242            
    243283
    244284    def show(self):
    245285        r"""
    246         Prints the MIP in a human-readable way
     286        Prints the ``MixedIntegerLinearProgram`` in a human-readable format.
     287
     288        EXAMPLE::
     289
     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)
     302        """
     303        print self.export(format="text")
     304
     305    def set_objective(self,obj):
     306        r"""
     307        Sets the objective of the ``MixedIntegerLinearProgram``.
     308
     309        INPUT:
     310
     311        - ``obj`` -- A linear function to be optimized.
    247312
    248313        EXAMPLE:
    249314
    250         sage: p=MIP()
    251         sage: x=p.newvar()
    252         sage: p.setobj(x[1]+x[2])
    253         sage: p.addconstraint(-3*x[1]+2*x[2],max=2)
    254         sage: p.show()
    255         Maximization :
    256           x2 + x1
    257         Constraints :
    258           2.0*x2 - 3.0*x1
    259         Variables :
    260           x2 is a real variable (min=0.0,max=+oo)
    261           x1 is a real variable (min=0.0,max=+oo)
    262         """
    263         print self.export(format="text")
    264        
    265     #Ok
    266     def setobj(self,obj):
    267         r"""
    268         Sets the objective of the ``MIP``.
     315        Let's solve the following linear program::
    269316
    270         INPUT:
    271        
    272         - ``obj`` : A linear function to be optimized
     317            Maximize:
     318              x + 5 * y
     319            Constraints:
     320              x + 0.2 y       <= 4
     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)
    273325
    274         EXAMPLE::
    275        
    276            This code solves the following Linear Program :
    277            
    278            Maximize:
    279               x + 5 * y
    280            Constraints:
    281               x + 0.2 y       <= 4
    282               1.5 * x + 3 * y   <=4
    283            Variables:
    284               x is Real ( min = 0, max = None )
    285               y is Real ( min = 0, max = None )
     326        This linear program can be solved as follows::
    286327
    287            sage: p=MIP(sense=1)
    288            sage: x=p.newvar()
    289            sage: p.setobj(x[1]+5*x[2])
    290            sage: p.addconstraint(x[1]+0.2*x[2],max=4)
    291            sage: p.addconstraint(1.5*x[1]+3*x[2],max=4)
    292            sage: p.solve()     # optional - requires Glpk or COIN-OR/CBC
    293            6.6666666666666661
    294            
     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
    295335        """
    296336        self.objective=obj
    297337
    298     def addconstraint(self,linear_function,max=None,min=None):
     338    def add_constraint(self, linear_function, max=None, min=None):
    299339        r"""
    300         Adds a constraint to the MIP
    301        
    302         INPUT :
    303 
    304         - ``consraint`` : : A linear function
    305         - ``max``  : An upper bound on the constraint ( set to ``None`` by default )
    306         - ``min``  : A lower bound on the constraint
    307 
    308         EXAMPLE::
    309        
    310            This code solves the following Linear Program :
    311            
    312            Maximize:
    313               x + 5 * y
    314            Constraints:
    315               x + 0.2 y       <= 4
    316               1.5 * x + 3 * y   <=4
    317            Variables:
    318               x is Real ( min = 0, max = None )
    319               y is Real ( min = 0, max = None )
    320 
    321            sage: p=MIP(sense=1)
    322            sage: x=p.newvar()
    323            sage: p.setobj(x[1]+5*x[2])
    324            sage: p.addconstraint(x[1]+0.2*x[2],max=4)
    325            sage: p.addconstraint(1.5*x[1]+3*x[2],max=4)
    326            sage: p.solve()     # optional - requires Glpk or COIN-OR/CBC
    327            6.6666666666666661
    328         """
    329 
    330         max=float(max) if max!=None else None
    331         min=float(min) if min!=None else None
    332         self.constraints.append({"function":linear_function,"min":min, "max":max,"card":len(linear_function.variables())})
    333 
    334     def setbinary(self,e):
    335         r"""
    336         Sets a variable or a ``MIPVariable`` as binary
     340        Adds a constraint to the ``MixedIntegerLinearProgram``.
    337341
    338342        INPUT:
    339343
    340         - ``e`` : An instance of ``MIPVariable`` or one of
    341                   its elements
    342 
    343         NOTE:
    344 
    345         We recommend you to define the types of your variables after
    346         your problem has been completely defined ( see example )
     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.
    347348
    348349        EXAMPLE:
    349350
    350           sage: p=MIP()
    351           sage: x=p.newvar()
    352           sage: #
    353           sage: # The following instruction does absolutely nothing
    354           sage: # as none of the variables of x have been used yet
    355           sage: p.setbinary(x)
    356           sage: p.setobj(x[0]+x[1])
    357           sage: p.addconstraint(-3*x[0]+2*x[1],max=2)
    358           sage: #
    359           sage: # This instructions sets x[0] and x[1]
    360           sage: # as binary variables
    361           sage: p.setbinary(x)
    362           sage: p.addconstraint(x[3]+x[2],max=2)
    363           sage: #
    364           sage: # x[3] is not set as binary
    365           sage: # as no setbinary(x) has been called
    366           sage: # after its first definition
    367           sage: #
    368           sage: # Now it is done
    369           sage: p.setbinary(x[3])
     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
    370371        """
    371         if isinstance(e,MIPVariable):
    372             if e.depth()==1:
    373                 for v in e.values():
    374                     self.types[v]=self.__BINARY               
    375             else:
    376                 for v in e.keys():
    377                     self.setbinary(e[v])
    378         elif self.variables.has_key(e):       
    379             self.types[e]=self.__BINARY
    380         else:
    381             raise Exception("Wrong kind of variable..")
     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()) })
    382379
    383     def isbinary(self,e):
     380    def set_binary(self, e):
    384381        r"""
    385         Tests whether the variable is binary.
    386 
    387         ( Variables are real by default )
     382        Sets a variable or a ``MIPVariable`` as binary.
    388383
    389384        INPUT:
    390385
    391         - ``e`` : a variable ( not a ``MIPVariable``, but one of its elements ! )
     386        - ``e`` -- An instance of ``MIPVariable`` or one of
     387          its elements.
     388
     389        EXAMPLE::
     390
     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])
     402        """
     403        if isinstance(e, MIPVariable):
     404            e.vtype = self.__BINARY
     405            if e.depth() == 1:
     406                for v in e.values():
     407                    self.types[v] = self.__BINARY
     408            else:
     409                for v in e.keys():
     410                    self.set_binary(e[v])
     411        elif self.variables.has_key(e):
     412            self.types[e] = self.__BINARY
     413        else:
     414            raise ValueError("e must be an instance of MIPVariable or one of its elements.")
     415
     416    def is_binary(self, e):
     417        r"""
     418        Tests whether the variable ``e`` is binary. Variables are real by
     419        default.
     420
     421        INPUT:
     422
     423        - ``e`` -- A variable (not a ``MIPVariable``, but one of its elements.)
    392424
    393425        OUTPUT:
    394426
    395         ``True`` if the variable is binary, ``False`` otherwise
     427        ``True`` if the variable ``e`` is binary; ``False`` otherwise.
    396428
    397         EXAMPLE:
     429        EXAMPLE::
    398430
    399             sage: p=MIP()
    400             sage: v=p.newvar()
    401             sage: p.setobj(v[1])
    402             sage: p.isbinary(v[1])
     431            sage: p = MixedIntegerLinearProgram()
     432            sage: v = p.new_variable()
     433            sage: p.set_objective(v[1])
     434            sage: p.is_binary(v[1])
    403435            False
    404             sage: p.setbinary(v[1])           
    405             sage: p.isbinary(v[1])
     436            sage: p.set_binary(v[1])
     437            sage: p.is_binary(v[1])
    406438            True
    407439        """
    408         # Returns an exception if the variable does not exist..
    409         # For exemple if the users tries to find out the type of
    410         # 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.
    411443        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:
    414445            return True
    415446        return False
    416447
    417     def setinteger(self,e):
     448    def set_integer(self, e):
    418449        r"""
    419         Sets a variable or a ``MIPVariable`` as integer
     450        Sets a variable or a ``MIPVariable`` as integer.
    420451
    421452        INPUT:
    422453
    423         - ``e`` : An instance of ``MIPVariable`` or one of
    424                   its elements
     454        - ``e`` -- An instance of ``MIPVariable`` or one of
     455          its elements.
    425456
    426         NOTE:
     457        EXAMPLE::
    427458
    428         We recommend you to define the types of your variables after
    429         your problem has been completely defined ( see example )
    430 
    431         EXAMPLE:
    432 
    433           sage: p=MIP()
    434           sage: x=p.newvar()
    435           sage: #
    436           sage: # The following instruction does absolutely nothing
    437           sage: # as none of the variables of x have been used yet
    438           sage: p.setinteger(x)
    439           sage: p.setobj(x[0]+x[1])
    440           sage: p.addconstraint(-3*x[0]+2*x[1],max=2)
    441           sage: #
    442           sage: # This instructions sets x[0] and x[1]
    443           sage: # as integer variables
    444           sage: p.setinteger(x)
    445           sage: p.addconstraint(x[3]+x[2],max=2)
    446           sage: #
    447           sage: # x[3] is not set as integer
    448           sage: # as no setinteger(x) has been called
    449           sage: # after its first definition
    450           sage: #
    451           sage: # Now it is done
    452           sage: p.setinteger(x[3])
     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])
    453470        """
    454         if isinstance(e,MIPVariable):
    455             if e.depth()==1:
     471        if isinstance(e, MIPVariable):
     472            e.vtype = self.__INTEGER
     473            if e.depth() == 1:
    456474                for v in e.values():
    457                     self.types[v]=self.__INTEGER               
     475                    self.types[v] = self.__INTEGER
    458476            else:
    459477                for v in e.keys():
    460                     self.setbinary(e[v])
    461         elif self.variables.has_key(e):       
    462             self.types[e]=self.__INTEGER
     478                    self.set_integer(e[v])
     479        elif self.variables.has_key(e):
     480            self.types[e] = self.__INTEGER
    463481        else:
    464             raise Exception("Wrong kind of variable..")
     482            raise ValueError("e must be an instance of MIPVariable or one of its elements.")
    465483
    466     def isinteger(self,e):
     484    def is_integer(self, e):
    467485        r"""
    468         Tests whether the variable is integer.
    469 
    470         ( Variables are real by default )
     486        Tests whether the variable is an integer. Variables are real by
     487        default.
    471488
    472489        INPUT:
    473490
    474         - ``e`` : a variable ( not a ``MIPVariable``, but one of its elements ! )
     491        - ``e`` -- A variable (not a ``MIPVariable``, but one of its elements.)
    475492
    476493        OUTPUT:
    477494
    478         ``True`` if the variable is integer, ``False`` otherwise
     495        ``True`` if the variable ``e`` is an integer; ``False`` otherwise.
    479496
    480         EXAMPLE:
     497        EXAMPLE::
    481498
    482             sage: p=MIP()
    483             sage: v=p.newvar()
    484             sage: p.setobj(v[1])
    485             sage: p.isinteger(v[1])
     499            sage: p = MixedIntegerLinearProgram()
     500            sage: v = p.new_variable()
     501            sage: p.set_objective(v[1])
     502            sage: p.is_integer(v[1])
    486503            False
    487             sage: p.setinteger(v[1])           
    488             sage: p.isinteger(v[1])
     504            sage: p.set_integer(v[1])
     505            sage: p.is_integer(v[1])
    489506            True
    490507        """
    491         # Returns an exception if the variable does not exist..
    492         # For exemple if the users tries to find out the type of
    493         # 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.
    494511        self.variables[e]
    495 
    496         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:
    497513            return True
    498514        return False
    499515
    500     def setreal(self,e):
     516    def set_real(self,e):
    501517        r"""
    502         Sets a variable or a ``MIPVariable`` as real
     518        Sets a variable or a ``MIPVariable`` as real.
    503519
    504520        INPUT:
    505521
    506         - ``e`` : An instance of ``MIPVariable`` or one of
    507                   its elements
     522        - ``e`` -- An instance of ``MIPVariable`` or one of
     523          its elements.
    508524
    509         NOTE:
     525        EXAMPLE::
    510526
    511         We recommend you to define the types of your variables after
    512         your problem has been completely defined ( see example )
    513 
    514         EXAMPLE:
    515 
    516           sage: p=MIP()
    517           sage: x=p.newvar()
    518           sage: #
    519           sage: # The following instruction does absolutely nothing
    520           sage: # as none of the variables of x have been used yet
    521           sage: p.setreal(x)
    522           sage: p.setobj(x[0]+x[1])
    523           sage: p.addconstraint(-3*x[0]+2*x[1],max=2)
    524           sage: #
    525           sage: # This instructions sets x[0] and x[1]
    526           sage: # as real variables
    527           sage: p.setreal(x)
    528           sage: p.addconstraint(x[3]+x[2],max=2)
    529           sage: #
    530           sage: # x[3] is not set as real
    531           sage: # as no setreal(x) has been called
    532           sage: # after its first definition
    533           sage: # ( even if actually, it is as variables
    534           sage: # are real by default ... )
    535           sage: #
    536           sage: # Now it is done
    537           sage: p.setreal(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])
    538538        """
    539         if isinstance(e,MIPVariable):
    540             if e.depth()==1:
     539        if isinstance(e, MIPVariable):
     540            e.vtype = self.__REAL
     541            if e.depth() == 1:
    541542                for v in e.values():
    542                     self.types[v]=self.__REAL               
     543                    self.types[v] = self.__REAL
    543544            else:
    544545                for v in e.keys():
    545                     self.setbinary(e[v])
    546         elif self.variables.has_key(e):       
    547             self.types[e]=self.__REAL
     546                    self.set_real(e[v])
     547        elif self.variables.has_key(e):
     548            self.types[e] = self.__REAL
    548549        else:
    549             raise Exception("Wrong kind of variable..")
     550            raise ValueError("e must be an instance of MIPVariable or one of its elements.")
    550551
    551 
    552     def isreal(self,e):
     552    def is_real(self, e):
    553553        r"""
    554         Tests whether the variable is real.
    555 
    556         ( Variables are real by default )
     554        Tests whether the variable is real. Variables are real by default.
    557555
    558556        INPUT:
    559557
    560         - ``e`` : a variable ( not a ``MIPVariable``, but one of its elements ! )
     558        - ``e`` -- A variable (not a ``MIPVariable``, but one of its elements.)
    561559
    562560        OUTPUT:
    563561
    564         ``True`` if the variable is real, ``False`` otherwise
     562        ``True`` if the variable is real; ``False`` otherwise.
    565563
    566         EXAMPLE:
     564        EXAMPLE::
    567565
    568             sage: p=MIP()
    569             sage: v=p.newvar()
    570             sage: p.setobj(v[1])
    571             sage: p.isreal(v[1])
     566            sage: p = MixedIntegerLinearProgram()
     567            sage: v = p.new_variable()
     568            sage: p.set_objective(v[1])
     569            sage: p.is_real(v[1])
    572570            True
    573             sage: p.setbinary(v[1])
    574             sage: p.isreal(v[1])
     571            sage: p.set_binary(v[1])
     572            sage: p.is_real(v[1])
    575573            False
    576             sage: p.setreal(v[1])           
    577             sage: p.isreal(v[1])
     574            sage: p.set_real(v[1])
     575            sage: p.is_real(v[1])
    578576            True
    579577        """
    580        
    581         # Returns an exception if the variable does not exist..
    582         # For exemple if the users tries to find out the type of
    583         # 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.
    584581        self.variables[e]
    585 
    586         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:
    587583            return True
    588584        return False
    589585
    590 
    591     def solve(self,solver=None,log=False,objective_only=False):
     586    def solve(self, solver=None, log=False, objective_only=False):
    592587        r"""
    593         Solves the MIP.
    594 
    595         INPUT :
    596         - ``solver'' :
    597                  3 solvers should be available through this class :
    598                      - GLPK ( ``solver="GLPK"`` )
    599                      http://www.gnu.org/software/glpk/
    600                      
    601                      - COIN Branch and Cut  ( ``solver="Coin"`` )
    602                      COIN-OR http://www.coin-or.org/
    603                      If the spkg is installed
    604                      
    605                      - CPLEX  ( ``solver="CPLEX"`` )
    606                      http://www.ilog.com/products/cplex/
    607                      Not Implemented Yet
    608                      
    609                      ``solver`` should then be equal to one of ``"GLPK"``,
    610                      ``"Coin"``, ``"CPLEX"``, or ``None``.
    611                      If ``solver=None`` ( default ), the default solver is used
    612                      ( Coin if available, GLPK otherwise )
    613                      
    614         - ``log`` : This boolean variable indicates whether progress should be printed
    615                     during the computations.
    616        
    617         - ``objective_only`` : Boolean variable
    618                           * When set to ``True``, only the objective function is returned
    619                           * When set to ``False`` (default), the optimal
    620                             numerical values are stored ( takes computational
    621                             time )
    622 
    623         OUTPUT :
    624        
    625         The optimal value taken by the objective function
    626        
    627         EXAMPLE :
    628        
    629         This code solves the following Linear Program :
    630 
    631            Maximize:
    632               x + 5 * y
    633            Constraints:
    634               x + 0.2 y       <= 4
    635               1.5 * x + 3 * y   <=4
    636            Variables:
    637               x is Real ( min = 0, max = None )
    638               y is Real ( min = 0, max = None )
    639 
    640 
    641            sage: p=MIP(sense=1)
    642            sage: x=p.newvar()
    643            sage: p.setobj(x[1]+5*x[2])
    644            sage: p.addconstraint(x[1]+0.2*x[2],max=4)
    645            sage: p.addconstraint(1.5*x[1]+3*x[2],max=4)
    646            sage: p.solve()           # optional - requires Glpk or COIN-OR/CBC
    647            6.6666666666666661
    648            sage: p.get_values(x)     # optional - requires Glpk or COIN-OR/CBC
    649            {1: 0.0, 2: 1.3333333333333333}
    650 
    651            sage: ### Computation of a maximum stable set in Petersen's graph ###
    652            sage: g=graphs.PetersenGraph()
    653            sage: p=MIP(sense=1)
    654            sage: b=p.newvar()
    655            sage: p.setobj(sum([b[v] for v in g]))
    656            sage: for (u,v) in g.edges(labels=None):
    657            ...       p.addconstraint(b[u]+b[v],max=1)
    658            sage: p.setbinary(b)
    659            sage: p.solve(objective_only=True)     # optional - requires Glpk or COIN-OR/CBC
    660            4.0
    661 
    662 
    663         """       
    664 
    665         if self.objective==None:
    666             raise Exception("No objective function has been defined !")
    667 
    668         if solver==None:
    669             solver=self.default_solver
    670 
    671         if solver==None:
    672              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")
    673         elif solver=="Coin":
    674              try:
    675                   from sage.numerical.mipCoin import solveCoin
    676              except:
    677                 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')")               
    678              return solveCoin(self,log=log,objective_only=objective_only)
    679 
    680         elif solver=="GLPK":
    681              try:
    682                   from sage.numerical.mipGlpk import solveGlpk
    683              except:
    684                 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')")               
    685              return solveGlpk(self,log=log,objective_only=objective_only)
    686         elif solver=="CPLEX":
    687              raise NotImplementedError("The support for CPLEX is not written yet... We're seriously thinking about it, though ;-)")
    688         else:
    689             raise NotImplementedError("solver should be set to 'GLPK', 'Coin', 'CPLEX' or None (in which case the default one is used).")
    690 
    691 
    692     def _NormalForm(self,exp):
    693         r"""
    694         Returns a dictionary built from the linear function
     588        Solves the ``MixedIntegerLinearProgram``.
    695589
    696590        INPUT:
    697591
    698         - ``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).
    699616
    700617        OUTPUT:
    701618
    702         A dictionary whose keys are the id of the variables, and whose
    703         values are their coefficients.
    704         The value corresponding to key `-1` is the constant coefficient
     619        The optimal value taken by the objective function.
    705620
    706         EXAMPLE:
     621        EXAMPLES:
    707622
    708             sage: p=MIP()
    709             sage: v=p.newvar()
    710             sage: p._NormalForm(v[0]+v[1])
    711             {1: 1.0, 2: 1.0, -1: 0.0}
     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
    712656        """
    713         d=dict(zip([self.variables[v] for v in exp.variables()],exp.coefficients()))
    714         d[-1]=exp.constant_coefficient()
    715         return d
     657        if self.objective == None:
     658            raise ValueError("No objective function has been defined.")
    716659
    717     def _addElementToRing(self):
     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):
    718683        r"""
    719         Creates a new variable from the main ``InfinitePolynomialRing``
     684        Returns a dictionary built from the linear function.
     685
     686        INPUT:
     687
     688        - ``exp`` -- The expression representing a linear function.
    720689
    721690        OUTPUT:
    722691
    723         - The newly created variable
     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.
    724695
    725         EXAMPLE:
     696        EXAMPLE::
    726697
    727             sage: p=MIP()
    728             sage: v=p.newvar()
    729             sage: p.count[0]
     698            sage: p = MixedIntegerLinearProgram()
     699            sage: v = p.new_variable()
     700            sage: p._NormalForm(v[0] + v[1])
     701            {1: 1.0, 2: 1.0, -1: 0.0}
     702        """
     703        d = dict( zip([self.variables[v] for v in exp.variables()],
     704                      exp.coefficients()) )
     705        d[-1] = exp.constant_coefficient()
     706        return d
     707
     708    def _add_element_to_ring(self, vtype):
     709        r"""
     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``).
     716
     717        OUTPUT:
     718
     719        - The newly created variable.
     720
     721        EXAMPLE::
     722
     723            sage: p = MixedIntegerLinearProgram()
     724            sage: v = p.new_variable()
     725            sage: p.count
    730726            0
    731             sage: p._addElementToRing()
     727            sage: p._add_element_to_ring(p.__REAL)
    732728            x1
    733             sage: p.count[0]
     729            sage: p.count
    734730            1
    735731        """
    736         self.count[0]+=1
    737         v=self.x[self.count[0]]
    738         self.variables[v]=self.count[0]
    739         self.types[v]=self.__REAL
    740         self.min[v]=0.0
     732        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
    741737        return v
    742738
    743     def setmin(self,v,min):
     739    def set_min(self, v, min):
    744740        r"""
    745         Sets the minimum value of a variable
     741        Sets the minimum value of a variable.
     742
     743        INPUT:
     744
     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.
     749
     750        EXAMPLE::
     751
     752            sage: p = MixedIntegerLinearProgram()
     753            sage: v = p.new_variable()
     754            sage: p.set_objective(v[1])
     755            sage: p.get_min(v[1])
     756            0.0
     757            sage: p.set_min(v[1],6)
     758            sage: p.get_min(v[1])
     759            6.0
     760        """
     761        self.min[v] = min
     762
     763    def set_max(self, v, max):
     764        r"""
     765        Sets the maximum value of a variable.
    746766
    747767        INPUT
    748768
    749         - ``v`` : a variable ( not a ``MIPVariable``, but one of its elements ! )
    750         - ``min`` : the minimum value the variable can take
    751                     when ``min=None``, the variable has no lower 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.
    752773
    753774        EXAMPLE::
    754775
    755             sage: p=MIP()
    756             sage: v=p.newvar()
    757             sage: p.setobj(v[1])
    758             sage: p.getmin(v[1])
    759             0.0
    760             sage: p.setmin(v[1],6)
    761             sage: p.getmin(v[1])
     776            sage: p = MixedIntegerLinearProgram()
     777            sage: v = p.new_variable()
     778            sage: p.set_objective(v[1])
     779            sage: p.get_max(v[1])
     780            sage: p.set_max(v[1],6)
     781            sage: p.get_max(v[1])
    762782            6.0
    763783        """
    764         self.min[v]=min
     784        self.max[v] = max
    765785
    766     def setmax(self,v,max):
     786    def get_min(self, v):
    767787        r"""
    768         Sets the maximum value of a variable
     788        Returns the minimum value of a variable.
    769789
    770         INPUT
     790        INPUT:
    771791
    772         - ``v`` : a variable ( not a ``MIPVariable``, but one of its elements ! )
    773         - ``max`` : the maximum value the variable can take
    774                     when ``max=None``, the variable has no upper bound
     792        - ``v`` -- a variable (not a ``MIPVariable``, but one of its elements).
     793
     794        OUTPUT:
     795
     796        Minimum value of the variable, or ``None`` if
     797        the variable has no lower bound.
    775798
    776799        EXAMPLE::
    777800
    778             sage: p=MIP()
    779             sage: v=p.newvar()
    780             sage: p.setobj(v[1])
    781             sage: p.getmax(v[1])
    782             sage: p.setmax(v[1],6)
    783             sage: p.getmax(v[1])
     801            sage: p = MixedIntegerLinearProgram()
     802            sage: v = p.new_variable()
     803            sage: p.set_objective(v[1])
     804            sage: p.get_min(v[1])
     805            0.0
     806            sage: p.set_min(v[1],6)
     807            sage: p.get_min(v[1])
    784808            6.0
    785809        """
    786         self.max[v]=max
     810        return float(self.min[v]) if self.min.has_key(v) else None
    787811
     812    def get_max(self, v):
     813        r"""
     814        Returns the maximum value of a variable.
    788815
    789     def getmin(self,v):
    790         r"""
    791         Returns the minimum value of a variable
     816        INPUT:
    792817
    793         INPUT
     818        - ``v`` -- a variable (not a ``MIPVariable``, but one of its elements).
    794819
    795         - ``v`` a variable ( not a ``MIPVariable``, but one of its elements ! )
     820        OUTPUT:
    796821
    797         OUTPUT
    798 
    799         Minimum value of the variable, or ``None`` is
    800         the variable has no lower bound
     822        Maximum value of the variable, or ``None`` if
     823        the variable has no upper bound.
    801824
    802825        EXAMPLE::
    803826
    804             sage: p=MIP()
    805             sage: v=p.newvar()
    806             sage: p.setobj(v[1])
    807             sage: p.getmin(v[1])
    808             0.0
    809             sage: p.setmin(v[1],6)
    810             sage: p.getmin(v[1])
    811             6.0
    812         """
    813         return float(self.min[v]) if self.min.has_key(v) else 0.0
    814     def getmax(self,v):
    815         r"""
    816         Returns the maximum value of a variable
    817 
    818         INPUT
    819 
    820         - ``v`` a variable ( not a ``MIPVariable``, but one of its elements ! )
    821 
    822         OUTPUT
    823 
    824         Maximum value of the variable, or ``None`` is
    825         the variable has no upper bound
    826 
    827         EXAMPLE::
    828 
    829             sage: p=MIP()
    830             sage: v=p.newvar()
    831             sage: p.setobj(v[1])
    832             sage: p.getmax(v[1])
    833             sage: p.setmax(v[1],6)
    834             sage: p.getmax(v[1])
     827            sage: p = MixedIntegerLinearProgram()
     828            sage: v = p.new_variable()
     829            sage: p.set_objective(v[1])
     830            sage: p.get_max(v[1])
     831            sage: p.set_max(v[1],6)
     832            sage: p.get_max(v[1])
    835833            6.0
    836834        """
    837835        return float(self.max[v]) if self.max.has_key(v) else None
    838836
    839837class MIPSolverException(Exception):
    840838    r"""
    841     Exception raised when the solver fails
     839    Exception raised when the solver fails.
    842840    """
     841
    843842    def __init__(self, value):
    844843        r"""
    845         Constructor for ``MIPSolverException``
     844        Constructor for ``MIPSolverException``.
    846845
    847         ``MIPSolverException`` is the exception raised when the solver fails
     846        ``MIPSolverException`` is the exception raised when the solver fails.
    848847
    849         EXAMPLE:
     848        EXAMPLE::
    850849
    851850            sage: MIPSolverException("Error")
    852851            MIPSolverException()
    853                    
    854852        """
    855853        self.value = value
     854
    856855    def __str__(self):
    857856        r"""
    858         Returns the value of the instance of ``MIPSolverException` `
     857        Returns the value of the instance of ``MIPSolverException``.
    859858
    860         EXAMPLE:
     859        EXAMPLE::
    861860
    862             sage: e=MIPSolverException("Error")
     861            sage: e = MIPSolverException("Error")
    863862            sage: print e
    864863            'Error'
    865864        """
    866865        return repr(self.value)
    867866
    868867class MIPVariable:
    869      r"""
    870      ``MIPVariable`` is a variable used by the class ``MIP``
    871      """
    872      def __init__(self,x,f,dim=1):
    873          r"""
    874          Constructor for ``MIPVariable``
     868    r"""
     869    ``MIPVariable`` is a variable used by the class
     870    ``MixedIntegerLinearProgram``.
     871    """
    875872
    876          INPUT:
     873    def __init__(self, p, vtype, dim=1):
     874        r"""
     875        Constructor for ``MIPVariable``.
    877876
    878          - ``x`` is the generator element of an ``InfinitePolynomialRing``
    879          - ``f`` is a function returning a new variable from the parent class
    880          - ``dim`` is the integer defining the definition of the variable
     877        INPUT:
    881878
    882          For more informations, see method ``MIP.newvar``
     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.
    883884
    884          EXAMPLE:
     885        For more informations, see the method
     886        ``MixedIntegerLinearProgram.new_variable``.
    885887
    886             sage: p=MIP()
    887             sage: v=p.newvar()
    888            
    889            
    890          """
    891          self.dim=dim
    892          self.dict={}
    893          self.x=x
    894          self.f=f
     888        EXAMPLE::
    895889
    896      def __getitem__(self,i):
    897           r"""
    898           Returns the symbolic variable corresponding to the key
     890            sage: p=MixedIntegerLinearProgram()
     891            sage: v=p.new_variable()
     892        """
     893        self.dim = dim
     894        self.dict = {}
     895        self.p = p
     896        self.vtype = vtype
    899897
    900           Returns the element asked, otherwise creates it.
    901           ( When depth>1, recursively creates the variables )
     898    def __getitem__(self, i):
     899        r"""
     900        Returns the symbolic variable corresponding to the key.
    902901
    903          EXAMPLE:
     902        Returns the element asked, otherwise creates it.
     903        (When depth>1, recursively creates the variables).
    904904
    905              sage: p=MIP()
    906              sage: v=p.newvar()
    907              sage: p.setobj(v[0]+v[1])
    908              sage: v[0]
    909              x1
    910           """
    911           if self.dict.has_key(i):
    912                return self.dict[i]
    913           elif self.dim==1:
    914               self.dict[i]=self.f()
    915               return self.dict[i]
    916           else:
    917                self.dict[i]=MIPVariable(dim=self.dim-1,x=self.x, f=self.f)
    918                return self.dict[i]
    919      def keys(self):
    920          r"""
    921          Returns the keys already defined in the dictionary
     905        EXAMPLE::
    922906
    923          EXAMPLE:
     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]
    924921
    925              sage: p=MIP()
    926              sage: v=p.newvar()
    927              sage: p.setobj(v[0]+v[1])
    928              sage: v.keys()
    929              [0, 1]
    930          """
    931          return self.dict.keys()
    932      def items(self):
    933          r"""
    934          Returns the pairs (keys,value) contained in the dictionary
     922    def keys(self):
     923        r"""
     924        Returns the keys already defined in the dictionary.
    935925
    936          EXAMPLE:
     926        EXAMPLE::
    937927
    938              sage: p=MIP()
    939              sage: v=p.newvar()
    940              sage: p.setobj(v[0]+v[1])
    941              sage: v.items()
    942              [(0, x1), (1, x2)]
    943          """
    944          return self.dict.items()
    945      def depth(self):
    946          r"""
    947          Returns the current variable's depth
     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()
    948935
    949          EXAMPLE:
     936    def items(self):
     937        r"""
     938        Returns the pairs (keys,value) contained in the dictionary.
    950939
    951              sage: p=MIP()
    952              sage: v=p.newvar()
    953              sage: p.setobj(v[0]+v[1])
    954              sage: v.depth()
    955              1
    956          """
    957          return self.dim
    958      def values(self):
    959          r"""
    960          Returns the symbolic variables associated to the current dictionary
     940        EXAMPLE::
    961941
    962          EXAMPLE:
     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()
    963949
    964              sage: p=MIP()
    965              sage: v=p.newvar()
    966              sage: p.setobj(v[0]+v[1])
    967              sage: v.values()
    968              [x1, x2]
    969          """
    970          return self.dict.values()
     950    def depth(self):
     951        r"""
     952        Returns the current variable's depth.
    971953
     954        EXAMPLE::
    972955
     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
     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()