Ticket #12616: trac_12616.patch

File trac_12616.patch, 7.0 KB (added by ncohen, 9 years ago)
  • sage/numerical/mip.pyx

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1330683028 -3600
    # Node ID 55d30918ba60644dff312590a99f3b64b5444cfb
    # Parent  218094b2e56274dae1c8cf21bb191d2cc5ab7b44
    The LP are not deallocated because of cyclic references !
    
    diff --git a/sage/numerical/mip.pyx b/sage/numerical/mip.pyx
    a b  
    11r"""
    22Mixed integer linear programming
    33
    4 A linear program (`LP <http://en.wikipedia.org/wiki/Linear_programming>`_) 
    5 is an `optimization problem <http://en.wikipedia.org/wiki/Optimization_%28mathematics%29>`_ 
     4A linear program (`LP <http://en.wikipedia.org/wiki/Linear_programming>`_)
     5is an `optimization problem <http://en.wikipedia.org/wiki/Optimization_%28mathematics%29>`_
    66in the following form
    77
    88.. MATH::
    99     \max \{ c^T x \;|\; A x \leq b, x \geq 0 \}
    1010
    11 with given `A \in \mathbb{R}^{m,n}`, `b \in \mathbb{R}^m`, 
     11with given `A \in \mathbb{R}^{m,n}`, `b \in \mathbb{R}^m`,
    1212`c \in \mathbb{R}^n` and unknown `x \in \mathbb{R}^{n}`.
    1313If some or all variables in the vector `x` are restricted over
    1414the integers `\mathbb{Z}`, the problem is called mixed integer
    15 linear program (`MILP <http://en.wikipedia.org/wiki/Mixed_integer_linear_programming>`_). 
     15linear program (`MILP <http://en.wikipedia.org/wiki/Mixed_integer_linear_programming>`_).
    1616A wide variety of problems in optimization
    1717can be formulated in this standard form. Then, solvers are
    18 able to calculate a solution. 
     18able to calculate a solution.
    1919
    2020Imagine you want to solve the following linear system of three equations:
    2121
     
    3434A mixed integer linear program can give you an answer:
    3535
    3636  #. You have to create an instance of :class:`MixedIntegerLinearProgram` and
    37      -- in our case -- specify that it is a minimization. 
     37     -- in our case -- specify that it is a minimization.
    3838  #. Create a variable vector ``w`` via ``w = p.new_variable(integer=True)`` and
    3939     tell the system that it is over the integers.
    40   #. Add those three equations as equality constraints via 
     40  #. Add those three equations as equality constraints via
    4141     :meth:`add_constraint <sage.numerical.mip.MixedIntegerLinearProgram.add_constraint>`.
    4242  #. Also add the inequality constraint.
    4343  #. Add an inequality constraint `w_3 \geq 1` to exclude the trivial solution.
     
    4646  #. Specify the objective function via :meth:`set_objective <sage.numerical.mip.MixedIntegerLinearProgram.set_objective>`.
    4747     In our case that is just `w_3`. If it
    4848     is a pure constraint satisfaction problem, specify it as ``None``.
    49   #. To check if everything is set up correctly, you can print the problem via 
     49  #. To check if everything is set up correctly, you can print the problem via
    5050     :meth:`show <sage.numerical.mip.MixedIntegerLinearProgram.show>`.
    5151  #. :meth:`Solve <sage.numerical.mip.MixedIntegerLinearProgram.solve>` it and print the solution.
    5252
    5353The following example shows all these steps::
    5454
    55     sage: p = MixedIntegerLinearProgram(maximization=False) 
    56     sage: w = p.new_variable(integer=True) 
    57     sage: p.add_constraint(w[0] + w[1] + w[2] - 14*w[3] == 0) 
    58     sage: p.add_constraint(w[1] + 2*w[2] - 8*w[3] == 0) 
    59     sage: p.add_constraint(2*w[2] - 3*w[3] == 0) 
     55    sage: p = MixedIntegerLinearProgram(maximization=False)
     56    sage: w = p.new_variable(integer=True)
     57    sage: p.add_constraint(w[0] + w[1] + w[2] - 14*w[3] == 0)
     58    sage: p.add_constraint(w[1] + 2*w[2] - 8*w[3] == 0)
     59    sage: p.add_constraint(2*w[2] - 3*w[3] == 0)
    6060    sage: p.add_constraint(w[0] - w[1] - w[2] >= 0)
    61     sage: p.add_constraint(w[3] >= 1) 
    62     sage: _ = [ p.set_min(w[i], None) for i in range(1,4) ] 
    63     sage: p.set_objective(w[3]) 
    64     sage: p.show() 
     61    sage: p.add_constraint(w[3] >= 1)
     62    sage: _ = [ p.set_min(w[i], None) for i in range(1,4) ]
     63    sage: p.set_objective(w[3])
     64    sage: p.show()
    6565    Minimization:
    6666       x_3
    6767    Constraints:
     
    151151         sage: p.solve(objective_only=True)
    152152         4.0
    153153    """
    154    
     154
    155155    def __init__(self, solver = None, maximization=True, constraint_generation = False, check_redundant = False):
    156156        r"""
    157157        Constructor for the ``MixedIntegerLinearProgram`` class.
     
    185185
    186186        - ``constraint_generation`` -- whether to require the returned solver to
    187187          support constraint generation (excludes Coin). ``False by default``.
    188          
     188
    189189        - ``check_redundant`` -- whether to check that constraints added to the
    190190          program are redundant with constraints already in the program.
    191191          Only obvious redundancies are checked: to be considered redundant,
     
    201201        EXAMPLE::
    202202
    203203            sage: p = MixedIntegerLinearProgram(maximization=True)
     204
     205        TESTS:
     206
     207        Checks the objects are deallocated (cf. :trac:`12616`)::
     208
     209            sage: del p
     210            sage: def just_create_variables():
     211            ...       p = MixedIntegerLinearProgram()
     212            ...       b = p.new_variable()
     213            ...       p.add_constraint(b[3]+b[6] <= 2)
     214            ...       p.solve()
     215            sage: C = sage.numerical.mip.MixedIntegerLinearProgram
     216            sage: import gc
     217            sage: _ = gc.collect()  # avoid side effects of other doc tests
     218            sage: len([x for x in gc.get_objects() if isinstance(x,C)])
     219            0
     220            sage: just_create_variables()
     221            sage: len([x for x in gc.get_objects() if isinstance(x,C)])
     222            0
    204223        """
    205224
    206225        from sage.numerical.backends.generic_backend import get_solver
    207226
    208         self._backend = get_solver(solver=solver, 
     227        self._backend = get_solver(solver=solver,
    209228                                   constraint_generation=constraint_generation)
    210229
    211230        if not maximization:
     
    216235        self.__INTEGER = 1
    217236
    218237
    219         # List of all the MIPVariables linked to this instance of
    220         # MixedIntegerLinearProgram
    221         self._mipvariables = []
    222 
    223238        # Associates an index to the variables
    224239        self._variables = {}
    225        
     240
    226241        # Check for redundant constraints
    227242        self._check_redundant = check_redundant
    228243        if check_redundant:
     
    244259
    245260         return ("Mixed Integer Program "+
    246261
    247                  ( "\"" +self._backend.problem_name()+ "\"" 
     262                 ( "\"" +self._backend.problem_name()+ "\""
    248263                   if (str(self._backend.problem_name()) != "") else "")+
    249264
    250265                 " ( " + ("maximization" if b.is_maximization() else "minimization" ) +
     
    257272        Returns a copy of the current ``MixedIntegerLinearProgram`` instance.
    258273        """
    259274        cdef MixedIntegerLinearProgram p = MixedIntegerLinearProgram(solver="GLPK")
    260         try:
    261             p._mipvariables = copy(self._mipvariables)
    262         except AttributeError:
    263             pass
    264275
    265276        try:
    266277            p._variables = copy(self._variables)
     
    395406            vtype = self.__REAL
    396407
    397408        v=MIPVariable(self, vtype, dim=dim,name=name)
    398         self._mipvariables.append(v)
    399409        return v
    400410
    401411    cpdef int number_of_constraints(self):