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

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

Various updates:

  1. Rework of CBC parser to handle infeasiblility results.
  1. Rework of Pyomo presolver to collect data the is needed for the NL writer. Rework of the NL writer to use this new data. (This has apparently been broken for a while. I'm not sure why our tests have failed to detect that!)
  1. Adding the --save-model option to Pyomo's command-line, which allows the user to specify the file that they want saved. Coopr will do the work of converting the model to the requested format.
File size: 4.3 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
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.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.implements(IPyomoPresolveAction)
26
27    def __init__(self, **kwds):
28        kwds['name'] = "identify_variables"
29        pyutilib.plugin.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.