Ticket #11606: trac_11606_simplify_with_sets.patch

File trac_11606_simplify_with_sets.patch, 4.7 KB (added by john_perry, 10 years ago)
  • sage/numerical/mip.pxd

    # HG changeset patch
    # User John Perry <john.perry@usm.edu>
    # Date 1314912689 18000
    # Node ID c1e11ee479786e1cfdd138935864e6059eb76116
    # Parent  561b13b5d2825433807b643d082fa4f1e000231d
    Trac 11606: simplify constraints in linear programs
    
    diff -r 561b13b5d282 -r c1e11ee47978 sage/numerical/mip.pxd
    a b  
    1818    cdef int __BINARY
    1919    cdef int __REAL
    2020    cdef int __INTEGER
     21    cdef int _check_redundant
     22    cdef set _constraints
     23    cdef _min
    2124    cpdef row(self, int index)
    2225    cpdef row_bounds(self, int index)
    2326    cpdef get_constraints(self)
  • sage/numerical/mip.pyx

    diff -r 561b13b5d282 -r c1e11ee47978 sage/numerical/mip.pyx
    a b  
    153153         4.0
    154154    """
    155155   
    156     def __init__(self, solver = None, maximization=True, constraint_generation = False):
     156    def __init__(self, solver = None, maximization=True, constraint_generation = False, check_redundant = False):
    157157        r"""
    158158        Constructor for the ``MixedIntegerLinearProgram`` class.
    159159
     
    184184
    185185        - ``constraint_generation`` -- whether to require the returned solver to
    186186          support constraint generation (excludes Coin). ``False by default``.
     187         
     188        - ``check_redundant`` -- whether to check that constraints added to the
     189          program are redundant with constraints already in the program
    187190
    188191        .. SEEALSO::
    189192
     
    214217
    215218        # Associates an index to the variables
    216219        self._variables = {}
     220       
     221        # Check for redundant constraints
     222        self._check_redundant = check_redundant
     223        if check_redundant:
     224            self._constraints = set()
     225            self._min = min
    217226
    218227    def __repr__(self):
    219228         r"""
     
    878887            ...
    879888            ValueError: min and max arguments are required to be numerical
    880889
    881         """
     890        Do not add redundant elements (notice only one copy of each constraint is added)::
     891       
     892            sage: lp = MixedIntegerLinearProgram(check_redundant=True)
     893            sage: for each in xrange(10): lp.add_constraint(lp[0]-lp[1],min=1)
     894            sage: lp.show()
     895            Maximization:
     896            <BLANKLINE>
     897            Constraints:
     898              1.0 <= x_0 -x_1 
     899            Variables:
     900              x_0 is a continuous variable (min=0.0, max=+oo)
     901              x_1 is a continuous variable (min=0.0, max=+oo)
     902               
     903        We check for constant multiples of constraints as well:
     904         
     905            sage: for each in xrange(10): lp.add_constraint(2*lp[0]-2*lp[1],min=2)
     906            sage: lp.show()
     907            Maximization:
     908            <BLANKLINE>
     909            Constraints:
     910              1.0 <= x_0 -x_1 
     911            Variables:
     912              x_0 is a continuous variable (min=0.0, max=+oo)
     913              x_1 is a continuous variable (min=0.0, max=+oo)
     914         
     915        But if the constant multiple is negative, we should add anyway:
     916         
     917              sage: for each in xrange(10): lp.add_constraint(-2*lp[0]+2*lp[1],min=-2)
     918              sage: lp.show()
     919              Maximization:
     920              <BLANKLINE>
     921              Constraints:
     922                1.0 <= x_0 -x_1 
     923                x_0 -x_1 <= 1.0
     924              Variables:
     925                x_0 is a continuous variable (min=0.0, max=+oo)
     926                x_1 is a continuous variable (min=0.0, max=+oo)
     927                 """
    882928        if linear_function is None or linear_function is 0:
    883929            return None
    884930
     
    902948            indices = []
    903949            values = []
    904950
    905             C = [(v,coeff) for (v,coeff) in f.iteritems() if v != -1]
     951            if self._check_redundant:
     952              b = self._backend
     953              i = self._min([v for (v,coeff) in f.iteritems() if coeff != 0])
     954              c = f[i]
     955              C = [(v,coeff/c) for (v,coeff) in f.iteritems() if v != -1]
     956              if c > 0:
     957                min = min/c if min != None else None
     958                max = max/c if max != None else None
     959              else:
     960                tempmin = max/c if max != None else None
     961                tempmax = min/c if min != None else None
     962                min, max = tempmin, tempmax
     963              if (tuple(C),min,max) in self._constraints:
     964                return None
     965              else:
     966                self._constraints.add((tuple(C),min,max))
     967            else:
     968              C = [(v,coeff) for (v,coeff) in f.iteritems() if v != -1]
    906969
    907970            if min == None and max == None:
    908971                raise ValueError("Both max and min are set to None ? Weird!")