# 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 r""" Mixed integer linear programming A linear program (LP _) is an optimization problem _ A linear program (LP _) is an optimization problem _ in the following form .. MATH:: \max \{ c^T x \;|\; A x \leq b, x \geq 0 \} with given A \in \mathbb{R}^{m,n}, b \in \mathbb{R}^m, with given A \in \mathbb{R}^{m,n}, b \in \mathbb{R}^m, c \in \mathbb{R}^n and unknown x \in \mathbb{R}^{n}. If some or all variables in the vector x are restricted over the integers \mathbb{Z}, the problem is called mixed integer linear program (MILP _). linear program (MILP _). A wide variety of problems in optimization can be formulated in this standard form. Then, solvers are able to calculate a solution. able to calculate a solution. Imagine you want to solve the following linear system of three equations: A mixed integer linear program can give you an answer: #. You have to create an instance of :class:MixedIntegerLinearProgram and -- in our case -- specify that it is a minimization. -- in our case -- specify that it is a minimization. #. Create a variable vector w via w = p.new_variable(integer=True) and tell the system that it is over the integers. #. Add those three equations as equality constraints via #. Add those three equations as equality constraints via :meth:add_constraint . #. Also add the inequality constraint. #. Add an inequality constraint w_3 \geq 1 to exclude the trivial solution. #. Specify the objective function via :meth:set_objective . In our case that is just w_3. If it is a pure constraint satisfaction problem, specify it as None. #. To check if everything is set up correctly, you can print the problem via #. To check if everything is set up correctly, you can print the problem via :meth:show . #. :meth:Solve  it and print the solution. The following example shows all these steps:: sage: p = MixedIntegerLinearProgram(maximization=False) sage: w = p.new_variable(integer=True) sage: p.add_constraint(w[0] + w[1] + w[2] - 14*w[3] == 0) sage: p.add_constraint(w[1] + 2*w[2] - 8*w[3] == 0) sage: p.add_constraint(2*w[2] - 3*w[3] == 0) sage: p = MixedIntegerLinearProgram(maximization=False) sage: w = p.new_variable(integer=True) sage: p.add_constraint(w[0] + w[1] + w[2] - 14*w[3] == 0) sage: p.add_constraint(w[1] + 2*w[2] - 8*w[3] == 0) sage: p.add_constraint(2*w[2] - 3*w[3] == 0) sage: p.add_constraint(w[0] - w[1] - w[2] >= 0) sage: p.add_constraint(w[3] >= 1) sage: _ = [ p.set_min(w[i], None) for i in range(1,4) ] sage: p.set_objective(w[3]) sage: p.show() sage: p.add_constraint(w[3] >= 1) sage: _ = [ p.set_min(w[i], None) for i in range(1,4) ] sage: p.set_objective(w[3]) sage: p.show() Minimization: x_3 Constraints: sage: p.solve(objective_only=True) 4.0 """ def __init__(self, solver = None, maximization=True, constraint_generation = False, check_redundant = False): r""" Constructor for the MixedIntegerLinearProgram class. - constraint_generation -- whether to require the returned solver to support constraint generation (excludes Coin). False by default. - check_redundant -- whether to check that constraints added to the program are redundant with constraints already in the program. Only obvious redundancies are checked: to be considered redundant, EXAMPLE:: sage: p = MixedIntegerLinearProgram(maximization=True) TESTS: Checks the objects are deallocated (cf. :trac:12616):: sage: del p sage: def just_create_variables(): ...       p = MixedIntegerLinearProgram() ...       b = p.new_variable() ...       p.add_constraint(b[3]+b[6] <= 2) ...       p.solve() sage: C = sage.numerical.mip.MixedIntegerLinearProgram sage: import gc sage: _ = gc.collect()  # avoid side effects of other doc tests sage: len([x for x in gc.get_objects() if isinstance(x,C)]) 0 sage: just_create_variables() sage: len([x for x in gc.get_objects() if isinstance(x,C)]) 0 """ from sage.numerical.backends.generic_backend import get_solver self._backend = get_solver(solver=solver, self._backend = get_solver(solver=solver, constraint_generation=constraint_generation) if not maximization: self.__INTEGER = 1 # List of all the MIPVariables linked to this instance of # MixedIntegerLinearProgram self._mipvariables = [] # Associates an index to the variables self._variables = {} # Check for redundant constraints self._check_redundant = check_redundant if check_redundant: return ("Mixed Integer Program "+ ( "\"" +self._backend.problem_name()+ "\"" ( "\"" +self._backend.problem_name()+ "\"" if (str(self._backend.problem_name()) != "") else "")+ " ( " + ("maximization" if b.is_maximization() else "minimization" ) + Returns a copy of the current MixedIntegerLinearProgram instance. """ cdef MixedIntegerLinearProgram p = MixedIntegerLinearProgram(solver="GLPK") try: p._mipvariables = copy(self._mipvariables) except AttributeError: pass try: p._variables = copy(self._variables) vtype = self.__REAL v=MIPVariable(self, vtype, dim=dim,name=name) self._mipvariables.append(v) return v cpdef int number_of_constraints(self):