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

Last change on this file since 1768 was 1768, checked in by wehart, 11 years ago

Rework of Coopr to use the new PyUtilib? package decomposition.

NOTE: to use Coopr with this update, we need to work with a new version of coopr_install.

File size: 4.4 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, 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._component[_VarBase]
85        Con = model._component[Constraint]
86        Obj = model._component[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                try:
104                    self._identify_variables(Obj[key]._data[ondx].expr, model)
105                except ValueError, err:
106                    raise "Problem processing objective %s (index %s): %s" % (str(key), str(ondx), str(err))
107
108                Obj[key]._data[ondx].id = self.onum
109                self.onum += 1
110        for key in Con.keys():
111            C = Con[key]
112            for cndx in C.keys():
113                try:
114                    self._identify_variables(C._data[cndx].body, model)
115                except ValueError, err:
116                    raise "Problem processing constraint %s (index %s): %s" % (str(key), str(cndx), str(err))
117                C._data[cndx].id = self.cnum
118                model._con[self.cnum] = C._data[cndx]
119                self.cnum += 1
120        model.vnum=self.vnum
121        model.cnum=self.cnum
122        model.onum=self.onum
123        return model
124
Note: See TracBrowser for help on using the repository browser.