source: coopr.opt/trunk/coopr/opt/results/old_results.py @ 2259

Last change on this file since 2259 was 1908, checked in by jwatson, 12 years ago

Using symbol map in solver results output to print names that a user will actually recognize!

File size: 10.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 Coopr README.txt file.
9#  _________________________________________________________________________
10
11__all__ = ['SolverResults', 'SolverStatus', 'ProblemSense', 'SolutionStatus', 'Solution']
12
13from pyutilib.misc import format_io
14from pyutilib.math import as_number
15from pyutilib.enum import Enum
16
17import sys
18import StringIO
19
20SolverStatus = Enum('error', 'warning', 'ok', 'aborted')
21ProblemSense = Enum('unknown', 'minimize', 'maximize')
22SolutionStatus = Enum('unbounded', 'globallyOptimal', 'locallyOptimal',
23                            'optimal', 'bestSoFar', 'feasible', 'infeasible',
24                            'stoppedByLimit', 'unsure', 'error', 'other')
25
26
27class _SolutionSuffix(object):
28
29    def __init__(self, description):
30        self._info = []
31        self._index = {}
32        self._count = {}
33        self.description = description
34
35    def add(self, index, value):
36        """ NOTE: this function is deprecated """
37        self.__setitem__(index, value)
38
39    def __getitem__(self, key):
40        if isinstance(key,basestring):
41            return self._index[key]
42        return self._count[key]
43
44    def __setitem__(self, index, value):
45        if isinstance(index, basestring):
46            index = index.replace('(','[')
47            index = index.replace(')',']')
48        if type(value) is str:
49           tmp = eval(value)
50        else:
51           tmp = value
52        self._count[len(self._info)]=tmp
53        self._info.append( (index, tmp) )
54        self._index[index]=tmp
55        #
56        # If the index has the format x(1,a) or x[3,4,5]
57        # then create a dictionary attribute 'x', which maps
58        # the tuple values to the corresponding value.
59        #
60        if isinstance(index, basestring):
61            if '[' in index:
62                pieces = index.split('[')
63                name = pieces[0]
64                rest = None
65                # when a variable is indexed by more than one parameter, you will
66                # see identifiers of the form "x((a,b))" instead of the "x(a)"
67                # one-dimensional form. this is due to the process of "stringifying"
68                # the index, which is fine. it just requires a bit of ugliness in
69                # the string splitting process.
70                if index.count("]") == 2:
71                   rest = pieces[2]
72                else:
73                   rest = pieces[1]
74                # we're always taking the first part of the index,
75                # so even in the two (or greater) dimensional case
76                # such as "x((a,b))", the first piece is what we want.
77                tpl = rest.split(']')[0]
78                tokens = tpl.split(',')
79                for i in xrange(len(tokens)):
80                    tokens[i] = as_number(tokens[i])
81                try:
82                    var = getattr(self, name)
83                except Exception, err:
84                    setattr(self, name, {})
85                    var = getattr(self, name)
86                if len(tokens) == 1:
87                    var[ tokens[0] ] = tmp
88                else:
89                    var[ tuple(tokens) ] = tmp
90            else:
91                setattr(self, index, tmp)
92           
93           
94
95    def __len__(self):
96        return len(self._info)
97
98    def __iter__(self):
99        return self._info.__iter__()
100
101    def pprint(self, ostream=None, symbol_map=None):
102        if ostream is None:
103           ostream = sys.stdout
104        if len(self._info) != 0:
105           print >>ostream, "  "+self.description
106           flag=True
107           for (name,value) in self._info:
108              # translate the name, if a map is available and the
109              # item is in the map.
110              if (symbol_map is not None) and (name in symbol_map):
111                 name=symbol_map[name]
112              if value != 0:
113                 print >>ostream, "        "+str(name)+"\t"+format_io(value)
114                 flag=False
115           if flag:
116              print >>ostream,   "        No nonzero values"
117
118
119class Solution(object):
120
121    def __init__(self):
122        self.__dict__["_suffix"] = []
123        self.value = None
124        self.gap = None
125        self.status = SolutionStatus.unsure
126        self.add_suffix("variable","Primal Variables")
127        self.add_suffix("dual","Dual Variables")
128        self.add_suffix("slack","Constraint Slacks")
129        self.add_suffix("constraint","Constraint Values")
130
131    def __getattr__(self, name):
132        try:
133            if name in self.__dict__['_suffix']:
134                return self.__dict__["_"+name]
135        except KeyError:
136            pass
137        try:
138           return self.__dict__[name]
139        except KeyError:
140           raise AttributeError, "Unknown attribute "+str(name)
141
142    def __setattr__(self, name, val):
143        if name in self._suffix:
144           raise AttributeError, "Cannot set attribute '"+name+"' which is reserved for suffix array"
145        self.__dict__[name]=val
146
147    def add_suffix(self,name,description):
148        self._suffix.append(name)
149        setattr(self, "_"+name, _SolutionSuffix(description))
150
151    def pprint(self, ostream=None, only_variables=False, symbol_map=None):
152        if ostream is None:
153           ostream = sys.stdout
154        print >>ostream, "----------------------------------------------------------"
155        print >>ostream, "------  Solution "+ str(self._counter+1)
156        print >>ostream, "----------------------------------------------------------"
157        tmp = self.__dict__.keys()
158        tmp.sort()
159        for key in tmp:
160          if key[0] != "_":
161             if key != "value":
162                print >>ostream, " ",key+":", format_io(getattr(self, key))
163             else:
164                tmp = getattr(self,key)
165                if isinstance(tmp, dict):
166                   print >>ostream, "  Objectives"
167                   for vkey in tmp:
168                     print >>ostream, "        "+str(vkey)+"\t"+format_io(tmp[vkey])
169                else:
170                   print >>ostream, "  value:",format_io(tmp)
171                   
172        for item in self._suffix:
173            if only_variables and item != "variable":
174                continue
175            getattr(self,"_"+item).pprint(ostream=ostream, symbol_map=symbol_map)
176
177
178class SolutionSet(object):
179
180    def __init__(self):
181        self._solution={}
182        self._counter=0
183        self._ndx=[]
184
185    def __len__(self):
186        return len(self._solution)
187
188    def __getitem__(self,i):
189        return self._solution[i]
190
191    def __call__(self,i=0):
192        return self._solution[self._ndx[i]]
193
194    def create(self):
195        tmp = Solution()
196        self.insert(tmp)
197        return tmp
198
199    def insert(self,solution):
200        solution._counter = self._counter
201        self._solution[self._counter] = solution
202        self._ndx.append(self._counter)
203        self._counter += 1
204
205    def delete(self,i):
206        del self._solution[i]
207        self._ndx.remove(i)
208
209
210class _Data_Container(object):
211    pass
212
213
214class SolverResults(object):
215
216    def __init__(self):
217        self.solver = _Data_Container()
218        self.problem = _Data_Container()
219        self.solution = SolutionSet()
220        self.initialize()
221        self.symbol_map = None 
222
223    def initialize(self):
224        #
225        # Standard solver information
226        #
227        self.solver.status=SolverStatus.ok
228        self.solver.systime=None
229        self.solver.usrtime=None
230        #
231        # Standard problem information
232        #
233        self.problem.name=None
234        self.problem.sense=ProblemSense.unknown
235        self.problem.num_variables=None
236        self.problem.num_constraints=None
237        self.problem.num_objectives=None
238        self.problem.lower_bound=None
239        self.problem.upper_bound=None
240
241    def __str__(self):
242        output = StringIO.StringIO()
243        self.write(ostream=output, num=sys.maxint)
244        return output.getvalue()
245       
246    def write(self, filename=None, num=1, ostream=None, times=True, only_variables=False):
247        if ostream is None:
248           ostream = sys.stdout
249        if not filename is None:
250           OUTPUT=open(filename,"w")
251           self.write(num=num,ostream=OUTPUT,times=times)
252           OUTPUT.close()
253           return
254
255        print >>ostream, "=========================================================="
256        print >>ostream, "---  Solver Results                                    ---"
257        print >>ostream, "=========================================================="
258        print >>ostream, "----------------------------------------------------------"
259        print >>ostream, "------  Problem Information                         ------"
260        print >>ostream, "----------------------------------------------------------"
261        flag=False
262        tmp = self.problem.__dict__.keys()
263        tmp.sort()
264        for key in tmp:
265          if key[0] != "_":
266             print >>ostream, " ",key+":", format_io(getattr(self.problem, key))
267             flag=True
268        if not flag:        # pragma:nocover
269           print >>ostream, "  No Info"
270        if self.symbol_map is not None:
271           print >>ostream, "  Symbol map is available"
272        #
273        print >>ostream, "----------------------------------------------------------"
274        print >>ostream, "------  Solver Information                          ------"
275        print >>ostream, "----------------------------------------------------------"
276        flag=False
277        tmp = self.solver.__dict__.keys()
278        tmp.sort()
279        for key in tmp:
280          if key[0] != "_":
281             if times or not key in ["systime","usrtime"]:
282                print >>ostream, " ",key+":", format_io(getattr(self.solver, key))
283             flag=True
284        if not flag:        # pragma:nocover
285           print >>ostream, "  No Info"
286        #
287        if not num is None:
288           print >>ostream, "  num_solutions: "+str(len(self.solution))
289           i=0
290           while i<min(num, len(self.solution)):
291             self.solution(i).pprint(ostream, only_variables=only_variables, symbol_map=self.symbol_map)
292             i += 1
293        else:
294           print >>ostream, "  num_solutions to display: 0"
295        print >>ostream, "----------------------------------------------------------"
296
297    def read(self, filename=None):          #pragma:nocover
298        raise IOError, "SolverResults.read is not defined!"
299
Note: See TracBrowser for help on using the repository browser.