source: coopr.pyomo/trunk/coopr/pyomo/presolve/identify_vars.py @ 1993

Last change on this file since 1993 was 1993, checked in by wehart, 10 years ago

Adding support for component index deactivation. Again,
this isn't tested except that all the normal tests pass.

This supports the following semantics:

model.C = Constraint(model.A)

model.C[index].deactivate()

Note that the current implementation requires the user to
query whether each index is active:

if model.C[index].active:

# Do something

I could have alternatively changed the iterator for the
constraint, but then that could mask the existence of a
constraint, making it difficult to reactivate.

Finally, note that this activation mechanism is independent
of the component level activation/deactivation:

model.C.deactivate()
# All C constraints are deactivated
model.C[index].deactivate
# You can still manipulate the C constraint
model.C.activate()
# Now, the C constraint is active, except for the '
# 'index' constraint

File size: 4.5 KB
Line 
1#  _________________________________________________________________________
2#
3#  Coopr: A COmmon Optimization Python Repository
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#  For more information, see the FAST README.txt file.
9#  _________________________________________________________________________
10
11
12import pyutilib.plugin.core
13from coopr.pyomo.base import expr, _VarBase, Var, Constraint, Objective
14from coopr.pyomo.base.var import _VarValue, VarStatus
15from coopr.pyomo.base.numvalue import NumericConstant
16from coopr.pyomo.base import IPyomoPresolver, IPyomoPresolveAction
17
18
19class IdentifyVariablesPresolver(pyutilib.plugin.core.SingletonPlugin):
20    """
21    This plugin processes a Pyomo Model instance to define
22    the order of variables and to categorize constraints.
23    """
24
25    pyutilib.plugin.core.implements(IPyomoPresolveAction)
26
27    def __init__(self, **kwds):
28        kwds['name'] = "identify_variables"
29        pyutilib.plugin.core.Plugin.__init__(self, **kwds)
30
31    def rank(self):
32        return 1
33
34    #
35    # Recursively work through an exression to identify variables.
36    #
37    def _identify_variables(self, exp, model):
38        if exp.fixed_value():
39            return
40        #
41        # Product Expressions store stuff differently
42        #
43        if type(exp) is expr._ProductExpression:
44            for arg in exp._numerator:
45                self._identify_variables(arg, model)
46            for arg in exp._denominator:
47                self._identify_variables(arg, model)
48        #
49        # Expression
50        #
51        elif isinstance(exp,expr.Expression):
52            for arg in exp._args:
53                self._identify_variables(arg, model)
54        #
55        # Variable Value
56        #
57        elif isinstance(exp,_VarValue) or isinstance(exp,_VarBase):
58            exp.status = VarStatus.used
59            if isinstance(exp,_VarValue):
60                if exp.id in model._var:
61                    return
62                exp.id = self.vnum
63                model._var[self.vnum] = exp
64            else:
65                tmp = exp.as_numeric()
66                if tmp is exp:
67                    raise ValueError, "Variable %s appears in an expression without an index, but this variable is an indexed value." % exp.name
68                if tmp.id in model._var:
69                    return
70                tmp.id = self.vnum
71                model._var[self.vnum] = tmp
72            self.vnum += 1
73        #
74        # If not a constant, then this is an error
75        #
76        elif exp is not None:
77            raise ValueError, "Unexpected expression type in identify_variables: " + str(type(exp))+" "+str(exp)
78
79
80    def presolve(self,model):
81        """
82        The main routine to perform the presolve
83        """
84        Vars = model.active_components(Var)
85        Con = model.active_components(Constraint)
86        Obj = model.active_components(Objective)
87        self.vnum=0
88        self.cnum=0
89        self.onum=0
90        #
91        # Indicate that all variables are unused
92        #
93        for var in Vars.values():
94            for V in var._varval.keys():
95                var._varval[V].status = VarStatus.unused
96                var._varval[V].id = -1
97        #
98        # Call identify_variables to find the variables that are used in
99        # the objective and constraints
100        #
101        for key in Obj.keys():
102            for ondx in Obj[key]._data:
103                if not Obj[key]._data[ondx].active:
104                    continue
105                try:
106                    self._identify_variables(Obj[key]._data[ondx].expr, model)
107                except ValueError, err:
108                    raise "Problem processing objective %s (index %s): %s" % (str(key), str(ondx), str(err))
109
110                Obj[key]._data[ondx].id = self.onum
111                self.onum += 1
112        for key in Con.keys():
113            C = Con[key]
114            for cndx in C.keys():
115                if not C._data[cndx].active:
116                    continue
117                try:
118                    self._identify_variables(C._data[cndx].body, model)
119                except ValueError, err:
120                    raise "Problem processing constraint %s (index %s): %s" % (str(key), str(cndx), str(err))
121                C._data[cndx].id = self.cnum
122                model._con[self.cnum] = C._data[cndx]
123                self.cnum += 1
124        model.vnum=self.vnum
125        model.cnum=self.cnum
126        model.onum=self.onum
127        return model
128
Note: See TracBrowser for help on using the repository browser.