source: pyomo/trunk/pyomo/core/plugins/transform/relax_integrality.py @ 9475

Last change on this file since 9475 was 9475, checked in by wehart, 4 years ago

Updating the version #.

Renaming transformations to 'base.*' if they didn't have a specific
naming. NOTE: these are in the pyomo.core package ... which seems
odd. But we agreed that 'core' provides a connotation that we don't
intend.

Adding some documentation changes for 'pyomo help -t'.

File size: 2.9 KB
Line 
1#  _________________________________________________________________________
2#
3#  Pyomo: Python Optimization Modeling Objects
4#  Copyright (c) 2008 Sandia Corporation.
5#  This software is distributed under the BSD License.
6#  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
7#  the U.S. Government retains certain rights in this software.
8#  _________________________________________________________________________
9
10from pyomo.util.plugin import alias
11from pyomo.core.base import Var
12from pyomo.core.base.set_types import BooleanSet, IntegerSet, Reals
13import pyomo.core.base
14from pyomo.core.plugins.transform.hierarchy import NonIsomorphicTransformation
15
16
17class RelaxIntegrality(NonIsomorphicTransformation):
18    """
19    This plugin relaxes integrality in a Pyomo model.
20    """
21
22    alias('base.relax_integrality', "Create a model where integer variables are replaced with real variables.")
23
24    def __init__(self, **kwds):
25        kwds['name'] = "relax_integrality"
26        super(RelaxIntegrality, self).__init__(**kwds)
27
28    def apply(self, model, **kwds):
29        #
30        # Clone the model
31        #
32        M = model.clone()
33        #
34        # Iterate over all variables, replacing the domain with a real-valued domain
35        # and setting appropriate bounds.
36        #
37        # Note: this technique is not extensible.  If a user creates a new integer variable
38        # class then we'd need to add it here (unless it was a subset of one of the sets we
39        # detect here.  Alternatively, we could make the variables responsible for managing
40        # the generation of a relaxed variable.  But that would pollute the variable objects
41        # with logic about generating a specific relaxation.  That's probably a worse alternative.
42        #
43        # TODO: rework this so it works with model instances
44        #
45        comp = M.components(Var)
46        for var in comp.values():
47            if isinstance(var.domain, BooleanSet):
48                var.domain=Reals
49                dbnd = ( 0.0, 1.0 )
50            elif isinstance(var.domain, IntegerSet):
51                dbnd = var.domain.bounds()
52                if dbnd is None:
53                    bnd = ( None, None )
54                var.domain=Reals
55            elif isinstance(var.domain, pyomo.core.base.RangeSet):
56                dbnd = var.domain.bounds()
57                if dbnd is None:
58                    bnd = ( None, None )
59                var.domain=Reals
60            else:
61                continue
62
63            bnd = var.bounds
64            if bnd is None:
65                bnd = ( None, None )
66
67            bnd = ( self._tightenBound(bnd[0], dbnd[0], max),
68                    self._tightenBound(bnd[1], dbnd[1], min) )
69            if bnd == (None, None):
70                var.bounds = None
71            else:
72                var.bounds = bnd
73        return M
74
75    def _tightenBound(self, a, b, comp):
76        if a is None:
77            return b
78        if b is None:
79            return a
80        return comp(a,b)
Note: See TracBrowser for help on using the repository browser.