Ticket #11607: trac_11607_reviewer.patch

File trac_11607_reviewer.patch, 6.1 KB (added by ncohen, 10 years ago)
  • sage/numerical/backends/cplex_backend.pyx

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1319208225 -7200
    # Node ID 00a4db86817d23c09d60de6c4a333fb299d42d1c
    # Parent  099536796c46cbb13149925b6e3ddb69b3a173df
    trac 11607 -- read constraints from linear program (reviewer's patch)
    
    diff --git a/sage/numerical/backends/cplex_backend.pyx b/sage/numerical/backends/cplex_backend.pyx
    a b  
    447447            bound[0] = lower_bound
    448448            rng[0] = upper_bound - lower_bound
    449449
    450 
    451450        elif upper_bound is not None:
    452451            sense[0] = 'L'
    453452            bound[0] = upper_bound
     
    468467                c_names[i] = names[i]
    469468
    470469        status = CPXnewrows(self.env, self.lp, number, bound, sense, rng, c_names if names else NULL)
     470
     471        sage_free(sense)
     472        sage_free(bound)
     473        sage_free(c_names)
    471474        check(status)       
    472475
    473476    cpdef add_linear_constraint(self, coefficients, lower_bound, upper_bound, name = None):
     
    542545
    543546            sense = 'R'
    544547            bound = lower_bound
     548            rng = upper_bound - lower_bound
    545549
    546550        elif upper_bound is not None:
    547551            sense = 'L'
  • sage/numerical/mip.pyx

    diff --git a/sage/numerical/mip.pyx b/sage/numerical/mip.pyx
    a b  
    388388    def constraints(self, indices = None):
    389389        r"""
    390390        Returns a list of constraints, as 3-tuples.
    391         If `n` is `None`, this returns all constraints.
    392         If `n` is an integer, this is similar (but not equivalent) to ``self.constraint(n)``.
    393         If `n` is a list of integers, this is equivalent to ``[self.constraint
    394         The first entry in each tuple is the lower bound;
    395         the second entry is a pair ``(indices, coeffs)``
    396         (see ``row`` for details); and
    397         the third entry is the upper bound.
     391
     392        INPUT:
     393
     394        - ``indices`` -- select which constraint(s) to return
     395
     396            - If ``indices = None``, the method returns the list of all the
     397              constraints.
     398
     399            - If ``indices`` is an integer `i`, the method returns constraint
     400              `i`.
     401
     402            - If ``indices`` is a list of integers, the method returns the list
     403              of the corresponding constraints.
     404
     405        OUTPUT:
     406
     407        Each constraint is returned as a triple ``lower_bound, (indices,
     408        coefficients), upper_bound``.  For each of those entries, the
     409        corresponding linear function is the one associating to variable
     410        ``indices[i]`` the coefficient ``coefficients[i]``, and `0` to all the
     411        others.
     412
     413        ``lower_bound`` and ``upper_bound`` are numerical values.
    398414       
    399         EXAMPLE::
     415        EXAMPLE:
     416
     417        First, let us define a small LP::
     418
    400419            sage: p = MixedIntegerLinearProgram()
    401420            sage: p.add_constraint(p[0] - p[2], min = 1, max = 4)
    402421            sage: p.add_constraint(p[0] - 2*p[1], min = 1)
    403             sage: p.constraints()
     422
     423        To obtain the list of all constraints::
     424
     425            sage: p.constraints()          # not tested
    404426            [(1.0, ([1, 0], [-1.0, 1.0]), 4.0), (1.0, ([2, 0], [-2.0, 1.0]), None)]
    405             sage: p.constraints(0)
    406             [(1.0, ([1, 0], [-1.0, 1.0]), 4.0)]
    407             sage: p.constraints([1])
     427
     428        Or constraint `0` only::
     429
     430            sage: p.constraints(0)         # not tested
     431            (1.0, ([1, 0], [-1.0, 1.0]), 4.0)
     432
     433        A list of constraints containing only `1`::
     434
     435            sage: p.constraints([1])       # not tested
    408436            [(1.0, ([2, 0], [-2.0, 1.0]), None)]
     437
     438
     439        TESTS:
     440
     441        As the ordering of the variables in each constraint depends on the
     442        solver used, we define a short function reordering it before it is
     443        printed. The output would look the same without this function applied::
     444
     445            sage: def reorder_constraint((lb,(ind,coef),ub)):
     446            ...     d = dict(zip(ind, coef))
     447            ...     ind.sort()
     448            ...     return (lb, (ind, [d[i] for i in ind]), ub)
     449
     450        Running the examples from above, reordering applied::
     451
     452            sage: p = MixedIntegerLinearProgram()
     453            sage: p.add_constraint(p[0] - p[2], min = 1, max = 4)
     454            sage: p.add_constraint(p[0] - 2*p[1], min = 1)
     455            sage: sorted(map(reorder_constraint,p.constraints()))
     456            [(1.0, ([0, 1], [1.0, -1.0]), 4.0), (1.0, ([0, 2], [1.0, -2.0]), None)]
     457            sage: reorder_constraint(p.constraints(0))
     458            (1.0, ([0, 1], [1.0, -1.0]), 4.0)
     459            sage: sorted(map(reorder_constraint,p.constraints([1])))
     460            [(1.0, ([0, 2], [1.0, -2.0]), None)]
     461
    409462        """
     463        from sage.rings.integer import Integer as Integer
    410464        cdef int i
    411465        cdef str s
    412466        cdef GenericBackend b = self._backend
     467
     468        result = list()
     469
     470        # If indices == None, we actually want to return all constraints
     471        if indices == None:
     472          indices = range(b.nrows())
     473
     474        # Only one constraint
     475        if isinstance(indices, int) or isinstance(indices, Integer):
     476            lb, ub = b.row_bounds(indices)
     477            return (lb, b.row(indices), ub)
     478
     479        # List of constraints
     480        elif isinstance(indices, list):
     481            for i in indices:
     482                lb, ub = b.row_bounds(i)
     483                result.append((lb, b.row(i), ub))
    413484       
    414         from sage.rings.integer import Integer as Integer
    415        
    416         result = list()
    417         if indices == None:
    418           indices = xrange(b.nrows())
    419         elif isinstance(indices, int) or isinstance(indices, Integer):
    420             indices = [indices]
    421         elif not isinstance(indices, list):
    422           raise TypeError, "constraints() requires a list of integers, though it will accommodate None or an integer."
    423         for i in indices:
    424           lb, ub = b.row_bounds(i)
    425           result.append((lb, b.row(i), ub))
    426        
    427         return result
     485            return result
     486
     487        # Weird Input
     488        else:
     489          raise ValueError, "constraints() requires a list of integers, though it will accommodate None or an integer."
    428490
    429491    def show(self):
    430492        r"""